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 service information
getServiceInfo
Confirm the API is reachable and find the specification. No credential needed.
Response 200 · Service information.
| Field | Type | Description |
|---|---|---|
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. |
versionrequired | string | The version of this API surface. |
documentationUrlrequired | string | Where the guides live. |
openapiUrlrequired | string | Where the machine-readable specification lives. |
Example
curl -X GET "https://api.usedoozy.com/api/v1/" \
-H "Authorization: Bearer $DOOZY_API_KEY"/openapi.jsonGet 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.
| Field | Type | Description |
|---|---|---|
openapirequired | string | The OpenAPI version, always 3.1.x. |
Example
curl -X GET "https://api.usedoozy.com/api/v1/openapi.json" \
-H "Authorization: Bearer $DOOZY_API_KEY"/meGet 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.
| Field | Type | Description |
|---|---|---|
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. |
workspacerequired | object | The workspace this credential opens. There is exactly one. |
organizationIdrequired | uuid or null | The organization the workspace belongs to, when it belongs to one. |
userrequired | object | The person behind the request: the key owner, or the signed-in user. |
credentialrequired | object | The credential that authenticated this request. |
allowedOperationsrequired | array of string | Every 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.
/todosList 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
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | integer | How many records to return. Between 1 and 100; defaults to 25. |
cursor | query | string | The `nextCursor` from a previous page. Omit it to start from the beginning. |
status | query | "ready" | "in_progress" | "done" | Only todos in this state. |
priority | query | "urgent" | "high" | "medium" | "low" | Only todos at this priority. |
type | query | "task" | "responsibility" | Only tasks, or only responsibilities. |
todoListId | query | uuid | Only todos in this list. |
captureId | query | uuid | Only todos that came from this capture. |
assigneeId | query | uuid | Only todos assigned to this user or agent. |
includeArchived | query | "true" | "false" | Set to `true` to list archived todos instead of active ones. Defaults to active. |
query | query | string | Free text match against the title and body. |
sort | query | "createdAt" | "updatedAt" | "dueDate" | "priority" | What to order by. Defaults to `createdAt`. |
order | query | "asc" | "desc" | Which direction to order in. Defaults to `desc`. |
Response 200 · A page of todos.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of Todo | The todos on this page, newest first unless you asked for another order. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/todosCreate 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
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
title | string | The short line that names the work. Give this or `content`, or both. |
content | string | The 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. |
todoListId | uuid | The list to file this under. Omit it and the todo goes to the workspace default list. |
dueDate | string | The date the work is due, as YYYY-MM-DD. |
assignees | array of object | Who is responsible. Assign an agent to make the todo runnable. Defaults to the key owner when omitted. |
captureId | uuid | Link this todo to the capture it came out of. |
run | boolean | Start 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.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | The short line that names the work. Null when the todo only has a body. |
contentrequired | string or null | The 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 null | How 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. |
todoListIdrequired | uuid | The list this todo sits in. |
dueDaterequired | string or null | The date the work is due, as YYYY-MM-DD, or null when there is no deadline. |
assigneesrequired | array of TodoAssignee | Everyone responsible for this todo. Empty when nobody is. |
captureIdrequired | uuid or null | The capture this todo came out of, when it was created from one. |
isArchivedrequired | boolean | True once the todo has been archived. Archived todos stay readable and can be restored. |
isSuggestedrequired | boolean | True while this is a suggestion an agent made that nobody has accepted yet. |
sourcerequired | "user_created" | "agent_created" | "auto_suggested" or null | Who or what created this todo. |
latestRunrequired | object or null | The most recent agent run on this todo, or null if an agent has never run it. |
createdAtrequired | date-time | When the todo was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
Response 200 · The todo.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | The short line that names the work. Null when the todo only has a body. |
contentrequired | string or null | The 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 null | How 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. |
todoListIdrequired | uuid | The list this todo sits in. |
dueDaterequired | string or null | The date the work is due, as YYYY-MM-DD, or null when there is no deadline. |
assigneesrequired | array of TodoAssignee | Everyone responsible for this todo. Empty when nobody is. |
captureIdrequired | uuid or null | The capture this todo came out of, when it was created from one. |
isArchivedrequired | boolean | True once the todo has been archived. Archived todos stay readable and can be restored. |
isSuggestedrequired | boolean | True while this is a suggestion an agent made that nobody has accepted yet. |
sourcerequired | "user_created" | "agent_created" | "auto_suggested" or null | Who or what created this todo. |
latestRunrequired | object or null | The most recent agent run on this todo, or null if an agent has never run it. |
createdAtrequired | date-time | When the todo was created. |
updatedAtrequired | date-time | When 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
title | string or null | Replace the title. |
content | string or null | Replace the body. |
status | "ready" | "in_progress" | "done" | Move the todo along. Setting `done` marks it complete. |
priority | "urgent" | "high" | "medium" | "low" or null | Change the urgency, or pass null to clear it. |
type | "task" | "responsibility" | Switch between task and responsibility. |
todoListId | uuid | Move the todo to another list. |
dueDate | string or null | Set or clear the deadline. |
assignees | array of object | Replace the assignee list outright. Pass an empty array to unassign everyone. |
Response 200 · The todo as it now stands.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | The short line that names the work. Null when the todo only has a body. |
contentrequired | string or null | The 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 null | How 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. |
todoListIdrequired | uuid | The list this todo sits in. |
dueDaterequired | string or null | The date the work is due, as YYYY-MM-DD, or null when there is no deadline. |
assigneesrequired | array of TodoAssignee | Everyone responsible for this todo. Empty when nobody is. |
captureIdrequired | uuid or null | The capture this todo came out of, when it was created from one. |
isArchivedrequired | boolean | True once the todo has been archived. Archived todos stay readable and can be restored. |
isSuggestedrequired | boolean | True while this is a suggestion an agent made that nobody has accepted yet. |
sourcerequired | "user_created" | "agent_created" | "auto_suggested" or null | Who or what created this todo. |
latestRunrequired | object or null | The most recent agent run on this todo, or null if an agent has never run it. |
createdAtrequired | date-time | When the todo was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
permanent | query | "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.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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"/todos/{todoId}/restoreRestore 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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
Response 200 · The restored todo.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | The short line that names the work. Null when the todo only has a body. |
contentrequired | string or null | The 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 null | How 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. |
todoListIdrequired | uuid | The list this todo sits in. |
dueDaterequired | string or null | The date the work is due, as YYYY-MM-DD, or null when there is no deadline. |
assigneesrequired | array of TodoAssignee | Everyone responsible for this todo. Empty when nobody is. |
captureIdrequired | uuid or null | The capture this todo came out of, when it was created from one. |
isArchivedrequired | boolean | True once the todo has been archived. Archived todos stay readable and can be restored. |
isSuggestedrequired | boolean | True while this is a suggestion an agent made that nobody has accepted yet. |
sourcerequired | "user_created" | "agent_created" | "auto_suggested" or null | Who or what created this todo. |
latestRunrequired | object or null | The most recent agent run on this todo, or null if an agent has never run it. |
createdAtrequired | date-time | When the todo was created. |
updatedAtrequired | date-time | When 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"/todos/{todoId}/runsRun 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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
agentId | uuid | Which agent should do the work. Defaults to the agent already assigned to the todo. |
message | string | Extra instruction for this run. Defaults to the todo title and body. |
Response 202 · The run that started. It is not finished yet.
| Field | Type | Description |
|---|---|---|
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. |
todoIdrequired | uuid | The todo that was run. |
chatIdrequired | uuid | The chat the agent worked in. Read its messages to watch the work happen. |
statusrequired | "running" | "completed" | "failed" | Where the run got to. |
startedAtrequired | date-time | When the run began. |
finishedAtrequired | date-time or null | When 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 '{ ... }'/todos/{todoId}/runsList 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
| Parameter | In | Type | Description |
|---|---|---|---|
todoIdrequired | path | uuid | The todo id. |
Response 200 · The runs on this todo.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of TodoRun | Runs on this todo, most recent first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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.
/todo-listsList 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.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of TodoList | The lists in this workspace, default first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/todo-listsCreate 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
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
namerequired | string | What to call the list. |
emoji | string | An emoji to show beside the name. |
color | string | A colour label for the list. |
Response 201 · The list that was created.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the list is called. |
emojirequired | string or null | An emoji shown beside the name, when one is set. |
colorrequired | string or null | A colour label for the list, when one is set. |
isDefaultrequired | boolean | True for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted. |
todoCountrequired | integer | How many unarchived todos are filed here. |
activeTodoCountrequired | integer | How many of those are still to do, rather than done. |
createdAtrequired | date-time | When the list was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/todo-lists/{todoListId}Get a todo list
getTodoList
Fetch one list by id, with its todo counts.
Requires todos:read
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
todoListIdrequired | path | uuid | The list id. |
Response 200 · The list.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the list is called. |
emojirequired | string or null | An emoji shown beside the name, when one is set. |
colorrequired | string or null | A colour label for the list, when one is set. |
isDefaultrequired | boolean | True for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted. |
todoCountrequired | integer | How many unarchived todos are filed here. |
activeTodoCountrequired | integer | How many of those are still to do, rather than done. |
createdAtrequired | date-time | When the list was created. |
updatedAtrequired | date-time | When 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
todoListIdrequired | path | uuid | The list id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
name | string | Rename the list. |
emoji | string or null | Change or clear the emoji. |
color | string or null | Change or clear the colour. |
Response 200 · The list as it now stands.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the list is called. |
emojirequired | string or null | An emoji shown beside the name, when one is set. |
colorrequired | string or null | A colour label for the list, when one is set. |
isDefaultrequired | boolean | True for the one list a workspace files todos into when no list is named. Every workspace has exactly one, and it cannot be deleted. |
todoCountrequired | integer | How many unarchived todos are filed here. |
activeTodoCountrequired | integer | How many of those are still to do, rather than done. |
createdAtrequired | date-time | When the list was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
todoListIdrequired | path | uuid | The list id. |
Response 200 · Confirmation that the list was removed.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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.
/chatsList 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
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | integer | How many records to return. Between 1 and 100; defaults to 25. |
cursor | query | string | The `nextCursor` from a previous page. Omit it to start from the beginning. |
status | query | "queued" | "running" | "awaiting_input" | "completed" | "failed" | "cancelled" | Only chats in this state. |
agentId | query | uuid | Only chats with this agent. |
query | query | string | Free text match against chat titles and subtitles. |
includeArchived | query | "true" | "false" | Set to `true` to list archived chats instead of active ones. |
Response 200 · A page of chats.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of Chat | The chats on this page, most recently active first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/chatsStart 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
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
messagerequired | string | What to say to the agent. This starts the work. |
title | string | A title for the chat. One is generated from your message if you leave this out. |
agentId | uuid | Which agent to talk to. Omit it to use the workspace default assistant. List agents with `listAgents`. |
todoId | uuid | Attach this chat to a todo, so the work is recorded against it. |
captureIds | array of uuid | Captures to put in front of the agent as context. Their content is loaded into the conversation. |
timezone | string | An IANA timezone name, for example `Europe/London`. The agent uses it to reason about dates. Defaults to UTC. |
waitSeconds | integer | Hold 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.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | A title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts. |
subtitlerequired | string or null | A 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. |
agentIdrequired | uuid or null | The agent working in this chat, or null for a chat with the default assistant. |
todoIdrequired | uuid or null | The todo this chat is doing the work for, when it is attached to one. |
messageCountrequired | integer | How many messages the chat holds. |
errorMessagerequired | string or null | What went wrong, when the status is `failed`. |
isArchivedrequired | boolean | True once the chat has been archived. |
createdAtrequired | date-time | When the chat was started. |
lastMessageAtrequired | date-time or null | When the most recent message arrived. |
completedAtrequired | date-time or null | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
Response 200 · The chat.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | A title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts. |
subtitlerequired | string or null | A 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. |
agentIdrequired | uuid or null | The agent working in this chat, or null for a chat with the default assistant. |
todoIdrequired | uuid or null | The todo this chat is doing the work for, when it is attached to one. |
messageCountrequired | integer | How many messages the chat holds. |
errorMessagerequired | string or null | What went wrong, when the status is `failed`. |
isArchivedrequired | boolean | True once the chat has been archived. |
createdAtrequired | date-time | When the chat was started. |
lastMessageAtrequired | date-time or null | When the most recent message arrived. |
completedAtrequired | date-time or null | When 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
title | string | Rename the chat. |
Response 200 · The chat as it now stands.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | A title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts. |
subtitlerequired | string or null | A 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. |
agentIdrequired | uuid or null | The agent working in this chat, or null for a chat with the default assistant. |
todoIdrequired | uuid or null | The todo this chat is doing the work for, when it is attached to one. |
messageCountrequired | integer | How many messages the chat holds. |
errorMessagerequired | string or null | What went wrong, when the status is `failed`. |
isArchivedrequired | boolean | True once the chat has been archived. |
createdAtrequired | date-time | When the chat was started. |
lastMessageAtrequired | date-time or null | When the most recent message arrived. |
completedAtrequired | date-time or null | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
permanent | query | "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.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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"/chats/{chatId}/restoreRestore an archived chat
restoreChat
Bring an archived chat back into the active list.
Requires chats:write
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
Response 200 · The restored chat.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | A title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts. |
subtitlerequired | string or null | A 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. |
agentIdrequired | uuid or null | The agent working in this chat, or null for a chat with the default assistant. |
todoIdrequired | uuid or null | The todo this chat is doing the work for, when it is attached to one. |
messageCountrequired | integer | How many messages the chat holds. |
errorMessagerequired | string or null | What went wrong, when the status is `failed`. |
isArchivedrequired | boolean | True once the chat has been archived. |
createdAtrequired | date-time | When the chat was started. |
lastMessageAtrequired | date-time or null | When the most recent message arrived. |
completedAtrequired | date-time or null | When 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"/chats/{chatId}/cancelStop 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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
Response 200 · The chat, now cancelled.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | A title generated from the first message. Null until the agent has written one, which happens shortly after a chat starts. |
subtitlerequired | string or null | A 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. |
agentIdrequired | uuid or null | The agent working in this chat, or null for a chat with the default assistant. |
todoIdrequired | uuid or null | The todo this chat is doing the work for, when it is attached to one. |
messageCountrequired | integer | How many messages the chat holds. |
errorMessagerequired | string or null | What went wrong, when the status is `failed`. |
isArchivedrequired | boolean | True once the chat has been archived. |
createdAtrequired | date-time | When the chat was started. |
lastMessageAtrequired | date-time or null | When the most recent message arrived. |
completedAtrequired | date-time or null | When 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"/chats/{chatId}/messagesList 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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
limit | query | integer | How many records to return. Between 1 and 100; defaults to 25. |
cursor | query | string | The `nextCursor` from a previous page. Omit it to start from the beginning. |
afterSequence | query | integer | Only 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.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of Message | The messages on this page, oldest first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/chats/{chatId}/messagesSend 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
| Parameter | In | Type | Description |
|---|---|---|---|
chatIdrequired | path | uuid | The chat id. |
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
messagerequired | string | What to say. This starts another agent turn. |
waitSeconds | integer | Hold 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`.
| Field | Type | Description |
|---|---|---|
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. |
chatIdrequired | uuid | The 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. |
messageSequencerequired | integer | The sequence number of the message you just sent. Poll `listMessages` with `afterSequence` set to this to collect the reply. |
repliesrequired | array of Message | Messages 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. |
timedOutrequired | boolean | True 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.
/agentsList 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
| Parameter | In | Type | Description |
|---|---|---|---|
includeArchived | query | "true" | "false" | Set to `true` to include archived agents in the list. |
Response 200 · The agents in this workspace.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of Agent | The agents in this workspace, newest first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/agentsCreate 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
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
namerequired | string | What to call the agent. Names must be unique among active agents. |
description | string | A short description of what this agent is for. |
instructions | string | Standing instructions the agent follows in every conversation. |
requiresApproval | boolean | Whether the agent pauses for a person before risky actions. Defaults to true, which is the safe way round. |
approvalGuidance | string | Extra guidance on what should and should not need approval. |
Response 201 · The agent that was created.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the agent is called. |
descriptionrequired | string or null | A short description of what this agent is for. |
instructionsrequired | string or null | The standing instructions the agent follows in every conversation. This is the main lever on how it behaves. |
requiresApprovalrequired | boolean | True when the agent pauses for a person before taking actions it judges risky. False lets it act without asking. |
approvalGuidancerequired | string or null | Extra guidance on what should and should not need approval. |
workingHoursEnabledrequired | boolean | True when the agent only works during set hours. |
workingHoursrequired | WorkingHours or null | The hours it works, when working hours are switched on. |
profilePhotoUrlrequired | string or null | A link to the agent avatar. The link is temporary and expires. |
isArchivedrequired | boolean | True once the agent has been archived. |
createdAtrequired | date-time | When the agent was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/agents/{agentId}Get an agent
getAgent
Fetch one agent by id, with its instructions, approval setting and working hours.
Requires agents:read
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Response 200 · The agent.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the agent is called. |
descriptionrequired | string or null | A short description of what this agent is for. |
instructionsrequired | string or null | The standing instructions the agent follows in every conversation. This is the main lever on how it behaves. |
requiresApprovalrequired | boolean | True when the agent pauses for a person before taking actions it judges risky. False lets it act without asking. |
approvalGuidancerequired | string or null | Extra guidance on what should and should not need approval. |
workingHoursEnabledrequired | boolean | True when the agent only works during set hours. |
workingHoursrequired | WorkingHours or null | The hours it works, when working hours are switched on. |
profilePhotoUrlrequired | string or null | A link to the agent avatar. The link is temporary and expires. |
isArchivedrequired | boolean | True once the agent has been archived. |
createdAtrequired | date-time | When the agent was created. |
updatedAtrequired | date-time | When 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
name | string | Rename the agent. |
description | string or null | Change the description. |
instructions | string or null | Replace the standing instructions. This changes how the agent behaves everywhere. |
requiresApproval | boolean | Switch the approval pause on or off. |
approvalGuidance | string or null | Change the guidance on what needs approval. |
workingHoursEnabled | boolean | Switch working hours on or off. |
workingHours | WorkingHours | Set the hours the agent works. Start must come before end. |
Response 200 · The agent as it now stands.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the agent is called. |
descriptionrequired | string or null | A short description of what this agent is for. |
instructionsrequired | string or null | The standing instructions the agent follows in every conversation. This is the main lever on how it behaves. |
requiresApprovalrequired | boolean | True when the agent pauses for a person before taking actions it judges risky. False lets it act without asking. |
approvalGuidancerequired | string or null | Extra guidance on what should and should not need approval. |
workingHoursEnabledrequired | boolean | True when the agent only works during set hours. |
workingHoursrequired | WorkingHours or null | The hours it works, when working hours are switched on. |
profilePhotoUrlrequired | string or null | A link to the agent avatar. The link is temporary and expires. |
isArchivedrequired | boolean | True once the agent has been archived. |
createdAtrequired | date-time | When the agent was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Response 200 · Confirmation that the agent was archived.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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"/agents/{agentId}/restoreRestore an archived agent
restoreAgent
Put an archived agent back into service.
Requires agents:write
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Response 200 · The restored agent.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | What the agent is called. |
descriptionrequired | string or null | A short description of what this agent is for. |
instructionsrequired | string or null | The standing instructions the agent follows in every conversation. This is the main lever on how it behaves. |
requiresApprovalrequired | boolean | True when the agent pauses for a person before taking actions it judges risky. False lets it act without asking. |
approvalGuidancerequired | string or null | Extra guidance on what should and should not need approval. |
workingHoursEnabledrequired | boolean | True when the agent only works during set hours. |
workingHoursrequired | WorkingHours or null | The hours it works, when working hours are switched on. |
profilePhotoUrlrequired | string or null | A link to the agent avatar. The link is temporary and expires. |
isArchivedrequired | boolean | True once the agent has been archived. |
createdAtrequired | date-time | When the agent was created. |
updatedAtrequired | date-time | When 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"/agents/{agentId}/skillsList 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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Response 200 · The skills this agent has.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of AgentSkill | The skills this agent has. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/agents/{agentId}/skillsTeach 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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
namerequired | string | What to call the skill. |
instructions | string | How the agent should carry out this skill. |
Response 201 · The skill that was added.
| Field | Type | Description |
|---|---|---|
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. |
agentIdrequired | uuid | The agent this skill belongs to. |
namerequired | string | What the skill is called. |
instructionsrequired | string or null | How the agent should carry out this skill. |
summaryrequired | string or null | A generated one-line summary of what the skill does. |
isArchivedrequired | boolean | True once the skill has been archived. |
createdAtrequired | date-time | When the skill was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
skillIdrequired | path | uuid | The skill id. |
Response 200 · The skill.
| Field | Type | Description |
|---|---|---|
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. |
agentIdrequired | uuid | The agent this skill belongs to. |
namerequired | string | What the skill is called. |
instructionsrequired | string or null | How the agent should carry out this skill. |
summaryrequired | string or null | A generated one-line summary of what the skill does. |
isArchivedrequired | boolean | True once the skill has been archived. |
createdAtrequired | date-time | When the skill was created. |
updatedAtrequired | date-time | When 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"/agents/{agentId}/skills/{skillId}Update an agent skill
updateAgentSkill
Rename a skill or rewrite its instructions.
Requires agents:write
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
skillIdrequired | path | uuid | The skill id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
name | string | Rename the skill. |
instructions | string or null | Replace the instructions. |
Response 200 · The skill as it now stands.
| Field | Type | Description |
|---|---|---|
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. |
agentIdrequired | uuid | The agent this skill belongs to. |
namerequired | string | What the skill is called. |
instructionsrequired | string or null | How the agent should carry out this skill. |
summaryrequired | string or null | A generated one-line summary of what the skill does. |
isArchivedrequired | boolean | True once the skill has been archived. |
createdAtrequired | date-time | When the skill was created. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
agentIdrequired | path | uuid | The agent id. |
skillIdrequired | path | uuid | The skill id. |
Response 200 · Confirmation that the skill was archived.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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.
/capturesList 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
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | integer | How many records to return. Between 1 and 100; defaults to 25. |
cursor | query | string | The `nextCursor` from a previous page. Omit it to start from the beginning. |
query | query | string | Free text match against titles, bodies and summaries. |
tags | query | string | Comma separated tags. A capture must carry all of them to match. Call `listTags` to see what exists. |
createdAfter | query | date-time | Only captures made at or after this time. |
createdBefore | query | date-time | Only captures made at or before this time. |
includeArchived | query | "true" | "false" | Set to `true` to list archived captures instead of active ones. |
Response 200 · A page of captures, without their bodies.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of Capture | The captures on this page, newest first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/capturesCreate 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
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | A 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.
| Field | Type | Description |
|---|---|---|
typerequired | "note" | Write something down. |
contentrequired | string | What to record. A leading markdown heading becomes the title and is taken out of the body. |
tags | array of string | Tags to file it under. |
Response 201 · The capture that was created, without its body.
| Field | Type | Description |
|---|---|---|
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. |
durationSecondsrequired | integer or null | How long the recording ran, for recordings. |
recordingIdrequired | uuid or null | The recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`. |
isArchivedrequired | boolean | True once the capture has been archived. |
createdAtrequired | date-time | When the capture was made. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
captureIdrequired | path | uuid | The capture id. |
Response 200 · The capture, with its content.
| Field | Type | Description |
|---|---|---|
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. |
titlerequired | string or null | The capture title, generated for recordings and taken from the first line of a note. |
subtitlerequired | string or null | A generated one-line description of what the capture is about. |
summaryrequired | string or null | The 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. |
tagsrequired | array of string | The tags on this capture. |
durationSecondsrequired | integer or null | How long the recording ran, for recordings. |
recordingIdrequired | uuid or null | The recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`. |
isArchivedrequired | boolean | True once the capture has been archived. |
createdAtrequired | date-time | When the capture was made. |
updatedAtrequired | date-time | When it last changed. |
contentrequired | string or null | The written body of the capture. This is the note text for a note. |
transcriptrequired | string or null | The 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. |
notesrequired | string or null | Notes typed alongside a recording while it was happening. |
mediaUrlrequired | string or null | A 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
captureIdrequired | path | uuid | The capture id. |
Request body
The fields to change.
| Field | Type | Description |
|---|---|---|
title | string or null | Change the title. |
content | string or null | Replace the written body. |
notes | string or null | Replace the notes taken alongside a recording. |
tags | array of string | Replace the tag list outright. Pass an empty array to clear it. |
Response 200 · The capture as it now stands, without its body.
| Field | Type | Description |
|---|---|---|
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. |
durationSecondsrequired | integer or null | How long the recording ran, for recordings. |
recordingIdrequired | uuid or null | The recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`. |
isArchivedrequired | boolean | True once the capture has been archived. |
createdAtrequired | date-time | When the capture was made. |
updatedAtrequired | date-time | When 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
captureIdrequired | path | uuid | The capture id. |
permanent | query | "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.
| Field | Type | Description |
|---|---|---|
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. |
deletedrequired | true | Always true. Present so a success can be told from an error at a glance. |
recoverablerequired | boolean | True 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"/captures/{captureId}/restoreRestore 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
| Parameter | In | Type | Description |
|---|---|---|---|
captureIdrequired | path | uuid | The capture id. |
Response 200 · The restored capture, without its body.
| Field | Type | Description |
|---|---|---|
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. |
durationSecondsrequired | integer or null | How long the recording ran, for recordings. |
recordingIdrequired | uuid or null | The recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`. |
isArchivedrequired | boolean | True once the capture has been archived. |
createdAtrequired | date-time | When the capture was made. |
updatedAtrequired | date-time | When 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"/captures/{captureId}/stopStop 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
| Parameter | In | Type | Description |
|---|---|---|---|
captureIdrequired | path | uuid | The capture id. |
Response 200 · The capture, now processing, without its body.
| Field | Type | Description |
|---|---|---|
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. |
durationSecondsrequired | integer or null | How long the recording ran, for recordings. |
recordingIdrequired | uuid or null | The recording session behind this capture, for recordings. An identifier only; the audio and its transcript are behind `captures:read`. |
isArchivedrequired | boolean | True once the capture has been archived. |
createdAtrequired | date-time | When the capture was made. |
updatedAtrequired | date-time | When 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"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.
/api-keys/scopesList 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.
| Field | Type | Description |
|---|---|---|
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. |
scopesrequired | array of object | Every scope this API defines. |
presetsrequired | array of object | Common 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"/api-keysList 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
| Parameter | In | Type | Description |
|---|---|---|---|
workspaceIdrequired | query | uuid | The workspace whose keys to list. You must be a member of it. |
includeRevoked | query | "true" | "false" | Set to `true` to include revoked keys in the list. |
Response 200 · The keys in this workspace.
| Field | Type | Description |
|---|---|---|
objectrequired | "list" | Always `list` for a paginated result. |
datarequired | array of ApiKey | The keys in this workspace, newest first. |
hasMorerequired | boolean | True when another page is waiting behind this one. |
nextCursorrequired | string or null | Pass 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"/api-keysCreate 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.
| Field | Type | Description |
|---|---|---|
workspaceIdrequired | uuid | The workspace this key will open. You must be a member of it. |
namerequired | string | What this key is for, in words you will recognise in six months. "Zapier production" beats "key 2". |
scopesrequired | array 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. |
expiresInDays | integer | How 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.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | The label given to the key when it was created. |
prefixrequired | string | The start of the secret, enough to recognise the key without revealing it. |
last4required | string | The last four characters of the secret. |
scopesrequired | array 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. |
workspaceIdrequired | uuid | The workspace this key opens. A key opens exactly one. |
rateLimitPerMinuterequired | integer | How many requests a minute this key may make. |
lastUsedAtrequired | date-time or null | When the key was last used, recorded to the nearest minute. Null if it has never been used. |
expiresAtrequired | date-time or null | When the key stops working, or null if it does not expire. |
revokedAtrequired | date-time or null | When the key was revoked, or null while it still works. |
createdAtrequired | date-time | When the key was created. |
secretrequired | string | The 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 '{ ... }'/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
| Parameter | In | Type | Description |
|---|---|---|---|
apiKeyIdrequired | path | uuid | The key id. |
Response 200 · The key.
| Field | Type | Description |
|---|---|---|
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. |
namerequired | string | The label given to the key when it was created. |
prefixrequired | string | The start of the secret, enough to recognise the key without revealing it. |
last4required | string | The last four characters of the secret. |
scopesrequired | array 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. |
workspaceIdrequired | uuid | The workspace this key opens. A key opens exactly one. |
rateLimitPerMinuterequired | integer | How many requests a minute this key may make. |
lastUsedAtrequired | date-time or null | When the key was last used, recorded to the nearest minute. Null if it has never been used. |
expiresAtrequired | date-time or null | When the key stops working, or null if it does not expire. |
revokedAtrequired | date-time or null | When the key was revoked, or null while it still works. |
createdAtrequired | date-time | When 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"/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
| Parameter | In | Type | Description |
|---|---|---|---|
apiKeyIdrequired | path | uuid | The key id. |
Response 200 · Confirmation that the key was revoked.
| Field | Type | Description |
|---|---|---|
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. |
revokedAtrequired | date-time | When 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"