Openbook

Board API

Give another system read access to a Kanban board — named, revocable tokens, one endpoint, the full board as JSON.

What the Board API is

Some things that read a board are not people: an integration that turns cards into work items, a script that builds a weekly report, a dashboard on a wall. The Board API gives them a read-only view of one board over HTTP — the full board, as JSON, guarded by tokens you mint and delete yourself.

It is a separate decision from publishing. A published board is a page for strangers' eyes, and its publish settings deliberately hold things back (descriptions and assignee names are off unless you turn them on). The API is for systems you chose to connect, so it always returns the full board: descriptions, assignees, dates, priorities, story points, labels, tags, and every checklist item. Enabling it — and minting a token — is the explicit act of sharing that much.

The API has no writes. Nothing that holds a token can change a card, a column, or anything else.

Turn it on

  1. Open the Kanban room and click Share on the board.
  2. Flip API access on. (The Public board toggle above it is unrelated — either can be on without the other.)
  3. Under Tokens, name a token for the system that will use it — "Madebook", "weekly report" — and click Create token.

One token per consumer is the point: when you delete a token, exactly that consumer is cut off, immediately, and the others keep working. Flipping API access off cuts them all off at once without deleting anything; flip it back on and the same tokens work again.

Read the board

One endpoint:

GET https://app.openbook.work/kanban/api/v1/board
Authorization: Bearer <token>

(?token=<token> in the query string works too, for tools that cannot set headers.)

The response is the board, its columns in order, and every card:

{
  "data": true,
  "board": { "name": "openbook build", "updated_at": "…" },
  "columns": [
    {
      "key": "col12",
      "title": "In progress",
      "color": null,
      "cards": [
        {
          "key": "6KjNOGvpDmMj",
          "reference_number": "OB-7",
          "title": "Universal login",
          "description": "Acceptance criteria:\n- SSO works\n- logout everywhere",
          "assigned_to": "Richard",
          "start_date": null,
          "due_date": "2026-09-12",
          "priority": "high",
          "story_points": 3,
          "in_backlog": false,
          "labels": ["story"],
          "tags": [{ "name": "auth", "color": "blue" }],
          "tasks": [{ "title": "wire the redirect", "completed": true }],
          "updated_at": "…"
        }
      ]
    }
  ]
}

A card's key is stable and unguessable; reference_number is the human key (OB-7) when the board assigns them. Backlog cards are included and marked in_backlog — filter them out if you only want the visible columns.

Errors are plain: 401 for a missing or unknown token, 403 when API access is switched off for the board.

Webhooks

Polling tells you eventually; webhooks tell you now. With API access on, the same Share dialog lets you register webhook URLs — every card created, edited, moved, or deleted on the board is announced to each of them within seconds. A move matters most: a card reaching Done is what tells a consumer to stop building it.

Each delivery is a POST with JSON:

{
  "event": "card.moved",
  "board": { "name": "openbook build" },
  "cards": [{ "key": "6KjNOGvpDmMj", "reference_number": "OB-7" }],
  "sent_at": "2026-08-31T12:00:00.000Z"
}

Events: card.created, card.updated, card.moved, card.deleted, and ping (from the Test button). Headers carry x-openbook-event, and — when the webhook was registered with a secret — x-openbook-signature: an HMAC SHA-256 of the raw body, hex-encoded, for consumers that verify.

Delivery is best-effort by design: one attempt, a five-second timeout, no retries — the consumer's own scheduled reconciliation is the guarantee of eventual truth, and the webhook only buys speed. The dialog shows each URL's last delivery result, so a dead endpoint is visible rather than silent. Deliveries stop the moment API access is switched off, and a deleted webhook never fires again.

Connecting Madebook: its connection card (Missions › Sources) shows a per-connection webhook URL — paste that here, no secret needed (the URL authenticates itself), and card changes reach Madebook in seconds instead of on the quarter-hour poll.

Self-hosted

Replace app.openbook.work with your own host. The path is the same wherever Openbook runs — it is part of the API's contract, not the deployment's.

What uses this today

Madebook connects to a board through this API as a mission source: cards become work items, the column a card sits in becomes its status, and "Acceptance criteria:" blocks in descriptions become contract material. Point Madebook's Missions › Sources → Openbook.work at a token from this page.