Skip to content
view raw .md

Plan · Projects

Projects group boards and carry health, status notes, milestones, members and saved views. 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].

GET/v1/plan/projects/BetaAPI keyCLI AuthPage-number pagination

List projects

The projects you can see, as a page. Search with search, filter by dates with start_date / end_date, and bring archived projects with include_archived. include adds optional blocks to each row.

Query parameters

Sorting & expansion

NameTypeRequiredDescription
includestringOptionalComma-separated roll-ups to embed. progress is the only token. Absent by default because it is an aggregate; when asked for, it is computed over the returned page. An unknown token is 400 invalid_filter_value; an empty value is a no-op.

Pagination

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.
limitintegerOptionalAlias for page_size, translated server-side.
offsetintegerOptionalAlias translated to page server-side.

Filters

NameTypeRequiredDescription
searchstringOptionalMatches title and key. Longer than 256 characters is 400 search_query_too_long, not truncated. q is an alias.

Archived rows

NameTypeRequiredDescription
is_archivedbooleanOptionaltrue returns only archived rows; false (the default) only live ones. Archive is the delete, so archived rows stay readable.
include_archivedbooleanOptionalInclude 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.

Dates

NameTypeRequiredDescription
start_datestringOptionalCreated-at window start. What the CLI's --since produces.
end_datestringOptionalCreated-at window end. What the CLI's --until produces.

Project object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
namestringRequiredDisplay name. Max 120 characters.
slugstringOptionalURL-friendly name. Max 48 characters.
descriptionstring | nullOptionalFree-form description.
leadUserRef | nullOptionalThe project's lead. See UserRef.
goalsarrayOptionalGoals this project points at. A project can serve several goals. Always present: uuid. Items: {uuid, name}.
goalobjectOptionalThe goal, when there is exactly one. Shape: {uuid, name}|null.
board_countintegerOptionalNumber of live boards in the project.
healthenumOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
start_datedate | nullOptionalPlanned start date.
target_datedate | nullOptionalPlanned end date.
progressProjectProgress | nullOptionalProgress roll-up over the tasks you can see. See ProjectProgress.
is_archivedbooleanRequiredWhether the row is archived. Archive is the delete: archived rows stay readable and restorable.
archived_atdate-time | nullOptionalWhen the row was archived.
created_atdate-timeOptionalWhen the row was created.
updated_atdate-timeOptionalWhen the row last changed.
viewerobjectOptionalWhat you can do with this row. Shape: {can_see_content: boolean, can_manage: boolean} (both required).

UserRef object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
namestringOptionalDisplay name.
avatar_urlstring | nullOptional—
has_photobooleanOptional—

ProjectProgress object

NameTypeRequiredDescription
totalintegerRequiredAll tasks counted.
completedintegerRequiredTasks in a done or canceled state.
openintegerOptionalTasks in a backlog, todo or in_progress state.
blockedintegerOptionalTasks with a live blocker.
overdueintegerOptionalOpen tasks past their due date.
percent_completeintegerRequiredcompleted as a percentage of total.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<Project>RequiredThe rows on this page. See Project.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS "https://api.dailybot.com/v1/plan/projects/?include=progress" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
POST/v1/plan/projects/BetaCLI Auth

Create a project

Creates a project, the container that groups boards. Every non-guest member can call it (with a login session or a personal API key); an agent or organization key cannot. Send an Idempotency-Key to retry safely; the plan's project limit answers 402 task_projects_limit_reached.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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

NameTypeRequiredDescription
visibilityenumOptionalorg (everyone in the organization — shared workspace) or members (explicit grants only; invite with POST …/members/). Creating as members grants you. One of org, members. Default org.
namestringRequiredDisplay name. Max 120 characters.
descriptionstring | nullOptionalFree-form description. Max 2000 characters.
leaduuid | nullOptionalThe project's lead.
healthenumOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
start_datedate | nullOptionalPlanned start date.
target_datedate | nullOptionalPlanned end date.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectRequiredA Project object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`), or the plan's project ceiling is reached (`task_projects_limit_reached`).
403Authenticated 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`).
409Conflict. The response `code` says which (for example `version_conflict`).
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q4 Roadmap",
    "visibility": "org",
    "health": "on_track",
    "target_date": "2026-12-18"
  }'

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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/projects/{project_id}/BetaAPI keyCLI Auth

Retrieve a project

One project by uuid. A project you cannot see answers 404, the same as one that does not exist.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Response

NameTypeRequiredDescription
(body)ProjectRequiredA Project object.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404Not found, or not visible to you. Both cases return the same body.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
PATCH/v1/plan/projects/{project_id}/BetaCLI Auth

Update a project

Changes a project's fields. Send only the fields you change. Every non-guest member can call it (with a login session or a personal API key); an agent or organization key cannot. Setting visibility to members privatizes the project and auto-grants the actor who privatizes.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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

NameTypeRequiredDescription
visibilityenumOptionalorg (everyone in the organization) or members (explicit members only). Changing org → members auto-grants the actor who privatizes. One of org, members.
namestringOptionalDisplay name. Max 120 characters.
descriptionstring | nullOptionalFree-form description. Max 2000 characters.
leaduuid | nullOptionalThe project's lead.
healthenumOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
start_datedate | nullOptionalPlanned start date.
target_datedate | nullOptionalPlanned end date.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectRequiredA Project object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "health": "at_risk"
  }'

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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/projects/updates/BetaAPI keyCLI AuthPage-number pagination

The newest updates across every project the caller can see

The batched form of the per-project updates list, for a home screen that would otherwise call it once per project.

Returns the newest per_project updates for each visible project as one flat, paginated list; each row carries its project, so group by that field. Ordered by project name, then newest first. It is a teaser, not a history: for a full thread or an archived project, use GET /v1/plan/projects/{project_id}/updates/.

projects narrows to named projects. A project you cannot see is silently omitted rather than refused, and archived projects are excluded even when named. body_html is rendered and sanitized server-side.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.
projectsarrayOptionalProject uuids to narrow to. Repeatable; values are OR-ed. A project the caller cannot see, or one that is archived, contributes nothing rather than raising. More than the published maximum is 400 too_many_filter_values.
per_projectintegerOptionalHow many updates each project contributes. Clamped to the published maximum rather than refused - this is a teaser size, not an identifier, and a home screen asking for too many should get a full page rather than an error.

ProjectUpdate object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
projectuuid | nullRequiredThe project.
bodystringRequiredMarkdown as typed. Mention someone with <@DB@{uuid}>, using a uuid from the mentionables list.
body_htmlstringRequiredbody rendered and sanitized by the server. Client HTML is never accepted.
mentionsarray<ActorRef>OptionalThe people mentioned. Read them from here, never by parsing body. See ActorRef.
healthenum | nullOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
created_byActorRef | nullOptionalWho created the row. See ActorRef.
created_atdate-timeRequiredWhen the row was created.
updated_atdate-timeOptionalWhen the row last changed.
executed_by_agentobject | nullOptionalThe agent that executed this person's post, beside created_by, or null for a plain human post: {uuid, name, username, avatar}.
provenanceenumOptionalHow the text reached us: typed, agent_authored or retrieved. A note posted through an API key, or stamped with an agent, is agent_authored.
edited_atdate-time | nullOptionalNull until the first edit.
attachmentsarray<TaskAttachment>OptionalREADY attachments, ordered by position, inline. Upload them with POST …/updates/{update_id}/attachments/.

ActorRef object

NameTypeRequiredDescription
kindstringRequired—
uuidstringRequiredStable public identifier.
namestringOptionalDisplay name.
usernamestring | nullOptional—
avatar_urlstring | nullOptional—
has_photobooleanOptional—

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<ProjectUpdate>RequiredThe rows on this page. See ProjectUpdate.

Errors

StatusWhen
400Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan 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/projects/updates/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
GET/v1/plan/projects/{project_id}/updates/BetaAPI keyCLI AuthPage-number pagination

Status notes on a project, newest first

The narrative half of a roadmap: why the health is what it is, with a name and a date on it. body is the markdown as typed; body_html is rendered server-side through the same sanitizer comments use, so no client-supplied HTML is ever trusted.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<ProjectUpdate>RequiredThe rows on this page. See ProjectUpdate.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
POST/v1/plan/projects/{project_id}/updates/BetaAPI keyCLI Auth

Post a status note

Send body as markdown. A body_html is NOT accepted — the server renders and sanitizes it, so the allow-list is ours and there is one of them. health records what the author claimed that day and does not change Project.health.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
bodystringRequiredMarkdown. Mention someone with <@DB@{uuid}>, using a uuid from the mentionables list.
healthenum | nullOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectUpdateRequiredA ProjectUpdate object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Staging is green; rolling out Friday. <@DB@00000000-0000-4000-8000-00000000000c> owns the release.",
    "health": "on_track"
  }'

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.
  • 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.
GET/v1/plan/projects/{project_id}/milestones/BetaAPI keyCLI AuthPage-number pagination

Dated commitments inside a project, in date order

Each row carries task_count, annotated in the same query — a roadmap draws every marker at once, so a count per marker would be a query per row.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.
include_archivedbooleanOptionalInclude 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.

ProjectMilestone object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
namestringRequiredDisplay name.
descriptionstring | nullOptionalFree-form description.
datedateRequiredThe milestone date.
task_countintegerOptionalNumber of live tasks.
attachment_countintegerOptionalREADY attachments on this milestone. Reference them from description with attachment:{uuid} markers and list them at …/milestones/{milestone_id}/attachments/.
is_archivedbooleanOptionalWhether the row is archived. Archive is the delete: archived rows stay readable and restorable.
completed_atdate-time | nullOptionalWhen it was completed, or null.
created_atdate-timeOptionalWhen the row was created.
updated_atdate-timeOptionalWhen the row last changed.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<ProjectMilestone>RequiredThe rows on this page. See ProjectMilestone.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
POST/v1/plan/projects/{project_id}/milestones/BetaAPI keyCLI Auth

Commit to a dated moment

Adds a milestone to a project: a name, a date and an optional description. Complete it later with the complete endpoint.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
namestringRequiredDisplay name.
datedateRequiredThe milestone date.
descriptionstring | nullOptionalFree-form description.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectMilestoneRequiredA ProjectMilestone object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Beta launch",
    "date": "2026-10-15"
  }'

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.
  • 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.
PATCH/v1/plan/projects/{project_id}/milestones/{milestone_id}/BetaAPI keyCLI Auth

Move or rename a milestone

Renames a milestone, moves its date or edits its description. Send only the fields you change.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
namestringOptionalDisplay name.
datedateOptionalThe milestone date.
descriptionstring | nullOptionalFree-form description.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectMilestoneRequiredA ProjectMilestone object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-10-22"
  }'

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.
  • 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.
DELETE/v1/plan/projects/{project_id}/milestones/{milestone_id}/BetaAPI keyCLI Auth

Retire a milestone (archives; tasks keep pointing at it)

Archives rather than hard-deletes, so tasks keep pointing at the milestone and the association is never lost. The change is recorded in the activity feed as project.milestone_deleted — read it as "retired". It is not a webhook event.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
  • 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.
POST/v1/plan/projects/{project_id}/milestones/{milestone_id}/complete/BetaAPI keyCLI Auth

Mark a milestone complete

Completing with open tasks is allowed. Those tasks stay open; the response reports open_task_count. Reversible via …/reopen/. ?dry_run=true returns the consequence without writing.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Query parameters

NameTypeRequiredDescription
dry_runbooleanOptionalPreview the consequence without performing it. The response has the same shape, {operation, dry_run, reversible, restore_path, consequence, affects}, but nothing is written and no event is emitted. Show consequence to a person before acting.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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.

DryRunPreview object

What the call answers with ?dry_run=true: the consequence, without performing it. Nothing is written and no event is emitted.

NameTypeRequiredDescription
operationstringRequiredThe operation that would run.
dry_runbooleanRequiredAlways true.
reversiblebooleanRequiredWhether the operation can be undone.
restore_pathstring | nullRequiredThe path that would undo it, or null when there is none.
consequencestringRequiredA sentence to show a person before acting. It states the cascade rather than summarising it.
affectsobjectRequiredWhat the operation would touch, as counts (integers) by kind.
would_refusebooleanOptionalWorkflow state archive only: true when the real call would be refused.
refusal_codestringOptionalWorkflow state archive only: the error code the real call would answer with.

Response

NameTypeRequiredDescription
(body)ProjectMilestone | DryRunPreviewRequiredA ProjectMilestone object. With ?dry_run=true, a DryRunPreview object instead.
open_task_countintegerOptionalTasks still open in the milestone. Completing with open tasks is allowed.

Errors

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/complete/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
  • 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.
POST/v1/plan/projects/{project_id}/milestones/{milestone_id}/reopen/BetaAPI keyCLI Auth

Clear milestone completion

Clears a milestone's completion, so it counts as open again.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectMilestoneRequiredA ProjectMilestone object.

Errors

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/reopen/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
  • 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.
POST/v1/plan/projects/{project_id}/archive/BetaCLI Auth

Archive a project, cascading to its boards and their tasks

Archive is the delete. Nothing in this API hard-deletes a project; the rows survive so identifiers, links and events keep resolving.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Query parameters

NameTypeRequiredDescription
dry_runbooleanOptionalPreview the consequence without performing it. The response has the same shape, {operation, dry_run, reversible, restore_path, consequence, affects}, but nothing is written and no event is emitted. Show consequence to a person before acting.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)Project | DryRunPreviewRequiredA Project object. With ?dry_run=true, a DryRunPreview object instead.

Errors

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/archive/" \
  -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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
POST/v1/plan/projects/{project_id}/restore/BetaCLI Auth

Restore an archived project

Inverse of archive, and the reason archiving a project is no longer the one act in Plan a person cannot undo. Boards and tasks that cascaded on archive stay archived: restore walks back up, never down, because "restore everything archived at the time" cannot tell the cascade apart from a board somebody archived on purpose beforehand. Bring those back with POST …/boards/{board_id}/restore/. Restore consumes one project-creation entitlement slot (archive frees one) and answers 402 when the plan has none to give.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalA 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-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectRequiredA Project object.

Errors

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`), or no project slot is free (`task_projects_limit_reached`).
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/restore/" \
  -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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/milestones/BetaAPI keyCLI AuthPage-number pagination

Every milestone the viewer may see, across projects

Every milestone you may see across projects, in one call, for a roadmap's markers. Visibility follows the projects you can open. project__in narrows that set and never widens it: an unknown uuid and another organization's uuid both return an empty result. Rows carry project as a reference.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.
project__instringOptionalComma-separated project uuids; at most 50. Narrows the visible set, never widens it.
include_archivedstringOptionalInclude retired milestones alongside live ones.

OrganizationMilestone object

NameTypeRequiredDescription
uuidstringRequiredStable public identifier.
namestringRequiredDisplay name.
descriptionstring | nullOptionalFree-form description.
datestringRequiredThe milestone date.
task_countintegerOptionalNumber of live tasks.
attachment_countintegerOptionalREADY attachments on this milestone. Reference them from description with attachment:{uuid} markers and list them at …/milestones/{milestone_id}/attachments/.
is_archivedbooleanOptionalWhether the row is archived. Archive is the delete: archived rows stay readable and restorable.
projectobjectRequiredThe project. A reference object.
created_atstringOptionalWhen the row was created.
updated_atstringOptionalWhen the row last changed.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<OrganizationMilestone>RequiredThe rows on this page. See OrganizationMilestone.

Errors

StatusWhen
400Validation failed, or a filter, sort or `include` value was not recognised. The response `code` says which.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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/milestones/?project__in=00000000-0000-4000-8000-000000000001" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
GET/v1/plan/projects/{project_id}/views/BetaCLI AuthPage-number pagination

This person's saved views inside a project

Your saved views inside a project: named filter sets that span every board in it. Views are personal and scoped by project, so the same name can exist in two projects. Needs a person: agent and organization keys are refused; a personal API key works.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

SavedView object

NameTypeRequiredDescription
namestringRequiredDisplay name. Max 64 characters.
view_modeenumOptionalHow the filtered set is drawn. Reads always return board for the kanban layout. One of list, board, timeline, calendar.
group_byenumOptionalThe grouping dimension. One of state, owner, priority, category.
sortstringOptionalA sort key, - prefixed for descending.
filtersobjectRequiredThe view's filters, in the shared task filter grammar.
schema_versionintegerOptionalVersion of the view's stored format.
visibilityenumOptionalpersonal (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.
collapsedobject | array | string | number | booleanOptionalClient UI state stored verbatim (which groups are collapsed). Only size and depth are validated.
columnsobject | array | string | number | booleanOptionalClient UI state stored verbatim (which columns are shown). Only size and depth are validated.
uuiduuidOptionalStable public identifier.
scopeenumOptionalWhich container the view belongs to: board or project. Read-only. One of board, project.
boarduuid | nullOptionalThe board's uuid when scope is board; null for a project view. Read-only.
ownerobjectOptionalWho owns the view. Shape: {uuid, name}.
created_atdate-timeOptionalWhen the row was created.
updated_atdate-timeOptionalWhen the row last changed.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<SavedView>RequiredThe rows on this page. See SavedView.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/views/" \
  -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: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`.
PUT/v1/plan/projects/{project_id}/views/BetaCLI Auth

Replace this person's saved views for a project

Replaces your whole saved-view array for the project. If-Match is required, for the same reason as board views.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
If-MatchstringRequiredThe ETag you received from GET .../views/, quoted. Required, because this PUT replaces the whole array: without a precondition two concurrent saves silently drop one another's view. A stale validator is 412 precondition_failed; a missing one is 428 precondition_required.
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)array<SavedView>RequiredA JSON array of SavedView objects.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
412The `If-Match` validator is stale (`precondition_failed`). Read again and retry.
428`If-Match` is required (`precondition_required`).
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS -X PUT "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/views/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "If-Match: $VIEWS_ETAG" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "name": "Overdue",
      "view_mode": "list",
      "filters": {
        "due_before": "2026-09-25",
        "state": [
          "open"
        ]
      }
    }
  ]'

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`.
GET/v1/plan/projects/{project_id}/members/BetaCLI AuthPage-number pagination

Members of a project

Visible to anyone who can see the project. On a members project this is the membership that grants sight of the project and its boards.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.

BoardMember object

NameTypeRequiredDescription
subject_typeenumRequiredOne of user, team.
user_uuiduuid | nullOptionalThe person's user uuid.
uuiduuid | nullOptionalStable public identifier.
full_namestringOptional—
namestringOptionalDisplay name.
roleenum | nullOptionalParticipant role. One of admin, member, guest.
team_uuiduuid | nullOptionalA team's uuid, instead of user_uuid. It creates one live team grant: whoever joins the team later is in, and whoever leaves is out.
team_namestringOptional—
added_atdate-timeRequired—
added_by_uuiduuid | nullOptional—

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<BoardMember>RequiredThe rows on this page. See BoardMember.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404Not found, or not visible to you. Both cases return the same body.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/members/" \
  -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: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`.
POST/v1/plan/projects/{project_id}/members/BetaCLI Auth

Invite somebody, or a whole team, into a project

Grants one person (user_uuid) or one team (team_uuid) access to the project: send exactly one of them; both or neither is 400 invalid_filter_value. A team grant is live: whoever joins the team later is in, and whoever leaves is out. Every non-guest member can call it (with a login session or a personal API key); an agent or organization key gets 403 insufficient_scope.

Writes a project.member_added event carrying actor_is_self, so the project's members can tell an invitation from somebody letting themselves in.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
user_uuiduuidOptionalThe person's user uuid.
team_uuiduuidOptionalA team's uuid, instead of user_uuid. It creates one live team grant: whoever joins the team later is in, and whoever leaves is out.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)BoardMemberRequiredA BoardMember object.

Errors

StatusWhen
400Send exactly one of `user_uuid` and `team_uuid`; both or neither is `invalid_filter_value`. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/members/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_uuid": "00000000-0000-4000-8000-00000000000c"
  }'

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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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/v1/plan/projects/{project_id}/members/{user_id}/BetaCLI Auth

Remove somebody from a project

Removes a person's explicit grant on the project. Every non-guest member can call it (with a login session or a personal API key); an agent or organization key cannot.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
user_idstringRequiredThe member's user uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Authenticated 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`).
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/members/00000000-0000-4000-8000-00000000000c/" \
  -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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
PATCH/v1/plan/projects/{project_id}/members/{user_id}/BetaCLI Auth

Inspect a project membership grant (role is read-only)

Project membership has no role column — org roles plus project visibility are the access model. Sending role returns 400. An empty PATCH returns the current grant row.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
user_idstringRequiredThe member's user uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)BoardMemberRequiredA BoardMember object.

Errors

StatusWhen
400Validation 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.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404Not found, or not visible to you. Both cases return the same body.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/members/00000000-0000-4000-8000-00000000000c/" \
  -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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/projects/{project_id}/attachments/BetaAPI keyCLI AuthPage-number pagination

List a project's attachments

The project's attachments, ordered by position. Anyone who can see the project can list its attachments; a project you cannot see is 404. Each url is a download link. Do not store it: keep the attachment uuid and read it again when you need the file. To show an image in the project's description, reference it as attachment:{uuid} and resolve it when you render, using the fresh url from this list.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.

TaskAttachment object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
filenamestringRequiredFile name.
content_typestringRequiredMIME type.
sizeintegerRequiredSize in bytes.
urlstringRequiredWhere to download the file.
thumbnail_urluri | nullOptionalThumbnail for images.
widthinteger | nullOptional—
heightinteger | nullOptional—
statusenumRequiredCurrent status. One of pending, ready, scanning, rejected.
uploaded_byActorRef | nullOptionalWho uploaded the file. See ActorRef.
executed_by_agentobject | nullOptionalThe 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_atdate-timeRequiredWhen the row was created.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<TaskAttachment>RequiredThe rows on this page. See TaskAttachment.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/attachments/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
POST/v1/plan/projects/{project_id}/attachments/BetaCLI Auth

Upload an attachment to a project

Attach a file to a project. Send multipart/form-data with the file field and an optional caption; there is no presign flow here. The limit is 5 MiB in every environment: a larger file is 400 attachment_too_large, with extra.max_size_bytes. The file type is checked from its content against the same list as task attachments (attachment_invalid_type). A project holds at most 50 attachments (attachment_limit_reached).

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filebinaryRequiredThe file to upload (max 5 MiB this way).
captionstringOptionalOptional caption. Max 255 characters.

Response

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400The file is missing, too large (`attachment_too_large`, over 5 MiB), of an unsupported type (`attachment_invalid_type`), or the limit of 50 is reached (`attachment_limit_reached`). `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Not a non-guest member acting with a login session or a personal API key (`insufficient_scope`); an agent or organization key always gets this.
404The project or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/attachments/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -F "file=@./screenshot.png" \
  -F "caption=Staging dashboard"

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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/projects/{project_id}/attachments/{attachment_id}/content/BetaAPI keyCLI Auth

Download a project attachment's bytes

Streams the file with the content type recorded at upload, X-Content-Type-Options: nosniff and Cache-Control: no-store. It never redirects to storage. Anyone who can see the project can download it.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
attachment_idstringRequiredThe attachment's uuid.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/attachments/00000000-0000-4000-8000-000000000009/content/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
DELETE/v1/plan/projects/{project_id}/attachments/{attachment_id}/BetaCLI Auth

Remove an attachment from a project

Removes the attachment from the project.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
attachment_idstringRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Not a non-guest member acting with a login session or a personal API key (`insufficient_scope`); an agent or organization key always gets this.
404The project or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/attachments/00000000-0000-4000-8000-000000000009/" \
  -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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
POST/v1/plan/projects/{project_id}/milestones/{milestone_id}/restore/BetaAPI keyCLI Auth

Restore a retired milestone

Brings a retired milestone back. It is the inverse of retiring a milestone with DELETE. Idempotent: a milestone that is not retired is returned unchanged. Send an Idempotency-Key to retry safely.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectMilestoneRequiredA ProjectMilestone object.

Errors

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403The credential cannot write to Plan (`insufficient_scope`), or the caller is a guest (`guest_not_allowed`).
404The project or milestone does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/restore/" \
  -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.
  • 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.
GET/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/BetaAPI keyCLI AuthPage-number pagination

List a milestone's attachments

The milestone's READY attachments, ordered by position. Anyone who can see the project can list them; a project you cannot see is 404. Each url is a download link. Do not store it: keep the attachment uuid and read it again when you need the file. Reference it from the milestone description with an attachment:{uuid} marker; resolve it with GET /v1/plan/attachments/resolve/ when you render.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.

TaskAttachment object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
filenamestringRequiredFile name.
content_typestringRequiredMIME type.
sizeintegerRequiredSize in bytes.
urlstringRequiredWhere to download the file.
thumbnail_urluri | nullOptionalThumbnail for images.
widthinteger | nullOptional—
heightinteger | nullOptional—
statusenumRequiredCurrent status. One of pending, ready, scanning, rejected.
uploaded_byActorRef | nullOptionalWho uploaded the file. See ActorRef.
executed_by_agentobject | nullOptionalThe 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_atdate-timeRequiredWhen the row was created.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<TaskAttachment>RequiredThe rows on this page. See TaskAttachment.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or milestone does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/" \
  -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: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.
POST/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/BetaAPI keyCLI Auth

Upload an attachment to a milestone

Attaches a file to the milestone. Send multipart/form-data with the file field and an optional caption; there is no presign flow here. The limit is 5 MiB: a larger file is 400 attachment_too_large, with extra.max_size_bytes. The file type is checked from its content against the same list as project attachments (attachment_invalid_type). Attaching follows the milestone's own write rules. Reference it from the milestone description with an attachment:{uuid} marker; resolve it with GET /v1/plan/attachments/resolve/ when you render.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filebinaryRequiredThe file to upload (max 5 MiB this way).
captionstringOptionalOptional caption. Max 255 characters.

Response

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400The file is missing, too large (`attachment_too_large`, over 5 MiB), of an unsupported type (`attachment_invalid_type`), or the limit of 50 is reached (`attachment_limit_reached`). `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403The credential cannot write to Plan (`insufficient_scope`), or the caller is a guest (`guest_not_allowed`).
404The project or milestone does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -F "[email protected]"

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.
  • 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.
GET/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Retrieve a milestone attachment

One attachment of the milestone. Anyone who can see the project can read it.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.
attachment_idstringRequiredThe attachment's uuid.

Response

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project, the milestone or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/00000000-0000-4000-8000-000000000009/" \
  -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: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.
PATCH/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Rename a milestone attachment

Changes the attachment's file name; the content does not change. The rules are the milestone's own.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.
attachment_idstringRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filenamestringRequiredThe new file name.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400The name is missing or not valid. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403The credential cannot write to Plan (`insufficient_scope`), or the caller is a guest (`guest_not_allowed`).
404The project, the milestone or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/00000000-0000-4000-8000-000000000009/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename": "roadmap-v2.png"}'

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.
  • 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.
DELETE/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Remove a milestone attachment

Removes the attachment. The rules are the milestone's own.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.
attachment_idstringRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403The credential cannot write to Plan (`insufficient_scope`), or the caller is a guest (`guest_not_allowed`).
404The project, the milestone or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/00000000-0000-4000-8000-000000000009/" \
  -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.
  • 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.
GET/v1/plan/projects/{project_id}/milestones/{milestone_id}/attachments/{attachment_id}/content/BetaAPI keyCLI Auth

Download a milestone attachment's bytes

Streams the file with the content type recorded at upload, X-Content-Type-Options: nosniff and Cache-Control: no-store. It never redirects to storage. Anyone who can see the project can download it.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
milestone_idstringRequiredThe milestone's uuid.
attachment_idstringRequiredThe attachment's uuid.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project, the milestone or the attachment does not exist or you cannot see it (`not_found`), never a 403.
409The attachment is not ready yet (`attachment_not_ready`).
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/milestones/00000000-0000-4000-8000-000000000007/attachments/00000000-0000-4000-8000-000000000009/content/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" -o roadmap.png

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.
GET/v1/plan/projects/{project_id}/updates/{update_id}/BetaAPI keyCLI Auth

Get a project update

One status note, with its READY attachments inline, provenance, edited_at (null until the first edit) and executed_by_agent.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Response

NameTypeRequiredDescription
(body)ProjectUpdateRequiredA ProjectUpdate object.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/" \
  -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: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.
PATCH/v1/plan/projects/{project_id}/updates/{update_id}/BetaAPI keyCLI Auth

Edit a project update

Changes body and/or health (null clears it) and stamps edited_at. Only the author can edit (403 update_not_author). created_by and the original executed_by_agent never change; an edit made through an API key, or stamped with an agent, makes provenance agent_authored. To place images inline, upload them to the update's attachments and add attachment:{uuid} markers to body. Send If-Match or a body version to avoid overwriting a concurrent edit.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
bodystringOptionalMarkdown. Max 20000 characters.
healthenum | nullOptionalDeclared health. One of not_set, on_track, at_risk, off_track.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectUpdateRequiredA ProjectUpdate object.

Errors

StatusWhen
400The body is empty or too long (`update_body_too_long`), or `health` is not valid. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Only the update's author can do this (`update_not_author`).
404The project or update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"body": "Staging is green; rolling out Friday.", "health": "on_track"}'

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.
  • 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.
DELETE/v1/plan/projects/{project_id}/updates/{update_id}/BetaAPI keyCLI Auth

Delete a project update

Removes the update and its attachments; a stored file is deleted once nothing else references it. The author or an organization admin can delete (403 update_not_author for anyone else).

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Only the update's author can do this (`update_not_author`).
404The project or update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/" \
  -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.
  • 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.
GET/v1/plan/projects/{project_id}/updates/{update_id}/attachments/BetaAPI keyCLI AuthPage-number pagination

List a update's attachments

The update's READY attachments, ordered by position. Anyone who can see the project can list them; a project you cannot see is 404. Each url is a download link. Do not store it: keep the attachment uuid and read it again when you need the file. Reference it from the update body with an attachment:{uuid} marker; resolve it with GET /v1/plan/attachments/resolve/ when you render.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.

TaskAttachment object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
filenamestringRequiredFile name.
content_typestringRequiredMIME type.
sizeintegerRequiredSize in bytes.
urlstringRequiredWhere to download the file.
thumbnail_urluri | nullOptionalThumbnail for images.
widthinteger | nullOptional—
heightinteger | nullOptional—
statusenumRequiredCurrent status. One of pending, ready, scanning, rejected.
uploaded_byActorRef | nullOptionalWho uploaded the file. See ActorRef.
executed_by_agentobject | nullOptionalThe 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_atdate-timeRequiredWhen the row was created.

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<TaskAttachment>RequiredThe rows on this page. See TaskAttachment.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/" \
  -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: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.
POST/v1/plan/projects/{project_id}/updates/{update_id}/attachments/BetaAPI keyCLI Auth

Upload an attachment to a update

Attaches a file to the update. Send multipart/form-data with the file field and an optional caption; there is no presign flow here. The limit is 5 MiB: a larger file is 400 attachment_too_large, with extra.max_size_bytes. The file type is checked from its content against the same list as project attachments (attachment_invalid_type). Only the update's author can attach (403 update_not_author). Upload first, then add the marker to the update's body with a PATCH. Reference it from the update body with an attachment:{uuid} marker; resolve it with GET /v1/plan/attachments/resolve/ when you render.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filebinaryRequiredThe file to upload (max 5 MiB this way).
captionstringOptionalOptional caption. Max 255 characters.

Response

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400The file is missing, too large (`attachment_too_large`, over 5 MiB), of an unsupported type (`attachment_invalid_type`), or the limit of 50 is reached (`attachment_limit_reached`). `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Only the update's author can do this (`update_not_author`).
404The project or update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -F "[email protected]"

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.
  • 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.
GET/v1/plan/projects/{project_id}/updates/{update_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Retrieve a update attachment

One attachment of the update. Anyone who can see the project can read it.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.
attachment_idstringRequiredThe attachment's uuid.

Response

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project, the update or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/00000000-0000-4000-8000-000000000009/" \
  -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: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.
PATCH/v1/plan/projects/{project_id}/updates/{update_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Rename a update attachment

Changes the attachment's file name; the content does not change. Only the update's author can rename it (403 update_not_author).

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.
attachment_idstringRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filenamestringRequiredThe new file name.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400The name is missing or not valid. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Only the update's author can do this (`update_not_author`).
404The project, the update or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/00000000-0000-4000-8000-000000000009/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename": "roadmap-v2.png"}'

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.
  • 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.
DELETE/v1/plan/projects/{project_id}/updates/{update_id}/attachments/{attachment_id}/BetaAPI keyCLI Auth

Remove a update attachment

Removes the attachment. The update's author can remove it, and so can an organization admin (403 update_not_author for anyone else).

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.
attachment_idstringRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400The agent name is invalid (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403Only the update's author can do this (`update_not_author`).
404The project, the update or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/00000000-0000-4000-8000-000000000009/" \
  -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.
  • 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.
GET/v1/plan/projects/{project_id}/updates/{update_id}/attachments/{attachment_id}/content/BetaAPI keyCLI Auth

Download a update attachment's bytes

Streams the file with the content type recorded at upload, X-Content-Type-Options: nosniff and Cache-Control: no-store. It never redirects to storage. Anyone who can see the project can download it.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.
attachment_idstringRequiredThe attachment's uuid.

Errors

StatusWhen
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project, the update or the attachment does not exist or you cannot see it (`not_found`), never a 403.
409The attachment is not ready yet (`attachment_not_ready`).
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000001/updates/00000000-0000-4000-8000-00000000000a/attachments/00000000-0000-4000-8000-000000000009/content/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" -o roadmap.png

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.
PATCH/v1/plan/projects/{project_id}/attachments/{attachment_id}/BetaCLI Auth

Rename a project attachment

Changes the display file name; the stored bytes do not change. The rules are the container's own: organization administrators only.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
attachment_iduuidRequiredThe attachment's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
filenamestringRequiredThe new file name (1–255 characters). The stored bytes do not change.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)TaskAttachmentRequiredA TaskAttachment object.

Errors

StatusWhen
400Validation failed; the response `code` says which field. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
403You are not an organization administrator (`insufficient_scope`), or you are a guest (`guest_not_allowed`). An agent or organization key is refused here too.
404The parent or the attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000003/attachments/00000000-0000-4000-8000-000000000009/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "filename": "spec-v2.pdf"
}'

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:admin` — container writes. A non-guest member can call it with a login session or a personal API key (a key with explicit Plan scopes needs `tasks:write`, which covers it); an agent or organization key gets `403 insufficient_scope`.
  • 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`.
GET/v1/plan/projects/{project_id}/updates/{update_id}/reactions/BetaAPI keyCLI AuthPage-number pagination

List who reacted to a project update

Everyone who reacted to the update, oldest first, as a page. emoji narrows to one emoji. The same shape as a comment's reactor list.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Query parameters

NameTypeRequiredDescription
pageintegerOptional1-based page number.
page_sizeintegerOptionalRows per page. Default 50, maximum 100. Out-of-range values are clamped, never rejected: asking for 500 returns 100.
emojistringOptionalOne emoji; every emoji when omitted. The same rule as writes: anything else is 400 reaction_invalid_emoji.

Reactor object

NameTypeRequiredDescription
emojistringRequired—
userActorRefRequiredWho reacted.
executed_by_agentAgentRef | nullOptionalThe agent that executed the reaction for that person, or null.
created_atdatetimeRequired—

ActorRef object

NameTypeRequiredDescription
kindstringRequired—
uuidstringRequiredStable public identifier.
namestringOptionalDisplay name.
usernamestring | nullOptional—
avatar_urlstring | nullOptional—
has_photobooleanOptional—

Response

NameTypeRequiredDescription
countintegerRequiredTotal number of rows.
nexturiRequiredURL of the next page, or null.
previousuriRequiredURL of the previous page, or null.
resultsarray<Reactor>RequiredThe page of Reactor objects.

Errors

StatusWhen
400`emoji` is not a single emoji (`reaction_invalid_emoji`), or a paging value is not valid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or the update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000003/updates/00000000-0000-4000-8000-000000000007/reactions/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
POST/v1/plan/projects/{project_id}/updates/{update_id}/reactions/BetaAPI keyCLI Auth

Add an emoji reaction to a project update (idempotent)

Adds your emoji reaction to the update; adding it again changes nothing. The same rules as comment reactions: one emoji, one reaction per person per emoji, and a person behind the credential. A person holds at most 20 different emojis on one update (400 reaction_limit_reached, extra.limit). The response is the whole update with its reactions.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

NameTypeRequiredDescription
emojistringRequiredThe emoji. Max 32 characters.
agent_namestringOptionalThe 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

NameTypeRequiredDescription
(body)ProjectUpdateRequiredA ProjectUpdate object.

Errors

StatusWhen
400Not a single emoji (`reaction_invalid_emoji`), an agent or organization key (`actor_required`), too many different emojis from you on this update (`reaction_limit_reached`), or an invalid agent name (`invalid_agent_attribution`).
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or the update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X POST "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000003/updates/00000000-0000-4000-8000-000000000007/reactions/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "emoji": "👍"
}'

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.
  • 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.
DELETE/v1/plan/projects/{project_id}/updates/{update_id}/reactions/{emoji}/BetaAPI keyCLI Auth

Remove the caller's emoji reaction from a project update

Removes your reaction with this emoji from the update. It answers 204 even when the reaction was already gone.

Path parameters

NameTypeRequiredDescription
project_idstringRequiredThe project's uuid.
update_idstringRequiredThe update's uuid.
emojistringRequiredThe emoji, percent-encoded as UTF-8.

Headers

NameTypeRequiredDescription
X-Dailybot-Agent-NamestringOptionalThe 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

StatusWhen
400Validation failed; the response `code` says which field. `invalid_agent_attribution` means the agent name is invalid.
401Missing, expired or malformed credential (`credential_absent`, `credential_expired`, `credential_malformed`).
402Plan is not enabled for your organization yet (`plan_upgrade_required`). Expected during the Beta: write to [email protected].
404The project or the update does not exist or you cannot see it (`not_found`), never a 403.
curl -sS -X DELETE "https://api.dailybot.com/v1/plan/projects/00000000-0000-4000-8000-000000000003/updates/00000000-0000-4000-8000-000000000007/reactions/%F0%9F%91%8D/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

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.
  • 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.

This page is the reference for Plan · Projects. 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.