# Dailybot Plan API

> Plan and track work through the Dailybot Plan API (Beta): projects, boards, tasks and goals over one REST API, with the concepts you need before your first call.

Language: en
Canonical: https://www.dailybot.com/developers/plan
Markdown: send header `Accept: text/markdown` on any URL to receive Markdown instead of HTML.
Last Updated: 2026-09-26

---

> **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 **support@dailybot.com**.
>
> [request beta access](mailto:support@dailybot.com?subject=Dailybot%20Plan%20Beta%20access)

Dailybot Plan is where a team plans and tracks its work: **projects**, **boards**, **tasks** and **goals**. The web app, the Dailybot CLI and the agent skill all use the same public API under `https://api.dailybot.com/v1/plan/`. There is no private API behind them, so anything one of them can do, your integration can do too.

This page explains the model once. Every other Plan page links back here.

<h2 id="permissions">Who can do what</h2>

Every authenticated **non-guest member** can use the whole Plan API: create and manage goals, projects, boards, states and memberships. A **personal API key** acts as its person and can do everything that person can do, so a member's key needs no scope grant and no organization-admin role. Guests are refused before entitlement (`403 guest_not_allowed`), with a key or a session.

**Privacy is invite / membership**, not org role. Org-wide projects and boards are a shared workspace. A `members` container is **404** (not visible) without a grant. Invite a person or a team to share; the last grant on a private container is `409 last_grant_cannot_be_removed`. There are no per-project roles (lead/viewer) — membership is a grant, not a role ladder.

**Oversight:** organization admins and managers of all teams can see every project. A `members` board still needs an explicit grant.

**Agent and organization keys** have no person behind them: they see organization-visible boards only and are refused (`403 insufficient_scope`) on the endpoints that need a person. Full detail: [Authentication and scopes for Plan](/developers/plan/authentication).

<h2 id="start-here">Start here</h2>

- **[Concepts](/developers/plan/concepts)**: projects, goals, boards, columns, owners and executors, labels, views and the inbox, one paragraph each.
- **[Agents on Plan](/developers/plan/agents)**: let an agent read a card and write back as a person, with the agent shown on the card.
- **[Dailybot CLI for Plan](/developers/plan/cli)** and the **[agent skill](/developers/plan/agent-skill)**: the command line and the public skill pack.
- **[Quickstart](/developers/plan/quickstart)**: your first calls in under five minutes (sign in, list boards, create, move and comment on a task).
- **[API reference](/developers/api/plan-tasks)**: every endpoint, grouped into [Projects](/developers/api/plan-projects), [Goals](/developers/api/plan-goals), [Boards](/developers/api/plan-boards), [Tasks](/developers/api/plan-tasks), [Comments & files](/developers/api/plan-collaboration) and [Home & search](/developers/api/plan-home).
- **[Authentication and scopes for Plan](/developers/plan/authentication)**: the three credentials, what a personal API key can do, scopes, guests and privacy as membership.
- **[Conventions for Plan](/developers/plan/conventions)**: pagination, filters, sorting, `include`, rate limits, `Idempotency-Key`, `If-Match` and `304`.
- **[Errors for Plan](/developers/plan/errors)**: every code with its status, meaning and what to do next, including `402` during the Beta.
- **[Authentication](/developers/authentication)** and **[Errors](/developers/errors)**: the rules shared by every Dailybot API.

<h2 id="recipes">Recipes</h2>

- **[Show a board and keep it fresh](/developers/plan/recipes/board-live-updates)**: snapshot, delta feed and server-paced polling.
- **[Render a home in one request](/developers/plan/recipes/home-in-one-request)**: the home pulse and its bands.
- **[Create tasks from a list](/developers/plan/recipes/bulk-create)**: bulk create with a dry run and idempotency.
- **[Move a task when a pull request merges](/developers/plan/recipes/move-on-pr-merge)**: from any CI, addressed by key.
- **[Track progress against a goal](/developers/plan/recipes/goal-progress)**: progress, projects and `is_partial`.
- **[React to changes with webhooks](/developers/plan/recipes/webhooks)**: the 25 events and verifying deliveries.

<h2 id="check-access">Check that Plan is enabled for your organization</h2>

Plan is in Beta and is enabled per organization. `GET /v1/plan/entitlements/` is the one Plan endpoint that answers even when your organization is not enabled yet, so call it first:

```bash
curl -sS "https://api.dailybot.com/v1/plan/entitlements/" \
  -H "Authorization: Bearer $DAILYBOT_TOKEN"
```

```json
{
  "enabled": false,
  "reason": "rollout",
  "boards": { "used": 0, "limit": 3 },
  "projects": { "used": 0, "limit": 1 },
  "labels": { "enabled": true }
}
```

`enabled: false` with `reason: "rollout"` means your organization is not in the Beta yet. Every other Plan endpoint answers `402 plan_upgrade_required` until it is: that is expected. Write to **support@dailybot.com** to join.

<h2 id="model">The model: organization, project, board, task</h2>

```
Organization
└── Project            what a body of work is (health, status notes, milestones)
    └── Board          where the work is tracked; its columns are workflow states
        └── Task       one unit of work, addressed as ENG-142
```

A board belongs to a project and a task belongs to a board. Tasks can have **sub-tasks** (one level deep), **relations** to other tasks (`blocks`, `relates_to`, `duplicates`), an **owner**, **participants**, **labels**, **comments** and **attachments**.

<h3 id="workflow-states">Workflow states and their five categories</h3>

A board's columns are its **workflow states**. You can name them anything, but every state has one of five fixed **categories**, and the category is what answers "is this finished?" on any board:

| Category | Meaning | Counts as |
|---|---|---|
| `backlog` | Not planned yet | open |
| `todo` | Planned, not started | open |
| `in_progress` | Being worked on | open |
| `done` | Finished | done |
| `canceled` | Will not be done | done |

The `state` filter accepts two shortcuts built on these categories: `open` (`backlog`, `todo`, `in_progress`) and `done` (`done`, `canceled`). "Blocked" is not a category: it is derived from relations, so filter with `blocked=true`.

<h3 id="goals">Goals point at work; they do not contain it</h3>

A **goal** says what the work is *for*, with a period (`period_start`, `period_end`) and a declared `status`. Nothing lives inside a goal. A project can point at several goals and a goal can be served by several projects, so archiving a goal leaves every project where it was.

A task can point at its own goal. When it does not, it inherits its project's goal, and filters and progress roll-ups apply that same rule.

Goal **progress is scoped to you**: it counts only the tasks you can see, and `is_partial: true` tells you when some of the goal's work is hidden from you. Never present it as an organization-wide number.

<h2 id="identifiers">Identifiers: uuid and KEY-n</h2>

Every object has a `uuid`. A task also has a human-readable key, `KEY-n`, such as `ENG-142`: `ENG` is the board's key and `142` is a per-board counter. **Both work wherever a task is addressed**, for example `GET /v1/plan/tasks/ENG-142/`.

A board's key can be renamed and **old keys keep resolving**, so a link written last year still opens the card. Keys are never reused, even after a task or board is archived. Numeric ids are never accepted.

An identifier that does not exist and an identifier from another organization return the **same `404` body**, so the API never reveals whether something exists outside your organization.

<h2 id="ordering">Ordering: move relative to neighbours</h2>

Cards in a column are ordered by an opaque `rank`. **Never compute a rank.** Place a card relative to its neighbours instead: `POST /v1/plan/tasks/{task_id}/move/` takes a target `state` and at most one of `after` / `before` (a task in that column). Send neither to append at the end. Two people dragging the same card at the same time both produce a valid order.

Moving is the only way to change a task's state.

<h2 id="versions">Versions and concurrent edits</h2>

Every task carries an integer `version` that increments on each write. To make sure you do not overwrite somebody else's edit, send the version you loaded in the `If-Match` header (or as the body field `version`) when you update, move or move a task to another board. If the task changed meanwhile, the API answers `409 version_conflict` with the current version in `extra.current_version`, so you can re-read and decide.

Without `If-Match`, the last write wins.

<h2 id="archive">Archive is the delete</h2>

No public endpoint hard-deletes a task, a board or a project. **Archiving is the delete**, and it is reversible:

- Archiving a project cascades to its boards and their tasks; archiving a board cascades to its tasks; archiving a task archives its sub-tasks.
- Restore walks back up, never down: restoring a project does not restore the boards it archived, because the API cannot tell them apart from boards archived on purpose. Restore each one you want back.
- Tasks, boards, projects, goals and workflow states each have a `…/restore/` endpoint.
- The `DELETE` endpoints for tasks and milestones are aliases that archive.
- Archived rows stay readable: lists hide them unless you pass `include_archived=true`, and a task stays readable by key or uuid.
- Board keys stay reserved through archive and restore.

The archive endpoints, milestone completion and bulk calls accept `?dry_run=true`, which returns the consequence (including a sentence to show a person) without writing anything.

<h2 id="mentions">Mentions</h2>

To mention someone in a comment or a project update, write `<@DB@{uuid}>`, using the person's `uuid` from `GET /v1/plan/boards/{board_id}/mentionables/`:

```text
Looks good. <@DB@00000000-0000-4000-8000-00000000000c> can you review the rollout plan?
```

Responses render mentions as display text in `body` and list the people in `mentions[]`: read them from there, never by parsing `body`. A uuid that names nobody in your organization is removed from the text. Comments support one level of threading through `parent_comment`.

<h2 id="additive-enums">Ignore values you do not recognise</h2>

Event types, relation types, state categories and the list of webhook events are **additive**: new values arrive in minor releases. A client that treats an unknown value as an error will break on a release that changed nothing for it. Skip what you do not know.

<h2 id="beta">What Beta means here</h2>

Paths, fields and behaviour described on these pages can change before general availability; we announce changes in the [API changelog](/developers/api-changelog). If something you rely on is missing or unclear, write to **support@dailybot.com**.

---

## Developer portal navigation

**Getting Started**

- [Overview](/developers)
- [Quick start](/developers/getting-started)
- [Authentication](/developers/authentication)

**API Reference**

- [API Overview](/developers/api)
- [Users](/developers/api/users)
- [Organization](/developers/api/organization)
- [Teams](/developers/api/teams)
- [Invitations](/developers/api/invitations)
- [Check-ins](/developers/api/check-ins)
- [Forms](/developers/api/forms)
- [Labels](/developers/api/labels)
- [Report channels](/developers/api/report-channels)
- [Templates](/developers/api/templates)
- [Kudos](/developers/api/kudos)
- [Mood tracking](/developers/api/mood)
- [Important dates](/developers/api/important-dates)
- [Messaging](/developers/api/messaging)
- [Automations](/developers/api/workflows)
- [Webhooks](/developers/api/webhooks)
- [Commands platform](/developers/api/commands-platform)
- [Agents](/developers/api/agents)
- [OAuth2](/developers/api/oauth2)
- [Integrations](/developers/api/integrations)
- [CLI](/developers/api/cli)
- [Plan · Projects](/developers/api/plan-projects)
- [Plan · Goals](/developers/api/plan-goals)
- [Plan · Boards](/developers/api/plan-boards)
- [Plan · Tasks](/developers/api/plan-tasks)
- [Plan · Comments & files](/developers/api/plan-collaboration)
- [Plan · Home & search](/developers/api/plan-home)
- [Plan · Notifications & reports](/developers/api/plan-notifications)

**Dailybot Plan**

- [Overview](/developers/plan) (this page)
- [Concepts](/developers/plan/concepts)
- [Quickstart](/developers/plan/quickstart)
- [Authentication & scopes](/developers/plan/authentication)
- [Agents on Plan](/developers/plan/agents)
- [Conventions](/developers/plan/conventions)
- [Errors](/developers/plan/errors)
- [CLI for Plan](/developers/plan/cli)
- [Agent skill](/developers/plan/agent-skill)
- [Recipe: live board](/developers/plan/recipes/board-live-updates)
- [Recipe: home in one request](/developers/plan/recipes/home-in-one-request)
- [Recipe: bulk create](/developers/plan/recipes/bulk-create)
- [Recipe: move on PR merge](/developers/plan/recipes/move-on-pr-merge)
- [Recipe: goal progress](/developers/plan/recipes/goal-progress)
- [Recipe: webhooks](/developers/plan/recipes/webhooks)

**API guides**

- [Errors & Status Codes](/developers/errors)
- [Rate Limits](/developers/rate-limits)
- [Conventions](/developers/conventions)
- [API Changelog](/developers/api-changelog)
- [Recipes](/developers/recipes)

**Developer Features**

- [Custom commands](/developers/custom-commands)
- [Serverless commands](/developers/serverless)
- [Webhooks & events](/developers/webhooks)
- [Automation API trigger](/developers/workflow-trigger)
- [Activity API](/developers/activity-api)

**CLI**

- [Overview](/developers/cli)
- [Authentication](/developers/cli-authentication)
- [Command reference](/developers/cli-reference)
- [CI/CD recipes](/developers/cli-ci-cd)
- [Configuration](/developers/cli-configuration)
- [Troubleshooting](/developers/cli-troubleshooting)

**Agent Skill**

- [Overview](/developers/agent-skill)
- [Skills catalog](/skills)

---

## Site navigation

**Product:**
- [Home](/)
- [Product](/product)
- [Pricing](/pricing)
- [Enterprise](/enterprise)
- [Integrations](/integrations)
- [Templates](/templates)

**Resources:**
- [Blog](/blog)
- [Academy](/academy)
- [Changelog](/changelog)
- [Help Center](/help)
- [Developers](/developers)
- [Agents](/agents)

**Company:**
- [About](/about)
- [Careers](/careers)
- [Security](/security)
- [Contact Sales](/demo)

**Connect:**
- [LinkedIn](https://www.linkedin.com/company/dailybot/)
- [X/Twitter](https://twitter.com/dailybot)
- [GitHub](https://github.com/Dailybot-Inc)
- [YouTube](https://www.youtube.com/channel/UC3uM9V52vwX7e3vQpCc4qvA)

