Plan · Home & search
Entitlements, the home screen in one request, my tasks, favorites, inbox, activity, timeline, search, organization labels and milestones. Part of the Dailybot Plan API (Beta).
On this page
Beta
Plan is in beta. Everything under /plan in the web app, the CLI and agent skill commands for projects, goals, boards and tasks, and the /v1/plan/ public API may change before general availability. Want to try it with your team? Write to [email protected].
The calling user's tasks
Your tasks, the same as GET /v1/plan/tasks/?owner=me plus the scope choice. Needs a person: an agent or organization key gets 403 insufficient_scope, never an empty list; a personal API key works.
Query parameters
Pagination
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | 1-based page number. |
| page_size | integer | Optional | Rows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100. |
Filters
| Name | Type | Required | Description |
|---|---|---|---|
| scope | string | Optional | Which sense of "mine": owned is owner = me; participating means you are on the card; involved is the union of owned, participating and created by you, which is what a person means by "my tasks". |
| state | array | Optional | Repeatable; values are OR-ed. Each value is either a workflow-state uuid or one of two lifecycle tokens:
- open - the state categories that are not terminal: backlog, todo, in_progress.
- done - the terminal categories: done, canceled.
The tokens are decided by state.category alone and never consult completed_at, so a client that classifies rows by the category on the state chip agrees with this filter by construction.
Mixing is allowed: a uuid and a token in the same request are OR-ed like any other repeated value. Any other value is 400 invalid_filter_value with extra.parameter: "state" - including overdue, which is not a lifecycle state. Overdue is a due-date question: see due_before. |
| category | array | Optional | The five fixed state categories. There is no blocked category — blocked-ness is a relation; use blocked=true. |
| priority | array | Optional | 1=urgent, 2=high, 3=medium, 4=low, 5=none. Repeatable. |
| blocked | boolean | Optional | Derived from relations, not from a status. This is the query the product answers with a link rather than a state.
blocked=true means a live blocker: a blocks relation whose source task is neither archived nor in a terminal category. A blocker that is itself done or canceled blocks nothing and does not match.
Orthogonal to lifecycle. A finished task can still carry a live blocker, so blocked=true alone returns terminal rows too. Work a person can act on is blocked=true&state=open — that combination is what reproduces the blocked tile on GET /v1/plan/pulse/. |
Dates
| Name | Type | Required | Description |
|---|---|---|---|
| due_before | string | Optional | Inclusive. Alone, this means overdue or due by that date - it does not exclude work that is already finished.
Overdue is spelled due_before=<today>&state=open. That pairing is the supported spelling, it is what reproduces the overdue tile on GET /v1/plan/pulse/, and there is deliberately no state=overdue sugar: state is a lifecycle dimension and overdue is a date one, so a single spelling keeps the two from drifting. state=overdue answers 400 invalid_filter_value, which is evidence about that spelling and not about the capability. |
Sorting & expansion
| Name | Type | Required | Description |
|---|---|---|---|
| sort | string | Optional | One field, optionally --prefixed. Every ordering appends a stable internal tiebreak so a row cannot appear on two pages. An unsupported value is 400 invalid_sort, never a silent fallback. |
Archived rows
| Name | Type | Required | Description |
|---|---|---|---|
| include_archived | boolean | Optional | Include archived rows alongside live ones. Distinct from is_archived, which selects one set or the other: include_archived=true is the union. Lists return live rows unless you opt in. |
Task object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | uuid | Required | Stable public identifier. |
| key | string | Required | Human-readable key KEY-n, for example ENG-142. Retired keys keep resolving. |
| title | string | Required | The task's title. Max 255 characters. |
| description | string | null | Optional | Free-form description. |
| board | uuid | Optional | The board. |
| state | WorkflowState | Required | The task's workflow state (its column). See WorkflowState. |
| priority | integer | Optional | 1 urgent, 2 high, 3 medium, 4 low, 5 none. From 1 to 5. |
| estimate | integer | null | Optional | Estimate on the board's scale. |
| owner | UserRef | null | Optional | The person accountable for the task. See UserRef. |
| executor | ActorRef | null | Optional | The actor doing the work, when different from the owner (for example an agent). See ActorRef. |
| executors | object[] | Optional | Every agent that has executed a write on this task on someone's behalf, newest first: {uuid, name, username, avatar, first_at, last_at}. Separate from executor, which stays the current ball-holder. Only on task detail and single-task write responses; omitted on list rows. |
| participant_count | integer | Optional | Number of participants. |
| start_date | date | null | Optional | Planned start date. |
| due_date | date | null | Optional | Due date. |
| milestone | null | {uuid, name, date} | Optional | The milestone this task counts toward. All fields are always present. |
| parent_task | null | {uuid, key, title} | Optional | The parent task, for a sub-task. One level of nesting only. All fields are always present. |
| subtask_count | integer | Optional | Number of sub-tasks. |
| subtask_done_count | integer | Optional | Number of finished sub-tasks. |
| attachment_count | integer | Optional | Number of attachments. |
| open_blocker_count | integer | Optional | Number of live blockers. |
| labels | array<Label> | Optional | Organization labels on the task. See Label. |
| rank | string | null | Optional | Opaque order within the column. Never compute it: move with after / before. |
| blocked | boolean | Optional | Tasks with a live blocker. |
| blocked_since | date-time | null | Optional | When the task became blocked. |
| completed_at | date-time | null | Optional | When it was completed, or null. |
| is_archived | boolean | Required | Whether the row is archived. Archive is the delete: archived rows stay readable and restorable. |
| subscribed | boolean | Optional | Whether you watch this task. |
| version | integer | Required | Increments on every write. Send it back as If-Match to refuse a stale update. |
| created_by | ActorRef | null | Optional | Who created the row. See ActorRef. |
| created_at | date-time | Optional | When the row was created. |
| updated_at | date-time | Optional | When the row last changed. |
WorkflowState object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | uuid | Required | Stable public identifier. |
| name | string | Required | Display name. Max 48 characters. |
| category | enum | Required | One of the five fixed categories. It never changes after create. One of backlog, todo, in_progress, done, canceled. |
| position | integer | Required | Column position, left to right. Minimum 0. |
| color | string | Optional | Display color (hex). |
| is_default | boolean | Optional | Whether new tasks land in this state by default. |
| is_archived | boolean | Optional | Whether the row is archived. Archive is the delete: archived rows stay readable and restorable. |
| task_count | integer | Optional | Number of live tasks. |
UserRef object
ActorRef object
Label object
Response
| Name | Type | Required | Description |
|---|---|---|---|
| count | integer | Required | Total number of rows. |
| next | uri | Required | URL of the next page, or null. |
| previous | uri | Required | URL of the previous page, or null. |
| results | array<Task> | Required | The rows on this page. See Task. |
Errors
| Status | When |
|---|---|
| 400 | An invalid filter value. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/me/tasks/?scope=involved&state=open" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks mine --scope involved --json{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "00000000-0000-4000-8000-000000000005",
"key": "ENG-142",
"title": "Ship the delta feed",
"description": null,
"board": "00000000-0000-4000-8000-000000000002",
"state": {
"uuid": "00000000-0000-4000-8000-000000000003",
"name": "In Progress",
"category": "in_progress",
"position": 2
},
"priority": 2,
"estimate": 3,
"owner": {
"uuid": "00000000-0000-4000-8000-00000000000c",
"name": "Ada L."
},
"executor": null,
"participant_count": 1,
"start_date": "2026-09-28",
"due_date": "2026-10-15",
"milestone": null,
"parent_task": null,
"subtask_count": 1,
"subtask_done_count": 1,
"attachment_count": 1,
"open_blocker_count": 1,
"labels": [],
"rank": "aU",
"blocked": false,
"blocked_since": null,
"completed_at": null,
"is_archived": false,
"subscribed": true,
"version": 7,
"created_by": {
"kind": "user",
"uuid": "00000000-0000-4000-8000-00000000000c",
"name": "Ada L."
},
"created_at": "2026-09-25T10:14:02Z",
"updated_at": "2026-09-25T10:14:02Z"
}
]
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Personal task tab counts
Caller-scoped counts for owned, participating, involved, and overdue work.
The four top-level integers are population totals across every lifecycle: owned counts every task assigned to the caller whether it is open, done or canceled. overdue is the exception and is owned-only, already excluding archived and terminal work.
by_scope carries the status-qualified numbers, so a badge can say "N open" without a second request. open is decided by the state CATEGORY, exactly as ?state=open decides it; overdue means open AND past due; blocked uses the one live-blocker predicate. Every number is computed in the same single aggregate over the same visibility root.
by_scope.<scope>.total equals the top-level integer of the same name by construction.
MyTaskCounts object
| Name | Type | Required | Description |
|---|---|---|---|
| owned | integer | Required | Tasks you own (all lifecycles). |
| participating | integer | Required | Tasks you participate in. |
| involved | integer | Required | Owned, participating or created by you. |
| overdue | integer | Required | Open tasks past their due date. |
| by_scope | object | Required | Status-qualified counts per scope: {total, open, overdue, blocked}. Shape: {owned, participating, involved} — each {total, open, overdue, blocked: integer} (all required). |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | MyTaskCounts | Required | A MyTaskCounts object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/me/tasks/counts/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks counts{
"owned": 1,
"participating": 1,
"involved": 1,
"overdue": 1,
"by_scope": {}
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Recently visited boards for the caller
Boards you opened recently, newest first, as recorded by POST /v1/plan/boards/{board_id}/visit/. Hidden, archived and other organizations' boards are omitted rather than raised. Needs a person (an agent or organization key gets 403; a personal API key works).
RecentBoardList object
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | RecentBoardList | Required | A RecentBoardList object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/me/recents/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"{
"count": 1,
"limit": 1,
"results": []
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Notification-worthy task events for the caller
Your inbox: task events worth your attention, newest first, as a page. mentioned=true keeps only the events where someone mentioned you; type keeps one event type. Both combine, and count and paging are exact, so there are no empty pages.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | 1-based page number. |
| page_size | integer | Optional | Rows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100. |
| type | string | Optional | Only events of this type, such as task.owner_changed (the Assigned tab). Combines with mentioned (AND). |
| mentioned | boolean | Optional | true keeps only the events where someone mentioned you. Must be true or false. |
ActivityEvent object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string | Required | Stable public identifier. |
| type | string | Required | The event type. New types are added over time: ignore ones you do not recognise. |
| actor | object | Required | Who acted. |
| executed_by_agent | object | null | Optional | The agent that executed this on behalf of the person, or null when no agent was named: an object with uuid, name, username and avatar. The person in the author field is still the author; the agent is shown as the one who executed it. |
| created_at | string | Required | When the row was created. |
| task | object | Optional | Shape: {uuid, key, title, board {uuid, key, name} | null} | null. |
| payload | object | Required | Ids, enum values, numbers, booleans and dates only, never user-written text. |
| changes | array | Required | Resolved field changes, [{field, from, to}]. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| count | integer | Required | Total number of rows. |
| next | uri | Required | URL of the next page, or null. |
| previous | uri | Required | URL of the previous page, or null. |
| results | array<ActivityEvent> | Required | The rows on this page. See ActivityEvent. |
Errors
| Status | When |
|---|---|
| 400 | An undeclared parameter or a bad value (`invalid_filter_value`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/inbox/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks inbox --json{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "00000000-0000-4000-8000-00000000000f",
"type": "task.moved",
"actor": {},
"created_at": "example",
"task": {},
"payload": {},
"changes": []
}
]
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Mark all inbox items read
Marks every inbox item read by moving your read cursor to now. The response is the new last_seen_at.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| last_seen_at | date-time | Required | Everything at or before this time counts as read. |
Errors
| Status | When |
|---|---|
| 400 | The agent name is invalid (`invalid_agent_attribution`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS -X POST "https://api.dailybot.com/v1/plan/inbox/read-all/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks inbox-read-all{
"last_seen_at": "2026-09-25T10:14:02Z"
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Catch up to one inbox row
Marks this row and everything older read, and answers with the new unread_count.
The inbox has no per-item read state, by design: read/unread is derived from a single cursor rather than a flag per row. Marking row five read while one to four stay unread has no representation in that model, and giving it one means a second source of truth that must agree with the cursor forever. What a watermark CAN express is "I have caught up to here", and in a newest-first feed that is what clicking a row usually means.
A row this actor cannot see is 404, so an event uuid from another organization cannot move somebody else's cursor.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| item_uuid | string | Required | The inbox row's uuid. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| last_seen_at | date-time | Required | Everything at or before this time counts as read. |
| unread_count | integer | Required | Unread items. |
Errors
| Status | When |
|---|---|
| 400 | The agent name is invalid (`invalid_agent_attribution`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS -X POST "https://api.dailybot.com/v1/plan/inbox/00000000-0000-4000-8000-00000000000f/read/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks inbox-read 00000000-0000-4000-8000-00000000000f{
"last_seen_at": "2026-09-25T10:14:02Z",
"unread_count": 3
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Unread inbox count for the caller
How many inbox items you have not read yet, for a badge. It takes the same filters as the inbox list, so each tab's badge counts exactly that tab's rows: mentioned=true for Mentions, type=task.owner_changed for Assigned. With no parameters it counts the whole inbox. Cheaper than listing the inbox.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| type | string | Optional | Only events of this type, such as task.owner_changed (the Assigned tab). Combines with mentioned (AND). |
| mentioned | boolean | Optional | true keeps only the events where someone mentioned you. Must be true or false. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| unread_count | integer | Required | Unread items. |
Errors
| Status | When |
|---|---|
| 400 | An undeclared parameter or a bad value (`invalid_filter_value`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/inbox/unread-count/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks inbox-unread{
"unread_count": 3
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Org activity feed for Plan Home
Paginated events you may open, enriched with task cards and resolved changes[{field, from, to}] for display. Tasks you cannot see are omitted even when their board is visible.
Only the parameters listed here are accepted: any other query parameter is 400 invalid_filter_value.
Query parameters
Pagination
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | 1-based page number. |
| page_size | integer | Optional | Rows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100. |
| limit | integer | Optional | Alias for page_size, translated server-side. |
| offset | integer | Optional | Alias translated to page server-side. |
Filters
| Name | Type | Required | Description |
|---|---|---|---|
| type | string | Optional | Filter to one event type. event_type is an alias. |
| actor | uuid | Optional | Only events by this person (user uuid). |
| project | uuid | Optional | Only events in this project (uuid). |
| board | uuid | Optional | Only events on this board (uuid). |
| task | uuid | Optional | Only events about this task (uuid). |
| since | string | Optional | ISO datetime: events recorded at or after this time (observed_at). |
| until | string | Optional | ISO datetime: events recorded at or before this time (observed_at). |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| count | integer | Required | Total number of rows. |
| next | uri | Required | URL of the next page, or null. |
| previous | uri | Required | URL of the previous page, or null. |
| results | array<ActivityEvent> | Required | The rows on this page. See ActivityEvent. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
curl -sS "https://api.dailybot.com/v1/plan/activity/" \
-H "X-API-KEY: $DAILYBOT_API_KEY"dailybot plan tasks activity --last-week --json
dailybot plan tasks activity --board 00000000-0000-4000-8000-000000000002 --since 2026-09-20T00:00:00Z --jsonTry it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Works with a login session, a CLI user token, a personal API key, or an agent or organization key. A personal key sees what its person sees; an agent or organization key acts as a system actor and sees organization-visible boards only.
Read the caller's activity read cursor
Your activity read cursor: the moment up to which you have read the activity feed. It is null until you set it.
ActivityCursor object
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | ActivityCursor | Required | A ActivityCursor object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
curl -sS "https://api.dailybot.com/v1/plan/me/activity-cursor/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks cursor{
"last_seen_at": null
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Mark activity as read up to a timestamp
Stores your activity read cursor at last_seen_at, so another client can pick up where you left off.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| last_seen_at | date-time | Required | Everything at or before this time counts as read. |
| agent_name | string | Optional | The name of the agent that executed this write on the person's behalf (max 128 characters, blank means no agent). Takes priority over the X-Dailybot-Agent-Name header. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | ActivityCursor | Required | A ActivityCursor object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. `invalid_agent_attribution` means the agent name is invalid. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
curl -sS -X PUT "https://api.dailybot.com/v1/plan/me/activity-cursor/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"last_seen_at": "2026-09-25T10:14:02Z"
}'dailybot plan tasks cursor --nowTry it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
List organization labels
The organization's label taxonomy, shared with forms and check-ins. Prefer this endpoint for settings screens; the board-scoped list is the same taxonomy behind a board access check.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | 1-based page number. |
| page_size | integer | Optional | Rows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100. |
| search | string | Optional | Case-insensitive substring match on the label name only. Empty means no filter; a value that matches nothing returns an empty list. |
| include_archived | boolean | Optional | Include archived rows alongside live ones. Distinct from is_archived, which selects one set or the other: include_archived=true is the union. Lists return live rows unless you opt in. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| next | string|null | Required | URL of the next page, or null. |
| previous | string|null | Required | URL of the previous page, or null. |
| results | array<Label> | Required | The rows on this page. |
Errors
| Status | When |
|---|---|
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/labels/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "00000000-0000-4000-8000-00000000000b",
"name": "backend",
"color": "#2563eb"
}
]
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Create an organization label
Creates a label in the organization taxonomy. Same shape as POST /boards/{board_id}/labels/.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | Display name. |
| color | string | Optional | Display color (hex). |
| description | string | Optional | Free-form description. |
| agent_name | string | Optional | The name of the agent that executed this write on the person's behalf (max 128 characters, blank means no agent). Takes priority over the X-Dailybot-Agent-Name header. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Label | Required | A Label object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. `invalid_agent_attribution` means the agent name is invalid. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS -X POST "https://api.dailybot.com/v1/plan/labels/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "backend",
"color": "#2563eb"
}'{
"uuid": "00000000-0000-4000-8000-00000000000b",
"name": "backend",
"color": "#2563eb"
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Update an organization label
Partial update of name, color, description, or is_archived. Archiving hides the label from the default list without hard-deleting it. Restore is the same field the other way: {"is_archived": false}. Read a retired label back with GET /v1/plan/labels/?include_archived=true.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| label_id | string | Required | The label's uuid. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Optional | Display name. |
| color | string | Optional | Display color (hex). |
| description | string | Optional | Free-form description. |
| is_archived | boolean | Optional | Whether the row is archived. Archive is the delete: archived rows stay readable and restorable. |
| agent_name | string | Optional | The name of the agent that executed this write on the person's behalf (max 128 characters, blank means no agent). Takes priority over the X-Dailybot-Agent-Name header. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Label | Required | A Label object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. `invalid_agent_attribution` means the agent name is invalid. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/labels/00000000-0000-4000-8000-00000000000b/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"is_archived": true
}'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Delete an organization label
Hard-deletes when the label has no task assignments. Otherwise 409 label_in_use. Prefer PATCH with is_archived: true to retire a label that is still on cards.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| label_id | string | Required | The label's uuid. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Errors
| Status | When |
|---|---|
| 400 | The agent name is invalid (`invalid_agent_attribution`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
| 404 | Not found, or not visible to you. Both cases return the same body. |
| 409 | The label is still on tasks (`label_in_use`). Archive it with `PATCH` instead. |
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/labels/00000000-0000-4000-8000-00000000000b/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Whether Plan is available here, and the plan ceilings
Whether Plan is available to your organization, and its plan ceilings. It is the one Plan endpoint that never answers 402, so call it before deciding whether to show the product.
enabled is the same check every other endpoint applies. reason is null when enabled; otherwise rollout (your organization is not enabled for the Beta yet) or usage (an admin turned Plan off). boards and projects report {used, limit}, even when disabled; limit is null when the plan has no cap. The free plan includes up to 3 boards and 1 project. used counts live rows only, so archiving frees a slot, and used > limit can happen on grandfathered plans.
A guest gets 403 guest_not_allowed here, not 200 with enabled: false, and never sees plan ceilings.
Entitlements object
| Name | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | Required | Whether Plan is enabled for your organization. |
| reason | enum | null | Required | Why Plan is not enabled: rollout or usage; null when enabled. One of rollout, usage. |
| boards | object | Required | Shape: {used: integer, limit: integer|null} (both required). |
| projects | object | Required | Linked projects. Shape: {used: integer, limit: integer|null} (both required). |
| labels | object | Required | Organization labels on the task. Shape: {enabled: boolean}. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Entitlements | Required | A Entitlements object. |
Errors
| Status | When |
|---|---|
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
curl -sS "https://api.dailybot.com/v1/plan/entitlements/" \
-H "X-API-KEY: $DAILYBOT_API_KEY"dailybot plan tasks entitlements{
"enabled": false,
"reason": null,
"boards": {},
"projects": {},
"labels": {}
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Works with a login session, a CLI user token, a personal API key, or an agent or organization key. A personal key sees what its person sees; an agent or organization key acts as a system actor and sees organization-visible boards only.
The scheduled work over a window, with its dependency edges and goal bands
The same filtered set as the task list, asked a scheduling question. rows are the cards that OVERLAP the window; unscheduled counts the matching cards with no dates at all; dependencies carries only edges whose both ends are in rows, because an arrow to a row the reader cannot see is a line to nowhere on the screen and a disclosure off it.
Window selection (first match wins):
- from + to (ISO dates) — explicit range; from may be in the past (e.g. today−7 … today+21). Aliases: window_from / window_to.
- window_days — forward helper: today through today+N (inclusive span).
- omitted — default forward window of 14 days from today (with a board filter).
Query parameters
Filters
| Name | Type | Required | Description |
|---|---|---|---|
| from | string | Optional | First day of an explicit window (ISO date). May be in the past. Pair with to. Alias: window_from. |
| to | string | Optional | Last day of an explicit window (ISO date). Must be ≥ from. Alias: window_to. |
| window_from | string | Optional | Alias for from. |
| window_to | string | Optional | Alias for to. |
| window_days | integer | Optional | Forward-from-today helper. Ignored when both from and to (or their aliases) are present. Default when no explicit window is 14. |
| board | array | Optional | Board uuids or board keys (ENG). Repeatable; values are OR-ed. Keys resolve within your organization only; a key that names no board of yours contributes nothing and never returns a 404. Retired keys keep resolving. |
| project | array | Optional | Project uuids. Repeatable; values are OR-ed. |
| goal | string | Optional | Repeatable. Matches a task's own goal, or the goal it inherits from its project when it has none, the same rule every progress roll-up uses. |
| team | string | Optional | Repeatable. The board's team. It narrows what you see and never widens it. |
| owner | array | Optional | A user uuid, me, or unowned. Repeatable; values are OR-ed, tokens included: owner=me&owner=unowned returns your tasks and the unowned ones. me with an agent or organization key is 400 actor_required. |
| category | array | Optional | The five fixed state categories. There is no blocked category — blocked-ness is a relation; use blocked=true. |
| label | array | Optional | Label uuids — v4 only, at most 50, matching the shared label filter's existing cap. A non-v4 value is 400 invalid_label_filter. |
| include_unscheduled | string | Optional | When 1 or true, unscheduled is {count, results[]} (capped) instead of a bare integer count. |
Timeline object
| Name | Type | Required | Description |
|---|---|---|---|
| window | object | Required | The window covered. Shape: {from: string, to: string}. |
| bands | array | Optional | Goals live across the window. Items: {uuid, name, status, period_start, period_end}. |
| rows | array | Required | Tasks that overlap the window. Items: {uuid, key, title, state (state name), category, owner (UserRef|null), goal (uuid|null), start_date, due_date, completed_at, is_blocked, is_overdue}. |
| dependencies | array | Optional | Dependency edges whose both ends are in rows. Items: {source (task uuid), target (task uuid), relation_type}. |
| unscheduled | integer | {count: integer, results: array} | Required | Matching tasks with no dates at all. |
| truncated | boolean | Optional | true when more changes are waiting: poll again immediately. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Timeline | Required | A Timeline object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
| 429 | Rate limit reached. Wait the number of seconds in `Retry-After`. |
curl -sS "https://api.dailybot.com/v1/plan/timeline/?board=ENG&from=2026-09-18&to=2026-10-16" \
-H "X-API-KEY: $DAILYBOT_API_KEY"dailybot plan tasks timeline --today{
"window": {},
"bands": [],
"rows": [],
"dependencies": [],
"unscheduled": 1,
"truncated": false
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Works with a login session, a CLI user token, a personal API key, or an agent or organization key. A personal key sees what its person sees; an agent or organization key acts as a system actor and sees organization-visible boards only.
Search tasks and containers visible to the caller
Search tasks (title, key, description) and, with types, projects, boards and goals you can see.
Matching is case-insensitive substring search, not full-text ranking. score is a coarse ordering aid between 0.6 and 1.0 (exact key 1.0, title or name hit 0.9 / 0.85, description hit 0.6), not calibrated relevance, and snippet is a window around the first match. The response repeats this in approximation. Hidden tasks and private boards never appear.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| q | string | Required | The query string. Fewer than 2 characters is refused with search_query_too_short; more than 256 with search_query_too_long. |
| types | array | Optional | Entity kinds to include: task, project, board, goal (default: all). Repeatable, or comma-separated: ?types=task,board and ?types=task&types=board are equivalent. Unknown values are 400 invalid_filter_value. |
| board | array | Optional | Board uuids or board keys (ENG). Repeatable; values are OR-ed. Keys resolve within your organization only; a key that names no board of yours contributes nothing and never returns a 404. Retired keys keep resolving. |
| project | array | Optional | Project uuids. Repeatable; values are OR-ed. |
| limit | integer | Optional | Alias for page_size, translated server-side. |
SearchResponse object
| Name | Type | Required | Description |
|---|---|---|---|
| q | string | Required | The query you sent. |
| limit | integer | Required | Page size applied. From 1 to 100. |
| approximation | string | Required | How matching works (substring search, not full-text ranking). |
| results | array | Required | The rows on this page. Items: {type: task|project|board|goal, uuid, title (tasks) or name (containers), key? (tasks), score?, snippet?}. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | SearchResponse | Required | A SearchResponse object. |
Errors
| Status | When |
|---|---|
| 400 | `q` is shorter than 2 characters (`search_query_too_short`) or longer than 256 (`search_query_too_long`), or a `types` value is unknown. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 403 | Authenticated but not allowed: missing scope (`insufficient_scope`, which is also what an agent or organization key gets on an operation that needs a person, and what a personal key gets when its explicit Plan scopes do not cover the endpoint) or a guest account (`guest_not_allowed`). |
| 429 | Rate limit reached. Wait the number of seconds in `Retry-After`. |
curl -sS "https://api.dailybot.com/v1/plan/search/?q=delta&types=task,board" \
-H "X-API-KEY: $DAILYBOT_API_KEY"dailybot plan tasks search -q "delta" --json{
"q": "delta",
"limit": 1,
"approximation": "substring",
"results": []
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Works with a login session, a CLI user token, a personal API key, or an agent or organization key. A personal key sees what its person sees; an agent or organization key acts as a system actor and sees organization-visible boards only.
The home screen in one request (HomePulse), or a board-health aggregate (TaskPulse)
Two modes, chosen by the presence of group_by.
HomePulse (no group_by): the Plan home in one request — generated_at, integer counts, your my_preview, board, goal and timeline teasers, agent_summary, and the optional include bands. The population is stated as scope: "viewer_visible": every live, non-terminal task you can see — not the whole organization. Each tile names the query that reproduces it: open → ?state=open, overdue → ?due_before=<today>&state=open, blocked → ?blocked=true&state=open.
TaskPulse (with group_by, e.g. group_by=state): a board-health aggregate with totals, throughput and cycle time. Counts are integers only and there is no per-person breakdown. Answers If-None-Match with 304.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| board | array | Optional | Board uuids or board keys (ENG). Repeatable; values are OR-ed. Keys resolve within your organization only; a key that names no board of yours contributes nothing and never returns a 404. Retired keys keep resolving. |
| project | array | Optional | Project uuids. Repeatable; values are OR-ed. |
| window_days | integer | Optional | The trailing window for throughput and cycle time. |
| group_by | string | Optional | Presence selects TaskPulse mode (a board-health aggregate). Omit it entirely for HomePulse; there is no default. The enum is closed and contains no person dimension: per-person output is refused by design. |
| include | string | Optional | HomePulse only (no group_by). Comma-separated opt-in bands so a home screen renders from one request: projects → projects_preview (visible live projects, progress, newest update), attention → attention (your open work that is overdue or blocked), activity → recent_activity, goal_progress → progress and projects on each goals_preview row. A band you do not ask for is absent and costs nothing. An unknown token is 400 invalid_filter_value. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| If-None-Match | string | Optional | The ETag from your previous read. A match answers 304. |
HomePulse object
| Name | Type | Required | Description |
|---|---|---|---|
| generated_at | date-time | Required | When the response was computed. |
| scope | enum | Required | The population counted: viewer_visible (everything you can see). One of viewer_visible. |
| open | integer | Optional | Tasks in a backlog, todo or in_progress state. |
| overdue | integer | Optional | Open tasks past their due date. |
| blocked | integer | Optional | Tasks with a live blocker. |
| unread_count | integer | Required | Unread items. |
| counts | HomePulseCounts {open_tasks, open_tasks_on_goal_linked_projects, overdue_tasks, blocked_tasks, active_boards, active_projects, active_goals: integer} | Required | Integer counts across what you can see. All fields are always present. |
| my_preview | object | Required | Your overdue and due-today work. Shape: {overdue: integer, due_today: integer, top_tasks: array of {uuid, title, due_date, priority, board (uuid)}} (all required). |
| recent_boards | array | Required | Items: {uuid, name, key, project (uuid|null), updated_at, viewer{is_member, can_see_content, can_manage}}. |
| featured_boards | array | Required | Items: {uuid, name, key, project (uuid|null), updated_at, viewer{is_member, can_see_content, can_manage}}. |
| goals_preview | array | Required | Items: {uuid, name, status, period_start, period_end}; with include=goal_progress also progress (GoalProgress|null) and projects [{uuid, name, …}]. |
| timeline_teaser | object | Required | Work due soon. Shape: {window_from: string, window_to: string, due_soon_count: integer, rows: array} (all required). |
| agent_summary | object | Required | Boards where agents act, and approvals waiting. Shape: {boards_advisory, boards_autonomous, pending_approvals: integer} (all required). |
| projects_preview | array | Optional | Present only with include=projects. Items: {uuid, name, health, progress (ProjectProgress|null), latest_update (ProjectUpdate|null)}. |
| attention | array | Optional | Present only with include=attention. Items: {uuid, key, title, due_date, priority, board, state{uuid, name, category}, overdue, blocked}. |
| recent_activity | array<ActivityEvent> | Optional | Present only with include=activity. See ActivityEvent. |
TaskPulse object
| Name | Type | Required | Description |
|---|---|---|---|
| board | Board | null | Optional | The board. See Board. |
| window_days | integer | Required | — |
| generated_at | date-time | Required | When the response was computed. |
| group_by | enum | Required | The grouping dimension. One of state, category, label, priority, board, age. |
| groups | array | Required | One entry per column (or group), in order. Always present: key, count. Items: {key: string, name: string|null, count: integer, oldest_age_days: integer|null}. |
| totals | object | Required | Shape: {total, blocked, unassigned, overdue , created_in_window, completed_in_window: integer}. |
| throughput | array | Optional | All fields are always present. Items: {week_start: string, created: integer, completed: integer}. |
| cycle_time_days_p50 | number | null | Optional | — |
| cycle_time_days_p90 | number | null | Optional | — |
Board object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | uuid | Required | Stable public identifier. |
| key | string | Required | The board's key: the prefix of its tasks' keys. Renaming it keeps the old key reserved and resolving. |
| name | string | Required | Display name. Max 120 characters. |
| project | Project | Optional | The project. See Project. |
| team | uuid | null | Optional | The team. |
| visibility | enum | Required | org (everyone in the organization) or members (explicit members only). One of org, members. |
| effective_visibility | string | Optional | Whether the board is effectively visible to the whole organization (org) or only to members (members). A board inside a members project is members here, while visibility stays the board's own stored setting. |
| estimate_scale | enum | Optional | How estimates are expressed on this board. One of none, fibonacci, linear. |
| default_view | SavedView | null | Optional | The board's default saved view, or null. See SavedView. |
| archive_after_days | integer | null | Optional | Archive done tasks automatically after this many days, or null to keep them. |
| task_count | integer | Optional | Number of live tasks. |
| wip_limits | object | Optional | Work-in-progress limits per column. |
| is_archived | boolean | Optional | Whether the row is archived. Archive is the delete: archived rows stay readable and restorable. |
| created_at | date-time | Optional | When the row was created. |
| updated_at | date-time | Optional | When the row last changed. |
| viewer | object | Optional | What you can do with this row. Shape: {is_member, can_see_content, can_manage: boolean} (all required). |
| states | array<WorkflowState> | Optional | The board's workflow states, in column order. See WorkflowState. |
Project object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | uuid | Required | Stable public identifier. |
| name | string | Required | Display name. Max 120 characters. |
| slug | string | Optional | URL-friendly name. Max 48 characters. |
| description | string | null | Optional | Free-form description. |
| lead | UserRef | null | Optional | The project's lead. See UserRef. |
| goals | array | Optional | Goals this project points at. A project can serve several goals. Always present: uuid. Items: {uuid, name}. |
| goal | object | Optional | The goal, when there is exactly one. Shape: {uuid, name}|null. |
| board_count | integer | Optional | Number of live boards in the project. |
| health | enum | Optional | Declared health. One of not_set, on_track, at_risk, off_track. |
| start_date | date | null | Optional | Planned start date. |
| target_date | date | null | Optional | Planned end date. |
| progress | ProjectProgress | null | Optional | Progress roll-up over the tasks you can see. See ProjectProgress. |
| is_archived | boolean | Required | Whether the row is archived. Archive is the delete: archived rows stay readable and restorable. |
| archived_at | date-time | null | Optional | When the row was archived. |
| created_at | date-time | Optional | When the row was created. |
| updated_at | date-time | Optional | When the row last changed. |
| viewer | object | Optional | What you can do with this row. Shape: {can_see_content: boolean, can_manage: boolean} (both required). |
SavedView object
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | Display name. Max 64 characters. |
| view_mode | enum | Optional | How the filtered set is drawn. Reads always return board for the kanban layout. One of list, board, timeline, calendar. |
| group_by | enum | Optional | The grouping dimension. One of state, owner, priority, category. |
| sort | string | Optional | A sort key, - prefixed for descending. |
| filters | object | Required | The view's filters, in the shared task filter grammar. |
| schema_version | integer | Optional | Version of the view's stored format. |
| visibility | enum | Optional | personal (default) is yours alone. shared and board_default (the default view for that board or project) are readable by everyone who can see the board or project. Setting them needs a board manager on board views, and project oversight (an organization admin or a manager of all teams) on project views; otherwise 403 view_visibility_forbidden. One of personal, shared, board_default. |
| collapsed | object | array | string | number | boolean | Optional | Client UI state stored verbatim (which groups are collapsed). Only size and depth are validated. |
| columns | object | array | string | number | boolean | Optional | Client UI state stored verbatim (which columns are shown). Only size and depth are validated. |
| uuid | uuid | Optional | Stable public identifier. |
| scope | enum | Optional | Which container the view belongs to: board or project. Read-only. One of board, project. |
| board | uuid | null | Optional | The board's uuid when scope is board; null for a project view. Read-only. |
| owner | object | Optional | Who owns the view. Shape: {uuid, name}. |
| created_at | date-time | Optional | When the row was created. |
| updated_at | date-time | Optional | When the row last changed. |
ProjectProgress object
| Name | Type | Required | Description |
|---|---|---|---|
| total | integer | Required | All tasks counted. |
| completed | integer | Required | Tasks in a done or canceled state. |
| open | integer | Optional | Tasks in a backlog, todo or in_progress state. |
| blocked | integer | Optional | Tasks with a live blocker. |
| overdue | integer | Optional | Open tasks past their due date. |
| percent_complete | integer | Required | completed as a percentage of total. |
Errors
| Status | When |
|---|---|
| 304 | Not modified: the `If-None-Match` ETag you sent still matches. |
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS "https://api.dailybot.com/v1/plan/pulse/?include=projects,attention,activity,goal_progress" \
-H "X-API-KEY: $DAILYBOT_API_KEY"dailybot plan tasks status --jsonTry it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Works with a login session, a CLI user token, a personal API key, or an agent or organization key. A personal key sees what its person sees; an agent or organization key acts as a system actor and sees organization-visible boards only.
Your pinned boards and saved views
Every pin you own, in rank order (1 is the top). A pin whose target you can no longer see (an archived or hidden board, or a saved view that is gone or no longer shared) is omitted rather than raised. The list uses the standard list envelope but is never paged: next and previous are always null, and it holds up to 50 pins. Needs a person: agent and organization keys are refused; a personal API key works.
Favorite object
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | uuid | Required | Stable public identifier. |
| target_type | enum | Required | What is pinned: board or view. One of board, view. |
| target_uuid | uuid | Required | The board's or the saved view's uuid, per target_type. |
| rank | integer | Required | 1-based position in your list. Minimum 1. |
| created_at | date-time | Required | When the row was created. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| count | integer | Required | Total number of rows. |
| next | uri | Required | URL of the next page, or null. |
| previous | uri | Required | URL of the previous page, or null. |
| results | array<Favorite> | Required | The rows on this page. See Favorite. |
Errors
| Status | When |
|---|---|
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
curl -sS "https://api.dailybot.com/v1/plan/me/favorites/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan tasks favorites --json{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "00000000-0000-4000-8000-000000000012",
"target_type": "board",
"target_uuid": "00000000-0000-4000-8000-000000000012",
"rank": "aU",
"created_at": "2026-09-25T10:14:02Z"
}
]
}Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:read`.
- Rate limit: 120 reads per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Pin a board or a saved view
New pins land at the bottom of your list. Pinning something already pinned returns the existing pin rather than a duplicate. A target you cannot see is 404, never 403. You can pin up to 50 boards and views; one more is 400 favorite_limit_reached.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string | Optional | A key you generate for this intent. A replay with the same key and body returns the first response without a second side effect and carries Idempotency-Replayed: true. Keys are kept for 24 hours. The same key with a different body is 409 idempotency_key_payload_mismatch; a repeat while the first call is still running gets 409 idempotency_in_progress for up to 120 seconds. |
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| target_type | enum | Required | What is pinned: board or view. One of board, view. |
| target_uuid | uuid | Required | The board's or the saved view's uuid, per target_type. |
| agent_name | string | Optional | The name of the agent that executed this write on the person's behalf (max 128 characters, blank means no agent). Takes priority over the X-Dailybot-Agent-Name header. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Favorite | Required | A Favorite object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. `invalid_agent_attribution` means the agent name is invalid. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS -X POST "https://api.dailybot.com/v1/plan/me/favorites/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target_type": "board",
"target_uuid": "00000000-0000-4000-8000-000000000012"
}'dailybot plan board star 00000000-0000-4000-8000-000000000002
dailybot plan tasks view star 00000000-0000-4000-8000-000000000010Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Move one pin within your list
Send one of after (place it just below that pin), before (just above it) or rank (1-based position, clamped to the list). When more than one is sent, after wins, then before. Ranks are renumbered to 1..n. A neighbour that is not one of your pins is 404.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| favorite_id | uuid | Required | The pin's uuid. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| rank | integer | Optional | 1-based target position, clamped to the list. Minimum 1. |
| before | uuid | Optional | Place the pin just above this pin. |
| after | uuid | Optional | Place the pin just below this pin. |
| agent_name | string | Optional | The name of the agent that executed this write on the person's behalf (max 128 characters, blank means no agent). Takes priority over the X-Dailybot-Agent-Name header. See Agent attribution. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| (body) | Favorite | Required | A Favorite object. |
Errors
| Status | When |
|---|---|
| 400 | Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which. `invalid_agent_attribution` means the agent name is invalid. |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/me/favorites/{favorite_id}/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
Unpin
Removes the pin, never its target. The remaining pins are renumbered to 1..n.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| favorite_id | uuid | Required | The pin's uuid. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| X-Dailybot-Agent-Name | string | Optional | The name of the agent that executed this write on the person's behalf. Use it on multipart and body-less writes (DELETE, archive, restore); on JSON writes send the body field agent_name instead, which wins if both are present. Percent-encode the value as UTF-8. Control characters are stripped; a blank value means no agent. More than 128 characters, or a value that cannot be decoded, is 400 invalid_agent_attribution (never truncated). An agent-type key, which is not bound to a person, gets 400 invalid_agent_attribution if it sends it. The stamp never changes a permission answer. See Agent attribution. |
Errors
| Status | When |
|---|---|
| 400 | The agent name is invalid (`invalid_agent_attribution`). |
| 401 | Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`). |
| 402 | Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected]. |
| 404 | Not found, or not visible to you. Both cases return the same body. |
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/me/favorites/{favorite_id}/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"dailybot plan board unstar 00000000-0000-4000-8000-000000000002
dailybot plan tasks view unstar 00000000-0000-4000-8000-000000000010Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Scope: `tasks:write`.
- Rate limit: 60 writes per minute per actor.
- Needs a person: call it with a login session, a CLI user token or a personal API key. An agent or organization key gets `403 insufficient_scope`.
This page is the reference for Plan · Home & search. Every endpoint lives under https://api.dailybot.com/v1/plan/ and answers JSON.
Authenticate with a login session or a CLI user token (Authorization: Bearer …), or with an API key (X-API-KEY). A personal API key acts as its person and can do everything that person can do in Dailybot; an agent or organization key never acts as a person and is refused on the endpoints that need one. On an endpoint, the API key badge means an agent or organization key is accepted too. See Authentication for Plan, Authentication and Errors for the rules shared by every Dailybot API.
New to Plan? Read the overview for the model: projects, boards, workflow states, keys, ordering, versions and archive.