Authentication and scopes for Plan
Which credentials reach the Dailybot Plan API (Beta): login sessions, personal API keys that act as their person, agent and organization keys, scopes, guests and privacy.
Beta
Plan is in beta. Everything under /plan in the web app, the CLI and agent skill commands for projects, goals, boards and tasks, and the /v1/plan/ public API may change before general availability. Want to try it with your team? Write to [email protected].
The Plan API accepts three credentials. They behave differently, so pick the one that matches who is acting. The general rules for every Dailybot API live in Authentication and CLI authentication; this page covers what is specific to Plan.
Three credentials
| Credential | How you send it | Acts as | Use it for |
|---|---|---|---|
| Login session | Authorization: Bearer <token> (the web app, or dailybot login for the CLI) |
You, with your role | The Dailybot web app, and scripts and agents working on behalf of one person |
| Personal API key | X-API-KEY: <key> |
The person who created it, for themselves | Scripts, CI and agents that should be that person |
| Agent or organization key | X-API-KEY: <key> |
A system actor: no person behind it | Server-to-server integrations that read or write organization-visible work |
Login session: acts as you
A login session carries your identity and your role in the organization. dailybot login gets one with an emailed one-time code; the same flow is available over HTTP (see the quickstart). A login token only travels to the API host that issued it.
curl -sS "https://api.dailybot.com/v1/plan/me/tasks/" \
-H "Authorization: Bearer $DAILYBOT_TOKEN"
Personal API key: acts as its person
A personal API key is created by a person for themselves. On Plan it answers exactly as that person does in the web app:
- It sees what the person sees, including the private boards they belong to.
meis the person, and every write is recorded as the person. - It can do everything the person can do on every Plan endpoint: all reads and all task writes, and all structure and membership writes: projects, boards, columns, goals, milestones, members (by user or team), participants, mute, saved views and attachments.
- There is no organization-admin prerequisite and no scope to request: every non-guest member can, so their key can.
- A key row that carries explicit
tasks:*scopes is a ceiling the person chose:tasks:writecovers admin operations too, andtasks:readkeeps the key read-only. A key with only non-Plan scopes has no Plan access.
curl -sS "https://api.dailybot.com/v1/plan/me/tasks/" \
-H "X-API-KEY: $DAILYBOT_API_KEY"
Agent or organization key: a system actor
A key with no person behind it never acts as a person:
- It sees organization-visible boards only, never members-only boards.
- It has no
me:?owner=meanswers400 actor_required. - Endpoints that need a person or an administrator (listed below) answer
403 insufficient_scope. - It must hold Plan scopes of its own (
tasks:readandtasks:write). - It acts as a specific person only when the request also carries an exchange token (
X-EXCHANGE-TOKEN), as described in Authentication. - It cannot name an agent on a write: sending an agent name with an agent key is
400 invalid_agent_attribution.
curl -sS "https://api.dailybot.com/v1/plan/boards/" \
-H "X-API-KEY: $DAILYBOT_API_KEY"
Agent and organization keys need Plan scopes enabled for the key. A new key has none. During the Beta, write to [email protected] to enable them.
Guests are limited by role with a key or a session alike: 403 guest_not_allowed, before anything else is checked. An expired key is 401 credential_expired; a revoked key or a deactivated owner is 401 too (see sign-in errors).
Scopes
| Scope | Grants |
|---|---|
tasks:read |
Every read |
tasks:write |
Row-level writes: tasks, comments, labels, relations, participants. On a key row it also covers the admin operations below |
tasks:admin |
Container writes: projects, boards, states, memberships, goals. Every non-guest member holds it |
Each endpoint in the reference states its scope. How a credential gets them:
| Credential | Scopes |
|---|---|
| Login session, non-guest member | tasks:read, tasks:write, tasks:admin |
| Personal API key | Everything its person can do, without granting anything. If the key row lists explicit Plan scopes, they are a ceiling |
| Agent or organization key | Only the scopes granted to the key (tasks:read, tasks:write); it is refused on the endpoints that need a person |
| Guest, with any credential | None: refused with 403 guest_not_allowed before entitlement |
A call without the scope it needs answers 403 insufficient_scope.
Privacy is membership (invite), not org role. Org-wide containers are a shared workspace. A members project, board or task answers 404 not found to anyone without a grant, in reads, lists, search, comments, attachments and activity alike. Treat that as not visible, never as “not allowed”. A board inside a members project follows the project’s membership, and boards expose effective_visibility (org or members) so you can tell. Invite a person or a team with membership writes to share; the last grant on a private container is 409 last_grant_cannot_be_removed. There are no per-project roles such as lead or viewer: membership is a grant only.
Oversight. Organization admins and managers of all teams can see every project. A members board still needs an explicit grant.
Guests are refused before anything else is checked, so a guest never learns whether the organization is enabled for Plan or how close it is to its plan limits.
Endpoints that need a person
Some endpoints need a person behind the request, so an agent or organization key is refused with 403 insufficient_scope. A login session and a personal API key work on all of them. In the reference, the API key badge on an endpoint means an agent or organization key is accepted too; endpoints without it are the ones listed here. They fall into four families:
- Your own things: your tasks, counts, recent boards, inbox, activity cursor, favorites and saved views.
- Who can see: project member lists (a board’s member list works with any key). Changing members is an administration operation (below).
- Who is notified: task participants and watch subscriptions. A key with no person has nobody to be accountable for who gets notified.
- Administration (
tasks:admin): creating, editing, archiving and restoring projects, boards, workflow states and goals, reordering states, adding and removing project and goal attachments, adding, changing and removing board and project members, and linking goals to projects. A personal API key can do all of it.
Managing organization labels through the Plan API (…/labels/) needs a person as well.
POST /v1/plan/projects/: Create a projectPATCH /v1/plan/projects/{project_id}/: Update a projectPOST /v1/plan/projects/{project_id}/archive/: Archive a project, cascading to its boards and their tasksPOST /v1/plan/projects/{project_id}/restore/: Restore an archived projectGET /v1/plan/projects/{project_id}/views/: This person’s saved views inside a projectPUT /v1/plan/projects/{project_id}/views/: Replace this person’s saved views for a projectGET /v1/plan/projects/{project_id}/members/: Members of a projectPOST /v1/plan/projects/{project_id}/members/: Invite somebody, or a whole team, into a projectDELETE /v1/plan/projects/{project_id}/members/{user_id}/: Remove somebody from a projectPATCH /v1/plan/projects/{project_id}/members/{user_id}/: Inspect a project membership grant (role is read-only)POST /v1/plan/projects/{project_id}/attachments/: Upload an attachment to a projectDELETE /v1/plan/projects/{project_id}/attachments/{attachment_id}/: Remove an attachment from a project
POST /v1/plan/goals/: Create a goalPATCH /v1/plan/goals/{goal_id}/: Update a goal, or declare its statusPOST /v1/plan/goals/{goal_id}/archive/: Archive a goal. The projects survive, unpointedPOST /v1/plan/goals/{goal_id}/restore/: Bring an archived goal backPOST /v1/plan/goals/{goal_id}/projects/: Link a project to a goal (from the goal page)DELETE /v1/plan/goals/{goal_id}/projects/{project_id}/: Unlink a project from a goalPOST /v1/plan/goals/{goal_id}/attachments/: Upload an attachment to a goalDELETE /v1/plan/goals/{goal_id}/attachments/{attachment_id}/: Remove an attachment from a goal
POST /v1/plan/boards/: Create a board and seed its five default statesPATCH /v1/plan/boards/{board_id}/: Update a board, including renaming its keyPOST /v1/plan/boards/{board_id}/archive/: Archive a board, cascading to its tasksPOST /v1/plan/boards/{board_id}/restore/: Restore an archived boardPOST /v1/plan/boards/{board_id}/visit/: Record that the caller opened a board (HomePulse recent_boards)POST /v1/plan/boards/{board_id}/states/: Add a workflow state to a boardPATCH /v1/plan/boards/{board_id}/states/{state_id}/: Rename, recolour or reorder a workflow statePOST /v1/plan/boards/{board_id}/states/{state_id}/archive/: Retire a columnPOST /v1/plan/boards/{board_id}/states/{state_id}/restore/: Restore a retired columnPOST /v1/plan/boards/{board_id}/states/reorder/: Reorder every live column on a board in one callGET /v1/plan/boards/{board_id}/views/: The caller’s saved views for this boardPUT /v1/plan/boards/{board_id}/views/: Replace the caller’s saved views for this boardGET /v1/plan/boards/{board_id}/mentionables/: Search people mentionable on a boardPOST /v1/plan/boards/{board_id}/members/: Add a member to a boardDELETE /v1/plan/boards/{board_id}/members/{user_id}/: Remove a member from a boardPATCH /v1/plan/boards/{board_id}/members/{user_id}/: Inspect a board membership grant (role is read-only)GET /v1/plan/boards/{board_id}/labels/: List organization labels (board access gate)POST /v1/plan/boards/{board_id}/labels/: Create an organization labelGET /v1/plan/views/{view_id}/: One saved view by uuidPATCH /v1/plan/views/{view_id}/: Edit one saved viewDELETE /v1/plan/views/{view_id}/: Delete one saved view
POST /v1/plan/tasks/{task_id}/subscription/: Subscribe to task notifications (watcher role)DELETE /v1/plan/tasks/{task_id}/subscription/: Remove a watcher subscriptionGET /v1/plan/tasks/{task_id}/participants/: Who is on this cardPOST /v1/plan/tasks/{task_id}/participants/: Put someone on this cardDELETE /v1/plan/tasks/{task_id}/participants/{user_uuid}/: Take someone off this card
GET /v1/plan/me/tasks/: The calling user’s tasksGET /v1/plan/me/tasks/counts/: Personal task tab countsGET /v1/plan/me/recents/: Recently visited boards for the callerGET /v1/plan/inbox/: Notification-worthy task events for the callerPOST /v1/plan/inbox/read-all/: Mark all inbox items readPOST /v1/plan/inbox/{item_uuid}/read/: Catch up to one inbox rowGET /v1/plan/inbox/unread-count/: Unread inbox count for the callerGET /v1/plan/me/activity-cursor/: Read the caller’s activity read cursorPUT /v1/plan/me/activity-cursor/: Mark activity as read up to a timestampGET /v1/plan/labels/: List organization labelsPOST /v1/plan/labels/: Create an organization labelPATCH /v1/plan/labels/{label_id}/: Update an organization labelDELETE /v1/plan/labels/{label_id}/: Delete an organization labelGET /v1/plan/me/favorites/: Your pinned boards and saved viewsPOST /v1/plan/me/favorites/: Pin a board or a saved viewPATCH /v1/plan/me/favorites/{favorite_id}/: Move one pin within your listDELETE /v1/plan/me/favorites/{favorite_id}/: Unpin
When Plan is not enabled
What you get depends on why:
| Situation | Response |
|---|---|
| Your organization’s plan allows Plan but it is not in the Beta yet | 402 plan_upgrade_required on every Plan endpoint, with any credential. This is expected during the Beta: write to [email protected] |
| Free-plan organization, CLI user token | 403 plan_upgrade_required, raised at sign-in, before Plan is reached |
| Free-plan organization, organization API key | 401 plan_free_api_keys_forbidden |
GET /v1/plan/entitlements/ never answers 402: call it to find out whether Plan is enabled and why not.
Sign-in errors
These come from the credential itself, before any Plan rule runs:
| Status | Code | Meaning |
|---|---|---|
| 401 | credential_absent · credential_expired · credential_malformed |
No credential, an expired one, or one that cannot be read |
| 401 | invalid_credentials |
The key or token does not exist |
| 401 | api_key_owner_inactive |
The key’s owner has been deactivated |
| 401 | plan_free_api_keys_forbidden |
API keys are not available on the free plan |
| 401 | plan_missing_core_api_integrations |
The organization’s plan does not include API access |
| 403 | plan_upgrade_required |
Free-plan CLI sign-in reaching a paid endpoint |
| 429 | (throttled) | Too many requests: wait the seconds in Retry-After |
The full list of Plan codes is in the reference’s error tables and in Errors.