Skip to content
view raw .md

Plan · Goals

Goals say what the work is for. They point at projects; nothing lives inside a goal. Part of the Dailybot Plan API (Beta).

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/goals/BetaAPI keyCLI AuthPage-number pagination

List goals

The goals you can see, as a page. Filter by status, owned_by, a date inside the goal's period with active_on, or text with search. include=progress,projects adds the progress roll-up and linked projects.

Query parameters

Sorting & expansion

NameTypeRequiredDescription
includestringOptionalComma-separated roll-ups to embed: progress, projects. Absent by default because each is an aggregate. 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.

Filters

NameTypeRequiredDescription
searchstringOptionalMatches title and key. Longer than 256 characters is 400 search_query_too_long, not truncated. q is an alias.
statusstringOptionalRepeatable. Filters by declared status.
owned_bystringOptionalThe accountable person's uuid. Named owned_by rather than owner because the task grammar's owner accepts me and unowned, and one parameter name that means two different value spaces is how a client sends the wrong one.
active_onstringOptionalGoals whose period covers this date - the roadmap's own question.

Archived rows

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

Goal object

NameTypeRequiredDescription
uuiduuidRequiredStable public identifier.
namestringRequiredDisplay name. Max 120 characters.
descriptionstring | nullOptionalFree-form description.
statusenumRequiredCurrent status. One of not_started, on_track, at_risk, off_track, achieved, missed.
period_startdateRequiredFirst day of the goal's period.
period_enddateRequiredLast day of the goal's period.
ownerUserRef | nullOptionalThe person accountable for the task. See UserRef.
teamTeamRef | nullOptionalThe team. See TeamRef.
progressGoalProgress | nullOptionalProgress roll-up over the tasks you can see. See GoalProgress.
project_countintegerOptionalNumber of linked projects.
projectsarrayOptionalLinked projects. Items: {uuid, name, slug, health, lead}.
is_archivedbooleanRequiredWhether the row is archived. Archive is the delete: archived rows stay readable and restorable.
completed_atdate-time | nullOptionalWhen it was completed, or null.
archived_atdate-time | nullOptionalWhen the row was archived.
created_atdate-timeOptionalWhen the row was created.
updated_atdate-timeOptionalWhen the row last changed.
viewerobjectRequiredWhat you can do with this row. Shape: {can_manage: boolean}.

UserRef object

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

TeamRef object

NameTypeRequiredDescription
uuidstringRequiredStable public identifier.
namestringOptionalDisplay name.

GoalProgress 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.
is_partialbooleanRequiredtrue when some of the goal's work is hidden from you, so the numbers cover only what you can see.

Response

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

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/goals/?include=progress,projects" \
  -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/goals/BetaCLI Auth

Create a goal

Creates a goal with a period and a declared status. A live goal with the same name is 409 goal_name_conflict. Every non-guest member can call it (with a login session or a personal API key); an agent or organization key cannot.

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
namestringRequiredDisplay name. Max 120 characters.
descriptionstringOptionalFree-form description. Max 2000 characters.
period_startdateRequiredFirst day of the goal's period.
period_enddateRequiredLast day of the goal's period.
owneruuid | nullOptionalThe owner's user uuid. The person must already be able to see the board (400 participant_cannot_access_board otherwise).
teamuuid | nullOptionalThe team.
statusenumOptionalCurrent status. One of not_started, on_track, at_risk, off_track, achieved, missed.
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)GoalRequiredA Goal 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`).
409A live goal already has this name (`goal_name_conflict`).
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS -X POST "https://api.dailybot.com/v1/plan/goals/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q4 Roadmap",
    "period_start": "2026-10-01",
    "period_end": "2026-12-31",
    "status": "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: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/goals/{goal_id}/BetaAPI keyCLI Auth

One goal, with its derived progress

Always returns progress, projects and project_count; the include parameter is not needed here.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal's uuid.

Response

NameTypeRequiredDescription
(body)GoalRequiredA Goal 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].
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/goals/00000000-0000-4000-8000-000000000006/" \
  -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/goals/{goal_id}/BetaCLI Auth

Update a goal, or declare its status

Changes a goal's fields or declares its status (on_track, at_risk, …). 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.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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. Max 120 characters.
descriptionstringOptionalFree-form description. Max 2000 characters.
period_startdateOptionalFirst day of the goal's period.
period_enddateOptionalLast day of the goal's period.
owneruuid | nullOptionalThe owner's user uuid. The person must already be able to see the board (400 participant_cannot_access_board otherwise).
teamuuid | nullOptionalThe team.
statusenumOptionalCurrent status. One of not_started, on_track, at_risk, off_track, achieved, missed.
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)GoalRequiredA Goal 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.
409A live goal already has this name (`goal_name_conflict`).
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS -X PATCH "https://api.dailybot.com/v1/plan/goals/00000000-0000-4000-8000-000000000006/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "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`.
POST/v1/plan/goals/{goal_id}/archive/BetaCLI Auth

Archive a goal. The projects survive, unpointed

Archives the goal. Nothing lives inside a goal, so its projects stay where they are, no longer pointing at it. Send ?dry_run=true first to see the consequence without archiving.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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)Goal | DryRunPreviewRequiredA Goal 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.
429Rate limit reached. Wait the number of seconds in `Retry-After`.
curl -sS -X POST "https://api.dailybot.com/v1/plan/goals/00000000-0000-4000-8000-000000000006/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/goals/{goal_id}/restore/BetaCLI Auth

Bring an archived goal back

The inverse of archive/, mirroring boards/{board_id}/restore/. Restoring a goal that is already live is a 200 no-op, not an error. Goal names are unique among LIVE goals, so if the name was taken while this one was archived the restore answers 409 goal_name_conflict — the one edge that separates a real restore from a flag flip.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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)GoalRequiredA Goal 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.
409A live goal already has this name (`goal_name_conflict`).
curl -sS -X POST "https://api.dailybot.com/v1/plan/goals/00000000-0000-4000-8000-000000000006/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/goals/{goal_id}/attachments/BetaAPI keyCLI AuthPage-number pagination

List a goal's attachments

The goal's attachments, ordered by position. Anyone who can see the goal can list its attachments; a goal 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 goal's description, reference it as attachment:{uuid} and resolve it when you render, using the fresh url from this list.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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.

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<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 goal or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/goals/00000000-0000-4000-8000-000000000006/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/goals/{goal_id}/attachments/BetaCLI Auth

Upload an attachment to a goal

Attach a file to a goal. 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 goal holds at most 50 attachments (attachment_limit_reached).

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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 goal 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/goals/00000000-0000-4000-8000-000000000006/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/goals/{goal_id}/attachments/{attachment_id}/content/BetaAPI keyCLI Auth

Download a goal 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 goal can download it.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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 goal or attachment does not exist or you cannot see it (`not_found`), never a 403.
curl -sS "https://api.dailybot.com/v1/plan/goals/00000000-0000-4000-8000-000000000006/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/goals/{goal_id}/attachments/{attachment_id}/BetaCLI Auth

Remove an attachment from a goal

Removes the attachment from the goal.

Path parameters

NameTypeRequiredDescription
goal_idstringRequiredThe goal'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 goal 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/goals/00000000-0000-4000-8000-000000000006/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`.
PATCH/v1/plan/goals/{goal_id}/attachments/{attachment_id}/BetaCLI Auth

Rename a goal 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
goal_idstringRequiredThe goal'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/goals/00000000-0000-4000-8000-000000000006/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`.

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