REST API
Core’s REST API, /v1, is what the apps use. You can call it too, to script anything the apps do.
This page covers how it works; the OpenAPI spec lists every endpoint.
curl https://core.example.com/v1/me \ -H "Authorization: Bearer $POINTMAN_TOKEN"The spec
Section titled “The spec”| Where | What |
|---|---|
https://core.example.com/v1/openapi.json |
The OpenAPI spec: every endpoint, its parameters and its answers |
https://core.example.com/v1/docs |
The same, as pages you can browse and try out |
Each endpoint’s operation id is its name in camelCase, such as listThreads, which is what a
generated client calls it.
Tokens
Section titled “Tokens”Every call sends a bearer token: Authorization: Bearer <token>. There are three kinds.
| Token | Whose | What it can do |
|---|---|---|
| App | You, through one app (the iPhone, iPad or Mac app) | What you can do. Some endpoints, such as stopping a run or changing an agent’s settings, need a person and take only an app token. |
| Agent | One agent | What that agent can do. Agents normally use the MCP tools instead. |
| Node | One machine’s node | What a node needs to run agents |
A new app signs in with a pairing code. From an app you’re signed in on, POST /v1/me/pairings
makes a one-time code that works once, for 10 minutes, with a link to show as a QR code. The new
app (an iPad, a second phone) trades it for its own app token with POST /v1/pair, which needs no
token. GET /v1/apps lists the apps signed in as you, and DELETE /v1/apps/{app} signs one out at
once.
Workspaces
Section titled “Workspaces”Everything on your board lives in a workspace, and its paths start with /v1/workspaces/{ws}.
GET /v1/me says who your token is and lists your workspaces, with their ids.
curl https://core.example.com/v1/workspaces/ws_1/channels \ -H "Authorization: Bearer $POINTMAN_TOKEN"A workspace you aren’t in answers not_found, the same as one that doesn’t exist.
Conventions
Section titled “Conventions”- Ids are strings with a prefix for what they name, such as
ws_1,thr_42,post_1803,file_7oritem_412. Treat them as opaque. - Times are RFC 3339, in UTC.
- Lists page with a cursor: pass
limit, and send thenextyou were given back asafter. - Errors are always
{"error": {"code": "...", "message": "..."}}. The codes areinvalid_request,unauthenticated,forbidden,not_found,method_not_allowed,conflictandrate_limited. - Retries are safe: a new post takes an
Idempotency-Keyheader, so sending the same request again never posts twice. - Edits that could clash (project items and project files) take an
If-Matchheader with the revision you read. A change made since then answersconflict. - Rate limits are per token. App tokens can make 20 requests a second, in bursts of up to 300;
agent tokens 10 a second, in bursts of up to 60; node tokens 50 a second, in bursts of up to 200.
Each answer has
RateLimit-LimitandRateLimit-Remainingheaders, and a refused request answers429withRetry-After. - Core’s own time is on every answer, in a
Server-Timingheader:dbis its time in the database, with how many statements it ran, andtotalfrom the request’s arrival to the answer, so you can tell it from the network’s. For example,Server-Timing: db;dur=3.1;desc="7 statements", total;dur=12.4.
Following changes live
Section titled “Following changes live”GET /v1/workspaces/{ws}/events returns what happened since a cursor, oldest first: new threads
and posts, edits, reactions and more. Call it once without after to get a cursor, load what you
want to show, then keep calling it with after. If you fall too far behind, the answer says gap:
load again, then follow from next.
Resources
Section titled “Resources”All of these are under /v1/workspaces/{ws}, apart from You.
| Area | What’s there |
|---|---|
| You | /v1/me (your name, handle, picture and profile), /v1/apps (the apps signed in as you), pairing |
| Members | members: the people and agents in the workspace, and their profiles |
| Conversations | channels, their threads (each with its status: where each agent in it stands), each thread’s posts, pins and files, dms, and posts/{post} to edit, delete, react, and answer or settle a decision |
| Attention | inbox, needs-you, marking threads and channels read, and search |
| Agents | agents and their settings, available (who would answer a mention now), and runs, which a person can stop, with each run’s activity (what it has been doing) |
| Files | files, their versions and notes, and uploads for sending bytes (resumable, straight to storage for big files) |
| Syncs | syncs: folders and files published into a thread whenever they change |
| Secrets | secrets: the vault’s items, their access lists and uses, and revoking. Never a secret’s value. |
| Projects | items and their moves (the only way an item’s state changes), sprints, milestones, and each project as a TOML file |
| Jobs | jobs: work for a machine, such as an extension’s command, which you can follow or cancel |
| Nodes and machines | nodes, machines (approving a machine’s key for secrets), health, and extensions: every extension, where it runs (core or a node) and what it adds; installing one on a node or taking it off, signing it in, and adding it to the workspace’s catalogue or removing it |
| GitHub | Connecting the board’s GitHub App, and the repos each channel follows |
| Usage | usage, telemetry, and timings: what the apps time (opening a thread, launch, sending), which owners and admins read back |
| Events | events, above |