Skip to content
Skip to Content
APIAPI reference

API reference

Every operation, grouped by what it works on. Each one lists the scopes it needs, its parameters, the fields it returns, the errors it can raise, and a curl you can paste.

Generated from the OpenAPI document the server runs. Version 1.0.0. Download the specification.

Meta

Find the service, read the specification, and check what a credential can do.

get/

Get service information

getServiceInfo

Confirm the API is reachable and find the specification. No credential needed.

Response 200 · Service information.

FieldTypeDescription
objectrequired"service_info"Always `service_info`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequired"Doozy API"The name of this service.
versionrequiredstringThe version of this API surface.
documentationUrlrequiredstringWhere the guides live.
openapiUrlrequiredstringWhere the machine-readable specification lives.

Example

curl -X GET "https://api.usedoozy.com/api/v1/" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/openapi.json

Get the OpenAPI specification

getOpenApiSpecification

The full OpenAPI 3.1 description of this API, generated from the running server.

It is always current: the routes and this document are built from the same definitions, so a route that exists is described here and a route described here exists.

Response 200 · An OpenAPI 3.1 document.

FieldTypeDescription
openapirequiredstringThe OpenAPI version, always 3.1.x.

Example

curl -X GET "https://api.usedoozy.com/api/v1/openapi.json" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/me

Get the current identity

getIdentity

Report which workspace this credential opens, who owns it, which scopes it holds, and every operation it may call.

Call this first. It is the cheapest way to check that a key works, the way to learn a workspace id without one being configured anywhere, and the way to find out what you are allowed to do before attempting it: `allowedOperations` lists the operationIds this credential can reach, derived from the same scopes the router enforces.

An agent connecting to Doozy should start here, then read `getOpenApiSpecification` for the shape of the operations it just learned it can call.

Response 200 · The identity behind this request.

FieldTypeDescription
objectrequired"identity"Always `identity`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
workspacerequiredobjectThe workspace this credential opens. There is exactly one.
organizationIdrequireduuid or nullThe organization the workspace belongs to, when it belongs to one.
userrequiredobjectThe person behind the request: the key owner, or the signed-in user.
credentialrequiredobjectThe credential that authenticated this request.
allowedOperationsrequiredarray of stringEvery operationId this credential may call, worked out from its scopes. This is the answer to "what can I do here" without cross-referencing the specification, and it is what an agent should read before deciding which calls to attempt.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/me" \
  -H "Authorization: Bearer $DOOZY_API_KEY"

Todos

The work in a workspace. Todos can be assigned to a person or to an agent, and an agent-assigned todo can be run.

get/todos

List todos

listTodos

Page through the todos in the workspace, newest first by default.

Active todos are returned. Pass `includeArchived=true` to see archived ones instead; there is no combined view, because a list that mixes live work with finished work is a list nobody can act on.

Suggestions an agent has made but nobody has accepted are left out, unless you filter by `captureId`, where they are part of what that capture produced.

Requires todos:read

Parameters

ParameterInTypeDescription
limitqueryintegerHow many records to return. Between 1 and 100; defaults to 25.
cursorquerystringThe `nextCursor` from a previous page. Omit it to start from the beginning.
statusquery"ready" | "in_progress" | "done"Only todos in this state.
priorityquery"urgent" | "high" | "medium" | "low"Only todos at this priority.
typequery"task" | "responsibility"Only tasks, or only responsibilities.
todoListIdqueryuuidOnly todos in this list.
captureIdqueryuuidOnly todos that came from this capture.
assigneeIdqueryuuidOnly todos assigned to this user or agent.
includeArchivedquery"true" | "false"Set to `true` to list archived todos instead of active ones. Defaults to active.
queryquerystringFree text match against the title and body.
sortquery"createdAt" | "updatedAt" | "dueDate" | "priority"What to order by. Defaults to `createdAt`.
orderquery"asc" | "desc"Which direction to order in. Defaults to `desc`.

Response 200 · A page of todos.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of TodoThe todos on this page, newest first unless you asked for another order.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed, invalid_cursor401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/todos" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/todos

Create a todo

createTodo

Add a piece of work to the workspace.

Give a `title`, some `content`, or both. Without a `todoListId` the todo lands in the workspace default list.

Assigning an agent starts that agent working on the todo immediately, which spends Doozy Minutes. Assign a person instead, or leave `assignees` off, if you only want the work recorded. `run: true` starts the agent explicitly and is the clearer way to ask for it.

Requires todos:write

Parameters

ParameterInTypeDescription
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The todo to create.

FieldTypeDescription
titlestringThe short line that names the work. Give this or `content`, or both.
contentstringThe detail behind the work. Everything an agent needs to act belongs here.
priority"urgent" | "high" | "medium" | "low"How urgent the work is. Left unset when omitted.
type"task" | "responsibility"Defaults to `task`. Use `responsibility` for standing work.
todoListIduuidThe list to file this under. Omit it and the todo goes to the workspace default list.
dueDatestringThe date the work is due, as YYYY-MM-DD.
assigneesarray of objectWho is responsible. Assign an agent to make the todo runnable. Defaults to the key owner when omitted.
captureIduuidLink this todo to the capture it came out of.
runbooleanStart an agent on this todo as soon as it is created. Requires an agent assignee and spends Doozy Minutes.

Response 201 · The todo that was created.

FieldTypeDescription
objectrequired"todo"Always `todo`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullThe short line that names the work. Null when the todo only has a body.
contentrequiredstring or nullThe body of the todo: the detail an agent or a person needs to act. Markdown is preserved as written.
statusrequired"ready" | "in_progress" | "done"`ready` means nobody has started, `in_progress` means work is under way, `done` means it is finished.
priorityrequired"urgent" | "high" | "medium" | "low" or nullHow urgent the work is, or null when nobody has said.
typerequired"task" | "responsibility"A `task` is finished once. A `responsibility` is standing work that recurs.
todoListIdrequireduuidThe list this todo sits in.
dueDaterequiredstring or nullThe date the work is due, as YYYY-MM-DD, or null when there is no deadline.
assigneesrequiredarray of TodoAssigneeEveryone responsible for this todo. Empty when nobody is.
captureIdrequireduuid or nullThe capture this todo came out of, when it was created from one.
isArchivedrequiredbooleanTrue once the todo has been archived. Archived todos stay readable and can be restored.
isSuggestedrequiredbooleanTrue while this is a suggestion an agent made that nobody has accepted yet.
sourcerequired"user_created" | "agent_created" | "auto_suggested" or nullWho or what created this todo.
latestRunrequiredobject or nullThe most recent agent run on this todo, or null if an agent has never run it.
createdAtrequireddate-timeWhen the todo was created.
updatedAtrequireddate-timeWhen the todo last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope409 idempotency_key_reused429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/todos" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/todos/{todoId}

Get a todo

getTodo

Fetch one todo by id, including who it is assigned to and the most recent agent run on it.

Requires todos:read

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.

Response 200 · The todo.

FieldTypeDescription
objectrequired"todo"Always `todo`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullThe short line that names the work. Null when the todo only has a body.
contentrequiredstring or nullThe body of the todo: the detail an agent or a person needs to act. Markdown is preserved as written.
statusrequired"ready" | "in_progress" | "done"`ready` means nobody has started, `in_progress` means work is under way, `done` means it is finished.
priorityrequired"urgent" | "high" | "medium" | "low" or nullHow urgent the work is, or null when nobody has said.
typerequired"task" | "responsibility"A `task` is finished once. A `responsibility` is standing work that recurs.
todoListIdrequireduuidThe list this todo sits in.
dueDaterequiredstring or nullThe date the work is due, as YYYY-MM-DD, or null when there is no deadline.
assigneesrequiredarray of TodoAssigneeEveryone responsible for this todo. Empty when nobody is.
captureIdrequireduuid or nullThe capture this todo came out of, when it was created from one.
isArchivedrequiredbooleanTrue once the todo has been archived. Archived todos stay readable and can be restored.
isSuggestedrequiredbooleanTrue while this is a suggestion an agent made that nobody has accepted yet.
sourcerequired"user_created" | "agent_created" | "auto_suggested" or nullWho or what created this todo.
latestRunrequiredobject or nullThe most recent agent run on this todo, or null if an agent has never run it.
createdAtrequireddate-timeWhen the todo was created.
updatedAtrequireddate-timeWhen the todo last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/todos/{todoId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/todos/{todoId}

Update a todo

updateTodo

Change some of a todo. Fields you leave out keep their current values.

Setting `status` to `done` completes the todo and closes any chats attached to it. Setting it back to `ready` reopens it.

Passing `assignees` replaces the whole list. Adding an agent to that list starts the agent working, exactly as it does in the app.

Requires todos:write

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.

Request body

The fields to change.

FieldTypeDescription
titlestring or nullReplace the title.
contentstring or nullReplace the body.
status"ready" | "in_progress" | "done"Move the todo along. Setting `done` marks it complete.
priority"urgent" | "high" | "medium" | "low" or nullChange the urgency, or pass null to clear it.
type"task" | "responsibility"Switch between task and responsibility.
todoListIduuidMove the todo to another list.
dueDatestring or nullSet or clear the deadline.
assigneesarray of objectReplace the assignee list outright. Pass an empty array to unassign everyone.

Response 200 · The todo as it now stands.

FieldTypeDescription
objectrequired"todo"Always `todo`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullThe short line that names the work. Null when the todo only has a body.
contentrequiredstring or nullThe body of the todo: the detail an agent or a person needs to act. Markdown is preserved as written.
statusrequired"ready" | "in_progress" | "done"`ready` means nobody has started, `in_progress` means work is under way, `done` means it is finished.
priorityrequired"urgent" | "high" | "medium" | "low" or nullHow urgent the work is, or null when nobody has said.
typerequired"task" | "responsibility"A `task` is finished once. A `responsibility` is standing work that recurs.
todoListIdrequireduuidThe list this todo sits in.
dueDaterequiredstring or nullThe date the work is due, as YYYY-MM-DD, or null when there is no deadline.
assigneesrequiredarray of TodoAssigneeEveryone responsible for this todo. Empty when nobody is.
captureIdrequireduuid or nullThe capture this todo came out of, when it was created from one.
isArchivedrequiredbooleanTrue once the todo has been archived. Archived todos stay readable and can be restored.
isSuggestedrequiredbooleanTrue while this is a suggestion an agent made that nobody has accepted yet.
sourcerequired"user_created" | "agent_created" | "auto_suggested" or nullWho or what created this todo.
latestRunrequiredobject or nullThe most recent agent run on this todo, or null if an agent has never run it.
createdAtrequireddate-timeWhen the todo was created.
updatedAtrequireddate-timeWhen the todo last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/todos/{todoId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/todos/{todoId}

Delete a todo

deleteTodo

Archive a todo. It disappears from the active list, stays readable at its id, and comes back with `restoreTodo`.

Pass `permanent=true` to erase it instead. That is final, and it is refused for a todo an agent has already run, because erasing it would orphan the record of that work.

Requires todos:write

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.
permanentquery"true" | "false"Set to `true` to erase the todo instead of archiving it. Erasing cannot be undone, and a todo an agent has already run cannot be erased.

Response 200 · Confirmation that the todo was archived or erased.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/todos/{todoId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/todos/{todoId}/restore

Restore an archived todo

restoreTodo

Bring an archived todo back into the active list. A todo that was erased cannot be restored.

Requires todos:write

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.

Response 200 · The restored todo.

FieldTypeDescription
objectrequired"todo"Always `todo`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullThe short line that names the work. Null when the todo only has a body.
contentrequiredstring or nullThe body of the todo: the detail an agent or a person needs to act. Markdown is preserved as written.
statusrequired"ready" | "in_progress" | "done"`ready` means nobody has started, `in_progress` means work is under way, `done` means it is finished.
priorityrequired"urgent" | "high" | "medium" | "low" or nullHow urgent the work is, or null when nobody has said.
typerequired"task" | "responsibility"A `task` is finished once. A `responsibility` is standing work that recurs.
todoListIdrequireduuidThe list this todo sits in.
dueDaterequiredstring or nullThe date the work is due, as YYYY-MM-DD, or null when there is no deadline.
assigneesrequiredarray of TodoAssigneeEveryone responsible for this todo. Empty when nobody is.
captureIdrequireduuid or nullThe capture this todo came out of, when it was created from one.
isArchivedrequiredbooleanTrue once the todo has been archived. Archived todos stay readable and can be restored.
isSuggestedrequiredbooleanTrue while this is a suggestion an agent made that nobody has accepted yet.
sourcerequired"user_created" | "agent_created" | "auto_suggested" or nullWho or what created this todo.
latestRunrequiredobject or nullThe most recent agent run on this todo, or null if an agent has never run it.
createdAtrequireddate-timeWhen the todo was created.
updatedAtrequireddate-timeWhen the todo last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/todos/{todoId}/restore" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/todos/{todoId}/runs

Run a todo with an agent

runTodo

Put an agent to work on this todo.

The run starts in the background and this returns as soon as it has begun. The `chatId` on the response is where the work happens: read its messages to follow along, and watch the chat status to know when the agent has finished.

A todo that is already running is refused. Agent work spends Doozy Minutes.

Requires todos:write

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

Which agent to use, and what to tell it.

FieldTypeDescription
agentIduuidWhich agent should do the work. Defaults to the agent already assigned to the todo.
messagestringExtra instruction for this run. Defaults to the todo title and body.

Response 202 · The run that started. It is not finished yet.

FieldTypeDescription
objectrequired"todo_run"Always `todo_run`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
todoIdrequireduuidThe todo that was run.
chatIdrequireduuidThe chat the agent worked in. Read its messages to watch the work happen.
statusrequired"running" | "completed" | "failed"Where the run got to.
startedAtrequireddate-timeWhen the run began.
finishedAtrequireddate-time or nullWhen the run ended, or null while it is still going.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/todos/{todoId}/runs" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/todos/{todoId}/runs

List runs on a todo

listTodoRuns

Every attempt an agent has made at this todo, most recent first. Each run points at the chat where the work happened.

Requires todos:read

Parameters

ParameterInTypeDescription
todoIdrequiredpathuuidThe todo id.

Response 200 · The runs on this todo.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of TodoRunRuns on this todo, most recent first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/todos/{todoId}/runs" \
  -H "Authorization: Bearer $DOOZY_API_KEY"

Todo lists

The lists todos are filed under. Every workspace has a default list that new todos fall into.

get/todo-lists

List todo lists

listTodoLists

Every list in the workspace, default first, each with a count of the todos filed under it. Workspaces have few lists, so this returns all of them in one page.

Requires todos:read

Response 200 · The lists in this workspace.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of TodoListThe lists in this workspace, default first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/todo-lists" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/todo-lists

Create a todo list

createTodoList

Add a list to file todos under. New lists are ordinary lists; the default list is set once when a workspace is created.

Requires todos:write

Parameters

ParameterInTypeDescription
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The list to create.

FieldTypeDescription
namerequiredstringWhat to call the list.
emojistringAn emoji to show beside the name.
colorstringA colour label for the list.

Response 201 · The list that was created.

FieldTypeDescription
objectrequired"todo_list"Always `todo_list`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the list is called.
emojirequiredstring or nullAn emoji shown beside the name, when one is set.
colorrequiredstring or nullA colour label for the list, when one is set.
isDefaultrequiredbooleanTrue for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted.
todoCountrequiredintegerHow many unarchived todos are filed here.
activeTodoCountrequiredintegerHow many of those are still to do, rather than done.
createdAtrequireddate-timeWhen the list was created.
updatedAtrequireddate-timeWhen the list last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/todo-lists" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/todo-lists/{todoListId}

Get a todo list

getTodoList

Fetch one list by id, with its todo counts.

Requires todos:read

Parameters

ParameterInTypeDescription
todoListIdrequiredpathuuidThe list id.

Response 200 · The list.

FieldTypeDescription
objectrequired"todo_list"Always `todo_list`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the list is called.
emojirequiredstring or nullAn emoji shown beside the name, when one is set.
colorrequiredstring or nullA colour label for the list, when one is set.
isDefaultrequiredbooleanTrue for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted.
todoCountrequiredintegerHow many unarchived todos are filed here.
activeTodoCountrequiredintegerHow many of those are still to do, rather than done.
createdAtrequireddate-timeWhen the list was created.
updatedAtrequireddate-timeWhen the list last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/todo-lists/{todoListId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/todo-lists/{todoListId}

Update a todo list

updateTodoList

Rename a list or change how it is labelled. Anything you leave out stays as it was.

Requires todos:write

Parameters

ParameterInTypeDescription
todoListIdrequiredpathuuidThe list id.

Request body

The fields to change.

FieldTypeDescription
namestringRename the list.
emojistring or nullChange or clear the emoji.
colorstring or nullChange or clear the colour.

Response 200 · The list as it now stands.

FieldTypeDescription
objectrequired"todo_list"Always `todo_list`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the list is called.
emojirequiredstring or nullAn emoji shown beside the name, when one is set.
colorrequiredstring or nullA colour label for the list, when one is set.
isDefaultrequiredbooleanTrue for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted.
todoCountrequiredintegerHow many unarchived todos are filed here.
activeTodoCountrequiredintegerHow many of those are still to do, rather than done.
createdAtrequireddate-timeWhen the list was created.
updatedAtrequireddate-timeWhen the list last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/todo-lists/{todoListId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/todo-lists/{todoListId}

Delete a todo list

deleteTodoList

Remove a list.

A list that still holds todos is refused, and so is the default list. Move the todos to another list first, with `updateTodo`.

Requires todos:write

Parameters

ParameterInTypeDescription
todoListIdrequiredpathuuidThe list id.

Response 200 · Confirmation that the list was removed.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/todo-lists/{todoListId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"

Chats

Conversations with agents. Sending a message starts an agent and returns straight away; the reply arrives later.

get/chats

List chats

listChats

Page through the chats in the workspace, most recently active first. Active chats are returned; pass `includeArchived=true` for archived ones instead.

Requires chats:read

Parameters

ParameterInTypeDescription
limitqueryintegerHow many records to return. Between 1 and 100; defaults to 25.
cursorquerystringThe `nextCursor` from a previous page. Omit it to start from the beginning.
statusquery"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"Only chats in this state.
agentIdqueryuuidOnly chats with this agent.
queryquerystringFree text match against chat titles and subtitles.
includeArchivedquery"true" | "false"Set to `true` to list archived chats instead of active ones.

Response 200 · A page of chats.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of ChatThe chats on this page, most recently active first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed, invalid_cursor401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/chats" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/chats

Start a chat with an agent

createChat

Start a conversation and give the agent its first message.

The agent begins work immediately and this returns before the reply exists. Read `chat.status`: `running` means it is still going, `completed` means the turn is done, and `awaiting_input` means it stopped for a person to approve something.

To collect the reply, call `listMessages` with `afterSequence` set to 0 and keep the highest sequence you see. Pass `waitSeconds` to have this request hold open until the agent finishes instead.

Agent work spends Doozy Minutes.

Requires chats:write

Parameters

ParameterInTypeDescription
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The message that starts the chat.

FieldTypeDescription
messagerequiredstringWhat to say to the agent. This starts the work.
titlestringA title for the chat. One is generated from your message if you leave this out.
agentIduuidWhich agent to talk to. Omit it to use the workspace default assistant. List agents with `listAgents`.
todoIduuidAttach this chat to a todo, so the work is recorded against it.
captureIdsarray of uuidCaptures to put in front of the agent as context. Their content is loaded into the conversation.
timezonestringAn IANA timezone name, for example `Europe/London`. The agent uses it to reason about dates. Defaults to UTC.
waitSecondsintegerHold the request open for up to this many seconds, at most 120, waiting for the agent to finish, then return the chat as it stands. Omit it to return immediately.

Response 201 · The chat that was started. The agent is still working.

FieldTypeDescription
objectrequired"chat"Always `chat`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullA title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts.
subtitlerequiredstring or nullA one-line summary of what the chat is about, when one has been generated.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"`queued` and `running` mean the agent is working. `awaiting_input` means it stopped and needs a person, usually to approve a tool. `completed` means the turn finished. `failed` and `cancelled` speak for themselves.
agentIdrequireduuid or nullThe agent working in this chat, or null for a chat with the default assistant.
todoIdrequireduuid or nullThe todo this chat is doing the work for, when it is attached to one.
messageCountrequiredintegerHow many messages the chat holds.
errorMessagerequiredstring or nullWhat went wrong, when the status is `failed`.
isArchivedrequiredbooleanTrue once the chat has been archived.
createdAtrequireddate-timeWhen the chat was started.
lastMessageAtrequireddate-time or nullWhen the most recent message arrived.
completedAtrequireddate-time or nullWhen the agent last finished a turn.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/chats" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/chats/{chatId}

Get a chat

getChat

Fetch one chat by id. Read `status` to learn whether the agent is still working, and `messageCount` to see whether anything new has arrived.

Requires chats:read

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.

Response 200 · The chat.

FieldTypeDescription
objectrequired"chat"Always `chat`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullA title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts.
subtitlerequiredstring or nullA one-line summary of what the chat is about, when one has been generated.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"`queued` and `running` mean the agent is working. `awaiting_input` means it stopped and needs a person, usually to approve a tool. `completed` means the turn finished. `failed` and `cancelled` speak for themselves.
agentIdrequireduuid or nullThe agent working in this chat, or null for a chat with the default assistant.
todoIdrequireduuid or nullThe todo this chat is doing the work for, when it is attached to one.
messageCountrequiredintegerHow many messages the chat holds.
errorMessagerequiredstring or nullWhat went wrong, when the status is `failed`.
isArchivedrequiredbooleanTrue once the chat has been archived.
createdAtrequireddate-timeWhen the chat was started.
lastMessageAtrequireddate-time or nullWhen the most recent message arrived.
completedAtrequireddate-time or nullWhen the agent last finished a turn.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/chats/{chatId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/chats/{chatId}

Update a chat

updateChat

Rename a chat. Titles are generated automatically from the first message, so this is for when the generated one is wrong.

Requires chats:write

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.

Request body

The fields to change.

FieldTypeDescription
titlestringRename the chat.

Response 200 · The chat as it now stands.

FieldTypeDescription
objectrequired"chat"Always `chat`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullA title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts.
subtitlerequiredstring or nullA one-line summary of what the chat is about, when one has been generated.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"`queued` and `running` mean the agent is working. `awaiting_input` means it stopped and needs a person, usually to approve a tool. `completed` means the turn finished. `failed` and `cancelled` speak for themselves.
agentIdrequireduuid or nullThe agent working in this chat, or null for a chat with the default assistant.
todoIdrequireduuid or nullThe todo this chat is doing the work for, when it is attached to one.
messageCountrequiredintegerHow many messages the chat holds.
errorMessagerequiredstring or nullWhat went wrong, when the status is `failed`.
isArchivedrequiredbooleanTrue once the chat has been archived.
createdAtrequireddate-timeWhen the chat was started.
lastMessageAtrequireddate-time or nullWhen the most recent message arrived.
completedAtrequireddate-time or nullWhen the agent last finished a turn.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/chats/{chatId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/chats/{chatId}

Delete a chat

deleteChat

Archive a chat. It leaves the active list, stays readable at its id, and comes back with `restoreChat`.

Pass `permanent=true` to erase the chat and every message in it. That is final, and the record of what the agent did goes with it.

Requires chats:write

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.
permanentquery"true" | "false"Set to `true` to erase the chat and every message in it. That cannot be undone. The default archives it instead.

Response 200 · Confirmation that the chat was archived or erased.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/chats/{chatId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/chats/{chatId}/restore

Restore an archived chat

restoreChat

Bring an archived chat back into the active list.

Requires chats:write

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.

Response 200 · The restored chat.

FieldTypeDescription
objectrequired"chat"Always `chat`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullA title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts.
subtitlerequiredstring or nullA one-line summary of what the chat is about, when one has been generated.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"`queued` and `running` mean the agent is working. `awaiting_input` means it stopped and needs a person, usually to approve a tool. `completed` means the turn finished. `failed` and `cancelled` speak for themselves.
agentIdrequireduuid or nullThe agent working in this chat, or null for a chat with the default assistant.
todoIdrequireduuid or nullThe todo this chat is doing the work for, when it is attached to one.
messageCountrequiredintegerHow many messages the chat holds.
errorMessagerequiredstring or nullWhat went wrong, when the status is `failed`.
isArchivedrequiredbooleanTrue once the chat has been archived.
createdAtrequireddate-timeWhen the chat was started.
lastMessageAtrequireddate-time or nullWhen the most recent message arrived.
completedAtrequireddate-time or nullWhen the agent last finished a turn.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/chats/{chatId}/restore" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/chats/{chatId}/cancel

Stop a running agent

cancelChat

Stop the agent mid-turn. Whatever it had already done stays in the chat.

A cancelled chat can be picked up again by sending another message.

Requires chats:write

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.

Response 200 · The chat, now cancelled.

FieldTypeDescription
objectrequired"chat"Always `chat`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
titlerequiredstring or nullA title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts.
subtitlerequiredstring or nullA one-line summary of what the chat is about, when one has been generated.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"`queued` and `running` mean the agent is working. `awaiting_input` means it stopped and needs a person, usually to approve a tool. `completed` means the turn finished. `failed` and `cancelled` speak for themselves.
agentIdrequireduuid or nullThe agent working in this chat, or null for a chat with the default assistant.
todoIdrequireduuid or nullThe todo this chat is doing the work for, when it is attached to one.
messageCountrequiredintegerHow many messages the chat holds.
errorMessagerequiredstring or nullWhat went wrong, when the status is `failed`.
isArchivedrequiredbooleanTrue once the chat has been archived.
createdAtrequireddate-timeWhen the chat was started.
lastMessageAtrequireddate-time or nullWhen the most recent message arrived.
completedAtrequireddate-time or nullWhen the agent last finished a turn.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/chats/{chatId}/cancel" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/chats/{chatId}/messages

List messages in a chat

listMessages

Read a chat, oldest message first.

This is the poll path for agent replies. Keep the highest `sequence` you have seen and pass it as `afterSequence` to get only what has arrived since. When `hasMore` is false and the chat status is no longer `running`, you have everything.

Each message carries the readable `text` and, in `blocks`, the tool calls the agent made and what came back from them.

Requires chats:read

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.
limitqueryintegerHow many records to return. Between 1 and 100; defaults to 25.
cursorquerystringThe `nextCursor` from a previous page. Omit it to start from the beginning.
afterSequencequeryintegerOnly messages after this sequence number. This is how you poll: keep the highest sequence you have seen and ask for what came after it.

Response 200 · A page of messages.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of MessageThe messages on this page, oldest first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed, invalid_cursor401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/chats/{chatId}/messages" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/chats/{chatId}/messages

Send a message to a chat

sendMessage

Say something to the agent and start another turn.

This returns as soon as the work has started, not when the reply exists. `messageSequence` is the sequence number of the message you just sent; call `listMessages` with `afterSequence` set to it to collect the reply.

Pass `waitSeconds` to hold this request open until the agent finishes. Whatever it produced comes back in `replies`. If the time runs out, `timedOut` is true, the agent keeps working, and polling picks up where the wait left off.

A chat with an agent already mid-turn is refused. Cancel it first, or wait for the turn to end.

Agent work spends Doozy Minutes.

Requires chats:write

Parameters

ParameterInTypeDescription
chatIdrequiredpathuuidThe chat id.
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The message to send.

FieldTypeDescription
messagerequiredstringWhat to say. This starts another agent turn.
waitSecondsintegerHold the request open for up to this many seconds, at most 120, waiting for the reply, then return whatever has arrived. Omit it to return immediately.

Response 202 · The work has started. The reply may or may not have arrived, depending on `waitSeconds`.

FieldTypeDescription
objectrequired"chat_run"Always `chat_run`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
chatIdrequireduuidThe chat the agent is working in.
statusrequired"queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled"Where the chat is now. `running` means the reply has not arrived yet.
messageSequencerequiredintegerThe sequence number of the message you just sent. Poll `listMessages` with `afterSequence` set to this to collect the reply.
repliesrequiredarray of MessageMessages the agent produced while this request waited. Empty unless you passed `waitSeconds`, and possibly empty even then if the agent was still working when the wait ran out.
timedOutrequiredbooleanTrue when `waitSeconds` ran out before the agent finished. The work carries on; poll for the rest.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/chats/{chatId}/messages" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Agents

The workers in a workspace, their standing instructions, their skills, and when they are on duty.

get/agents

List agents

listAgents

Every agent in the workspace, newest first. Workspaces have few agents, so this returns all of them in one page. Use an agent id here to start a chat or to assign a todo.

Requires agents:read

Parameters

ParameterInTypeDescription
includeArchivedquery"true" | "false"Set to `true` to include archived agents in the list.

Response 200 · The agents in this workspace.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of AgentThe agents in this workspace, newest first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/agents" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/agents

Create an agent

createAgent

Add an agent to the workspace.

The name has to be unique among active agents. `instructions` is the main thing worth setting: it is what the agent follows in every conversation.

New agents pause for approval before risky actions unless you say otherwise.

Requires agents:write

Parameters

ParameterInTypeDescription
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The agent to create.

FieldTypeDescription
namerequiredstringWhat to call the agent. Names must be unique among active agents.
descriptionstringA short description of what this agent is for.
instructionsstringStanding instructions the agent follows in every conversation.
requiresApprovalbooleanWhether the agent pauses for a person before risky actions. Defaults to true, which is the safe way round.
approvalGuidancestringExtra guidance on what should and should not need approval.

Response 201 · The agent that was created.

FieldTypeDescription
objectrequired"agent"Always `agent`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the agent is called.
descriptionrequiredstring or nullA short description of what this agent is for.
instructionsrequiredstring or nullThe standing instructions the agent follows in every conversation. This is the main lever on how it behaves.
requiresApprovalrequiredbooleanTrue when the agent pauses for a person before taking actions it judges risky. False lets it act without asking.
approvalGuidancerequiredstring or nullExtra guidance on what should and should not need approval.
workingHoursEnabledrequiredbooleanTrue when the agent only works during set hours.
workingHoursrequiredWorkingHours or nullThe hours it works, when working hours are switched on.
profilePhotoUrlrequiredstring or nullA link to the agent avatar. The link is temporary and expires.
isArchivedrequiredbooleanTrue once the agent has been archived.
createdAtrequireddate-timeWhen the agent was created.
updatedAtrequireddate-timeWhen the agent last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/agents" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/agents/{agentId}

Get an agent

getAgent

Fetch one agent by id, with its instructions, approval setting and working hours.

Requires agents:read

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.

Response 200 · The agent.

FieldTypeDescription
objectrequired"agent"Always `agent`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the agent is called.
descriptionrequiredstring or nullA short description of what this agent is for.
instructionsrequiredstring or nullThe standing instructions the agent follows in every conversation. This is the main lever on how it behaves.
requiresApprovalrequiredbooleanTrue when the agent pauses for a person before taking actions it judges risky. False lets it act without asking.
approvalGuidancerequiredstring or nullExtra guidance on what should and should not need approval.
workingHoursEnabledrequiredbooleanTrue when the agent only works during set hours.
workingHoursrequiredWorkingHours or nullThe hours it works, when working hours are switched on.
profilePhotoUrlrequiredstring or nullA link to the agent avatar. The link is temporary and expires.
isArchivedrequiredbooleanTrue once the agent has been archived.
createdAtrequireddate-timeWhen the agent was created.
updatedAtrequireddate-timeWhen the agent last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/agents/{agentId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/agents/{agentId}

Update an agent

updateAgent

Change how an agent behaves. Anything you leave out stays as it was.

Changing `instructions` affects every conversation the agent has from now on, including ones already open. Turning `requiresApproval` off lets the agent act without checking with a person first.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.

Request body

The fields to change.

FieldTypeDescription
namestringRename the agent.
descriptionstring or nullChange the description.
instructionsstring or nullReplace the standing instructions. This changes how the agent behaves everywhere.
requiresApprovalbooleanSwitch the approval pause on or off.
approvalGuidancestring or nullChange the guidance on what needs approval.
workingHoursEnabledbooleanSwitch working hours on or off.
workingHoursWorkingHoursSet the hours the agent works. Start must come before end.

Response 200 · The agent as it now stands.

FieldTypeDescription
objectrequired"agent"Always `agent`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the agent is called.
descriptionrequiredstring or nullA short description of what this agent is for.
instructionsrequiredstring or nullThe standing instructions the agent follows in every conversation. This is the main lever on how it behaves.
requiresApprovalrequiredbooleanTrue when the agent pauses for a person before taking actions it judges risky. False lets it act without asking.
approvalGuidancerequiredstring or nullExtra guidance on what should and should not need approval.
workingHoursEnabledrequiredbooleanTrue when the agent only works during set hours.
workingHoursrequiredWorkingHours or nullThe hours it works, when working hours are switched on.
profilePhotoUrlrequiredstring or nullA link to the agent avatar. The link is temporary and expires.
isArchivedrequiredbooleanTrue once the agent has been archived.
createdAtrequireddate-timeWhen the agent was created.
updatedAtrequireddate-timeWhen the agent last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/agents/{agentId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/agents/{agentId}

Archive an agent

deleteAgent

Take an agent out of service. Its chats and the work it did stay where they are, and `restoreAgent` brings it back.

Agents are never erased, because erasing one would break the record of everything it did. The workspace default agent cannot be archived.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.

Response 200 · Confirmation that the agent was archived.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/agents/{agentId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/agents/{agentId}/restore

Restore an archived agent

restoreAgent

Put an archived agent back into service.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.

Response 200 · The restored agent.

FieldTypeDescription
objectrequired"agent"Always `agent`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringWhat the agent is called.
descriptionrequiredstring or nullA short description of what this agent is for.
instructionsrequiredstring or nullThe standing instructions the agent follows in every conversation. This is the main lever on how it behaves.
requiresApprovalrequiredbooleanTrue when the agent pauses for a person before taking actions it judges risky. False lets it act without asking.
approvalGuidancerequiredstring or nullExtra guidance on what should and should not need approval.
workingHoursEnabledrequiredbooleanTrue when the agent only works during set hours.
workingHoursrequiredWorkingHours or nullThe hours it works, when working hours are switched on.
profilePhotoUrlrequiredstring or nullA link to the agent avatar. The link is temporary and expires.
isArchivedrequiredbooleanTrue once the agent has been archived.
createdAtrequireddate-timeWhen the agent was created.
updatedAtrequireddate-timeWhen the agent last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/agents/{agentId}/restore" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/agents/{agentId}/skills

List an agent skills

listAgentSkills

The named procedures this agent knows. Skills are how a workspace teaches an agent to do something the same way every time.

Requires agents:read

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.

Response 200 · The skills this agent has.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of AgentSkillThe skills this agent has.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/agents/{agentId}/skills" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/agents/{agentId}/skills

Teach an agent a skill

createAgentSkill

Add a named procedure to an agent. The agent reaches for it when the work matches, so the name and the instructions are worth writing carefully.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The skill to add.

FieldTypeDescription
namerequiredstringWhat to call the skill.
instructionsstringHow the agent should carry out this skill.

Response 201 · The skill that was added.

FieldTypeDescription
objectrequired"agent_skill"Always `agent_skill`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
agentIdrequireduuidThe agent this skill belongs to.
namerequiredstringWhat the skill is called.
instructionsrequiredstring or nullHow the agent should carry out this skill.
summaryrequiredstring or nullA generated one-line summary of what the skill does.
isArchivedrequiredbooleanTrue once the skill has been archived.
createdAtrequireddate-timeWhen the skill was created.
updatedAtrequireddate-timeWhen the skill last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/agents/{agentId}/skills" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/agents/{agentId}/skills/{skillId}

Get an agent skill

getAgentSkill

Fetch one skill by id, with the instructions the agent follows for it.

Requires agents:read

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.
skillIdrequiredpathuuidThe skill id.

Response 200 · The skill.

FieldTypeDescription
objectrequired"agent_skill"Always `agent_skill`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
agentIdrequireduuidThe agent this skill belongs to.
namerequiredstringWhat the skill is called.
instructionsrequiredstring or nullHow the agent should carry out this skill.
summaryrequiredstring or nullA generated one-line summary of what the skill does.
isArchivedrequiredbooleanTrue once the skill has been archived.
createdAtrequireddate-timeWhen the skill was created.
updatedAtrequireddate-timeWhen the skill last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/agents/{agentId}/skills/{skillId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/agents/{agentId}/skills/{skillId}

Update an agent skill

updateAgentSkill

Rename a skill or rewrite its instructions.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.
skillIdrequiredpathuuidThe skill id.

Request body

The fields to change.

FieldTypeDescription
namestringRename the skill.
instructionsstring or nullReplace the instructions.

Response 200 · The skill as it now stands.

FieldTypeDescription
objectrequired"agent_skill"Always `agent_skill`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
agentIdrequireduuidThe agent this skill belongs to.
namerequiredstringWhat the skill is called.
instructionsrequiredstring or nullHow the agent should carry out this skill.
summaryrequiredstring or nullA generated one-line summary of what the skill does.
isArchivedrequiredbooleanTrue once the skill has been archived.
createdAtrequireddate-timeWhen the skill was created.
updatedAtrequireddate-timeWhen the skill last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/agents/{agentId}/skills/{skillId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/agents/{agentId}/skills/{skillId}

Archive an agent skill

deleteAgentSkill

Take a skill away from an agent. It is archived rather than erased, so the record of work done with it stays intact.

Requires agents:write

Parameters

ParameterInTypeDescription
agentIdrequiredpathuuidThe agent id.
skillIdrequiredpathuuidThe skill id.

Response 200 · Confirmation that the skill was archived.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/agents/{agentId}/skills/{skillId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"

Captures

What the workspace has recorded and written down: meeting recordings with their transcripts, notes, and the summaries generated from them.

get/captures

List captures

listCaptures

Page through the captures in the workspace, newest first.

This returns each capture without its body. Transcripts and notes run long, and a page of twenty of them would be a page nobody could use. Fetch a capture with `getCapture` to read it.

Recordings that are still running are included, with status `recording`.

Requires captures:read

Parameters

ParameterInTypeDescription
limitqueryintegerHow many records to return. Between 1 and 100; defaults to 25.
cursorquerystringThe `nextCursor` from a previous page. Omit it to start from the beginning.
queryquerystringFree text match against titles, bodies and summaries.
tagsquerystringComma separated tags. A capture must carry all of them to match. Call `listTags` to see what exists.
createdAfterquerydate-timeOnly captures made at or after this time.
createdBeforequerydate-timeOnly captures made at or before this time.
includeArchivedquery"true" | "false"Set to `true` to list archived captures instead of active ones.

Response 200 · A page of captures, without their bodies.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of CaptureThe captures on this page, newest first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed, invalid_cursor401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/captures" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/captures

Create a capture

createCapture

Record something in the workspace.

A `note` is finished the moment it is created. Its summary and any todos it suggests are generated straight after, so fetch it again a few seconds later to see them.

A `recording` opens a session and nothing more. Audio comes from a microphone and is streamed to Doozy over the workspace WebSocket by the app, the desktop client or the mobile client. Over this API you can open the session, watch it, and stop it, but you cannot supply the audio. Stop it with `stopCapture` when the recording is over.

Opening a recording session checks that the workspace has Doozy Minutes left.

This answers with the capture but not its body. Writing to a capture is not a way to read one: the transcript, notes and content are behind `captures:read`, so fetch them with `getCapture` if your key holds it.

Requires captures:write

Parameters

ParameterInTypeDescription
Idempotency-KeyheaderstringA unique string of your choosing, at most 255 characters. Retrying with the same key returns the first response instead of creating a second resource. Keys are remembered for 24 hours.

Request body

The capture to create.

FieldTypeDescription
typerequired"note"Write something down.
contentrequiredstringWhat to record. A leading markdown heading becomes the title and is taken out of the body.
tagsarray of stringTags to file it under.

Response 201 · The capture that was created, without its body.

FieldTypeDescription
objectrequired"capture"Always `capture`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
typerequired"note" | "recording"`recording` when audio was captured, `note` when it was written.
statusrequired"recording" | "processing" | "completed" | "failed"`recording` means audio is still arriving, `processing` means the transcript and summary are being made, `completed` means everything is there.
durationSecondsrequiredinteger or nullHow long the recording ran, for recordings.
recordingIdrequireduuid or nullThe recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`.
isArchivedrequiredbooleanTrue once the capture has been archived.
createdAtrequireddate-timeWhen the capture was made.
updatedAtrequireddate-timeWhen it last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key402 insufficient_minutes403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/captures" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/captures/{captureId}

Get a capture

getCapture

Fetch one capture in full: the written body, the transcript of the recording, the notes taken alongside it, and the generated summary.

For a recording that is still being transcribed, `transcript` is null and `status` is `processing`. Check back rather than assuming the recording was silent.

Requires captures:read

Parameters

ParameterInTypeDescription
captureIdrequiredpathuuidThe capture id.

Response 200 · The capture, with its content.

FieldTypeDescription
objectrequired"capture"Always `capture`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
typerequired"note" | "recording"`recording` when audio was captured, `note` when it was written.
titlerequiredstring or nullThe capture title, generated for recordings and taken from the first line of a note.
subtitlerequiredstring or nullA generated one-line description of what the capture is about.
summaryrequiredstring or nullThe generated summary. Null until processing finishes, which for a recording takes a moment after it stops.
statusrequired"recording" | "processing" | "completed" | "failed"`recording` means audio is still arriving, `processing` means the transcript and summary are being made, `completed` means everything is there.
tagsrequiredarray of stringThe tags on this capture.
durationSecondsrequiredinteger or nullHow long the recording ran, for recordings.
recordingIdrequireduuid or nullThe recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`.
isArchivedrequiredbooleanTrue once the capture has been archived.
createdAtrequireddate-timeWhen the capture was made.
updatedAtrequireddate-timeWhen it last changed.
contentrequiredstring or nullThe written body of the capture. This is the note text for a note.
transcriptrequiredstring or nullThe transcript of the recording, with speaker labels where the audio allowed them. Null for a note, and null for a recording that is still being transcribed.
notesrequiredstring or nullNotes typed alongside a recording while it was happening.
mediaUrlrequiredstring or nullA link to the audio file. The link is temporary and expires, so fetch it again rather than storing it.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/captures/{captureId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
patch/captures/{captureId}

Update a capture

updateCapture

Change a capture title, its written body, the notes taken alongside it, or its tags. Anything you leave out stays as it was.

The transcript of a recording is not editable here. It is what the recording said, and rewriting it would make the record untrue. Put corrections in `notes` instead.

This answers with the capture but not its body. Writing to a capture is not a way to read one: the transcript, notes and content are behind `captures:read`, so fetch them with `getCapture` if your key holds it.

Requires captures:write

Parameters

ParameterInTypeDescription
captureIdrequiredpathuuidThe capture id.

Request body

The fields to change.

FieldTypeDescription
titlestring or nullChange the title.
contentstring or nullReplace the written body.
notesstring or nullReplace the notes taken alongside a recording.
tagsarray of stringReplace the tag list outright. Pass an empty array to clear it.

Response 200 · The capture as it now stands, without its body.

FieldTypeDescription
objectrequired"capture"Always `capture`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
typerequired"note" | "recording"`recording` when audio was captured, `note` when it was written.
statusrequired"recording" | "processing" | "completed" | "failed"`recording` means audio is still arriving, `processing` means the transcript and summary are being made, `completed` means everything is there.
durationSecondsrequiredinteger or nullHow long the recording ran, for recordings.
recordingIdrequireduuid or nullThe recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`.
isArchivedrequiredbooleanTrue once the capture has been archived.
createdAtrequireddate-timeWhen the capture was made.
updatedAtrequireddate-timeWhen it last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X PATCH "https://api.usedoozy.com/api/v1/captures/{captureId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
delete/captures/{captureId}

Delete a capture

deleteCapture

Archive a capture. It leaves the active feed, stays readable at its id, and comes back with `restoreCapture`.

Pass `permanent=true` to erase it. The transcript, the notes and the audio go with it, and none of that can be recovered.

Requires captures:write

Parameters

ParameterInTypeDescription
captureIdrequiredpathuuidThe capture id.
permanentquery"true" | "false"Set to `true` to erase the capture, its transcript and its audio. That cannot be undone. The default archives it instead.

Response 200 · Confirmation that the capture was archived or erased.

FieldTypeDescription
objectrequired"deleted"Always `deleted`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
deletedrequiredtrueAlways true. Present so a success can be told from an error at a glance.
recoverablerequiredbooleanTrue when the resource was archived and can be restored, false when it was erased for good.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/captures/{captureId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/captures/{captureId}/restore

Restore an archived capture

restoreCapture

Bring an archived capture back into the active feed.

This answers with the capture but not its body. Writing to a capture is not a way to read one: the transcript, notes and content are behind `captures:read`, so fetch them with `getCapture` if your key holds it.

Requires captures:write

Parameters

ParameterInTypeDescription
captureIdrequiredpathuuidThe capture id.

Response 200 · The restored capture, without its body.

FieldTypeDescription
objectrequired"capture"Always `capture`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
typerequired"note" | "recording"`recording` when audio was captured, `note` when it was written.
statusrequired"recording" | "processing" | "completed" | "failed"`recording` means audio is still arriving, `processing` means the transcript and summary are being made, `completed` means everything is there.
durationSecondsrequiredinteger or nullHow long the recording ran, for recordings.
recordingIdrequireduuid or nullThe recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`.
isArchivedrequiredbooleanTrue once the capture has been archived.
createdAtrequireddate-timeWhen the capture was made.
updatedAtrequireddate-timeWhen it last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/captures/{captureId}/restore" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/captures/{captureId}/stop

Stop a recording

stopCapture

Close a recording session.

The transcript is written as the audio arrives, so this does not wait for transcription. The capture moves to `processing` while its summary and suggested todos are generated, then to `completed`.

A capture that is not a running recording is refused.

This answers with the capture but not its body. Writing to a capture is not a way to read one: the transcript, notes and content are behind `captures:read`, so fetch them with `getCapture` if your key holds it.

Requires captures:write

Parameters

ParameterInTypeDescription
captureIdrequiredpathuuidThe capture id.

Response 200 · The capture, now processing, without its body.

FieldTypeDescription
objectrequired"capture"Always `capture`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
typerequired"note" | "recording"`recording` when audio was captured, `note` when it was written.
statusrequired"recording" | "processing" | "completed" | "failed"`recording` means audio is still arriving, `processing` means the transcript and summary are being made, `completed` means everything is there.
durationSecondsrequiredinteger or nullHow long the recording ran, for recordings.
recordingIdrequireduuid or nullThe recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`.
isArchivedrequiredbooleanTrue once the capture has been archived.
createdAtrequireddate-timeWhen the capture was made.
updatedAtrequireddate-timeWhen it last changed.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope404 resource_not_found409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/captures/{captureId}/stop" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/tags

List tags

listTags

Every tag in use across the workspace. Read this before filtering captures by tag, so you filter on tags that exist rather than tags you guessed.

Requires captures:read

Response 200 · The tags in use.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of objectEvery tag in use in this workspace.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/tags" \
  -H "Authorization: Bearer $DOOZY_API_KEY"

API keys

Create, list and revoke the credentials that open this API. Managed with a signed-in user session only, never with an API key.

get/api-keys/scopes

List available scopes

listScopes

Every scope this API defines, with what each one exposes, plus the common combinations. Read this to build a key-creation screen without copying a list that will go out of date.

Response 200 · The scope catalogue.

FieldTypeDescription
objectrequired"scope_catalog"Always `scope_catalog`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
scopesrequiredarray of objectEvery scope this API defines.
presetsrequiredarray of objectCommon combinations, offered as a starting point.

Example

curl -X GET "https://api.usedoozy.com/api/v1/api-keys/scopes" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
get/api-keys

List API keys

listApiKeys

The keys in a workspace, newest first. Secrets are never included; a key is identified by its prefix and last four characters.

Parameters

ParameterInTypeDescription
workspaceIdrequiredqueryuuidThe workspace whose keys to list. You must be a member of it.
includeRevokedquery"true" | "false"Set to `true` to include revoked keys in the list.

Response 200 · The keys in this workspace.

FieldTypeDescription
objectrequired"list"Always `list` for a paginated result.
datarequiredarray of ApiKeyThe keys in this workspace, newest first.
hasMorerequiredbooleanTrue when another page is waiting behind this one.
nextCursorrequiredstring or nullPass this back as `cursor` to fetch the next page. Null on the last page.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope, api_key_auth_required, workspace_access_denied429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/api-keys" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
post/api-keys

Create an API key

createApiKey

Mint a key for a workspace.

The secret comes back once, in this response, and is never retrievable again. Doozy stores only a hash of it, so a lost key can be revoked but not recovered.

Grant the narrowest set of scopes that does the job. `captures:read` is worth thinking about separately from the rest: it opens meeting transcripts and the notes taken during them.

Any member of a workspace may create a key for it, and any member may revoke any of its keys.

Request body

The key to create.

FieldTypeDescription
workspaceIdrequireduuidThe workspace this key will open. You must be a member of it.
namerequiredstringWhat this key is for, in words you will recognise in six months. "Zapier production" beats "key 2".
scopesrequiredarray of "todos:read" | "todos:write" | "chats:read" | "chats:write" | "agents:read" | "agents:write" | "captures:read" | "captures:write"What the key may do. Grant the least that works. `todos:read`: Read todos and todo lists, including their titles, descriptions, assignees, schedules and run history. `todos:write`: Create, update, archive, restore and delete todos and todo lists, and start agent runs on a todo. `chats:read`: Read chats and every message in them, including agent replies and the tool calls the agent made. `chats:write`: Start chats, send messages, cancel a running chat, and archive, restore or delete chats. `agents:read`: Read the agents in the workspace along with their instructions, skills and working hours. `agents:write`: Create agents, change their instructions, permissions, skills and working hours, and archive or restore them. `captures:read`: Read captures in full, including the transcript of a recording, the notes taken during it, and the generated summary. `captures:write`: Create notes, start and stop recordings, edit capture titles, content and tags, and archive, restore or delete captures.
expiresInDaysintegerHow many days until the key stops working. Omit it for a key that does not expire.

Response 201 · The key, including its secret. This is the only time the secret appears.

FieldTypeDescription
objectrequired"api_key"Always `api_key`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringThe label given to the key when it was created.
prefixrequiredstringThe start of the secret, enough to recognise the key without revealing it.
last4requiredstringThe last four characters of the secret.
scopesrequiredarray of "todos:read" | "todos:write" | "chats:read" | "chats:write" | "agents:read" | "agents:write" | "captures:read" | "captures:write"What this key is allowed to do. Fixed at creation.
workspaceIdrequireduuidThe workspace this key opens. A key opens exactly one.
rateLimitPerMinuterequiredintegerHow many requests a minute this key may make.
lastUsedAtrequireddate-time or nullWhen the key was last used, recorded to the nearest minute. Null if it has never been used.
expiresAtrequireddate-time or nullWhen the key stops working, or null if it does not expire.
revokedAtrequireddate-time or nullWhen the key was revoked, or null while it still works.
createdAtrequireddate-timeWhen the key was created.
secretrequiredstringThe full key. This is the only time it is ever returned. Store it somewhere safe before you close the response; if you lose it, revoke the key and create another.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope, api_key_auth_required, workspace_access_denied409 resource_conflict429 rate_limit_exceeded500 internal_error

Example

curl -X POST "https://api.usedoozy.com/api/v1/api-keys" \
  -H "Authorization: Bearer $DOOZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
get/api-keys/{apiKeyId}

Get an API key

getApiKey

Fetch one key by id, without its secret. Useful for checking when a key was last used before revoking it.

Parameters

ParameterInTypeDescription
apiKeyIdrequiredpathuuidThe key id.

Response 200 · The key.

FieldTypeDescription
objectrequired"api_key"Always `api_key`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
namerequiredstringThe label given to the key when it was created.
prefixrequiredstringThe start of the secret, enough to recognise the key without revealing it.
last4requiredstringThe last four characters of the secret.
scopesrequiredarray of "todos:read" | "todos:write" | "chats:read" | "chats:write" | "agents:read" | "agents:write" | "captures:read" | "captures:write"What this key is allowed to do. Fixed at creation.
workspaceIdrequireduuidThe workspace this key opens. A key opens exactly one.
rateLimitPerMinuterequiredintegerHow many requests a minute this key may make.
lastUsedAtrequireddate-time or nullWhen the key was last used, recorded to the nearest minute. Null if it has never been used.
expiresAtrequireddate-time or nullWhen the key stops working, or null if it does not expire.
revokedAtrequireddate-time or nullWhen the key was revoked, or null while it still works.
createdAtrequireddate-timeWhen the key was created.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope, api_key_auth_required404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X GET "https://api.usedoozy.com/api/v1/api-keys/{apiKeyId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
delete/api-keys/{apiKeyId}

Revoke an API key

revokeApiKey

Stop a key working. This takes effect on the next request that uses it, with no grace period and no cache to wait out.

Revoking is permanent. The key is not erased: it drops out of the default listing but is still there with `includeRevoked=true`, carrying what it was and when it stopped.

Parameters

ParameterInTypeDescription
apiKeyIdrequiredpathuuidThe key id.

Response 200 · Confirmation that the key was revoked.

FieldTypeDescription
objectrequired"api_key_revoked"Always `api_key_revoked`. Every object this API returns names its own type, so a mixed list or a stored record can be told apart without context.
revokedAtrequireddate-timeWhen it was revoked. It stopped working at that moment.

Errors

400 validation_failed401 missing_credentials, invalid_api_key403 missing_scope, api_key_auth_required404 resource_not_found429 rate_limit_exceeded500 internal_error

Example

curl -X DELETE "https://api.usedoozy.com/api/v1/api-keys/{apiKeyId}" \
  -H "Authorization: Bearer $DOOZY_API_KEY"
Last updated on