Endpoints
Every route an API token can call, by resource, with the scope it needs; and the few that only the portal can.
Reading this page
A route's scope is its resource, the first part of its path after /v1, and its level: read for a GET, write
for anything else. So a route nested under a task is a task route: starting a run, POST /v1/tasks/{id}/runs, needs
tasks:write, not runs:write. See Authentication for tokens and scopes, and
Conventions for errors, pagination and retries.
Every {id} is an id, never a slug. Apart from the catalogue, every route below answers only for your own
enterprise: an id from another enterprise is a 404.
Tasks
A task's definition, its versions and schedule, and the runs, memory and recommendations that belong to it. See Tasks, and Tasks over the API for the task as JSON.
| Call | Scope | What it does |
|---|---|---|
GET /v1/tasks |
tasks:read |
Tasks, a page at a time, with search and filters. |
POST /v1/tasks |
tasks:write |
Create a task, with its first version. |
GET /v1/tasks/{id} |
tasks:read |
The task, its current version and skill, its version list, its webhook, and its definition warnings. |
DELETE /v1/tasks/{id} |
tasks:write |
Delete the task and every version of it. Its runs are kept. A 409 while it has a run under way. |
POST /v1/tasks/{id}/copy |
tasks:write |
Copy it as a new task of your own: send teamId, name and slug, and optionally assigneeRole, which is the original's unless you send one. |
GET /v1/tasks/{id}/versions |
tasks:read |
Every version, newest first. |
GET /v1/tasks/{id}/versions/{versionId} |
tasks:read |
One version as it was, with its skill, how many runs used it, and whether it is current. |
POST /v1/tasks/{id}/versions |
tasks:write |
Publish a new version. Send baseVersionId. |
GET /v1/tasks/{id}/workflow |
tasks:read |
The current version and its skill, on their own. |
PUT /v1/tasks/{id}/schedule |
tasks:write |
Set its schedule. See Schedules and webhooks. |
DELETE /v1/tasks/{id}/schedule |
tasks:write |
Remove its schedule. |
POST /v1/tasks/{id}/runs |
tasks:write |
Start a run, with the body as its input. |
GET /v1/tasks/{id}/memory |
tasks:read |
The notes trained on this task, and its training grants. |
POST /v1/tasks/{id}/memory |
tasks:write |
Train a note on this task: { "text": "…" }. |
GET /v1/tasks/{id}/memory/ask |
tasks:read |
Ask memory as this task would. See Memory. |
POST /v1/tasks/{id}/memory/train |
tasks:write |
Train a note, or a correction, at a layer this task may write. A person may train this task's team, or the enterprise, here. |
GET /v1/tasks/{id}/recommendations |
tasks:read |
Self-improvement recommendations for this task. |
A task is given to a role, never to one member. A body that creates, changes, copies or clones a task and still
names a member in assigneeMemberId is refused with a 400 (assignee_member_removed).
Runs
One run of one task: its status, events, log and cost. See Runs.
| Call | Scope | What it does |
|---|---|---|
GET /v1/runs |
runs:read |
Runs, a page at a time, filtered by task, version or status. |
GET /v1/runs/{id} |
runs:read |
One run, its events and gates, its task, what came before and after it, and its cost. afterEventId sends only the events since that one. |
GET /v1/runs/{id}/log |
runs:read |
Its full log, once stored. A 404 (log_not_found) until then. |
GET /v1/runs/{id}/os-tool |
runs:read |
A short read: its status, task, input and last eight events. |
POST /v1/runs/{id}/cancel |
runs:write |
Cancel it. |
POST /v1/runs/{id}/retry |
runs:write |
Retry it as a new run, on the task's current version. |
POST /v1/runs/{id}/clear |
runs:write |
Take a failed run, or a pipeline that stopped, off Blockers. |
Blockers
What cannot move without someone. See Runs.
| Call | Scope | What it does |
|---|---|---|
GET /v1/blockers |
blockers:read |
Everything on Blockers, section by section. failedPage and pageSize page the failed runs. |
POST /v1/blockers/clear |
blockers:write |
Clear every failed run at once: { "section": "failed" }. |
Executions
The connected runs of more than one task. See Executions.
| Call | Scope | What it does |
|---|---|---|
GET /v1/executions |
executions:read |
Executions, a page at a time. Closed ones only with closed=true. |
GET /v1/executions/board |
executions:read |
Every lane of the board in one read. |
GET /v1/executions/counts |
executions:read |
How many executions and runs are running, queued and waiting. |
GET /v1/executions/{id} |
executions:read |
One execution: its runs, links and task graph. Any of its run ids works. |
POST /v1/executions/{id}/cancel |
executions:write |
Stop every open run in it. |
POST /v1/executions/{id}/close |
executions:write |
Take a finished execution off the board. |
POST /v1/executions/{id}/reopen |
executions:write |
Put a closed execution back. |
POST /v1/executions/close-completed |
executions:write |
Close every execution in the Complete lane under the given filters. |
Gates
The calls and questions waiting for your decision. See Gates and tool scopes.
| Call | Scope | What it does |
|---|---|---|
GET /v1/gates |
gates:read |
Every gate waiting on you. |
POST /v1/gates/{id}/decision |
gates:write |
Decide one: decision is approve, reject or request_changes, with an optional note, answers for questions, and choice (the key of one of the gate's choices) on a gate that offers its own. |
POST /v1/gates/chat/{chatId}/decision |
gates:write |
Answer the question a chat is waiting on. Name it with gateId, or the newest is answered. |
gates:write decides gates, including merges that go live. Grant it deliberately.
Chats
Talking to a member. See Chat and plans.
| Call | Scope | What it does |
|---|---|---|
GET /v1/chats |
chats:read |
Chats, the most recently active first. memberId narrows them to one member. A chat opened for a purpose is not listed. |
POST /v1/chats |
chats:write |
Start a chat with a member: { "memberId": "…" }. Or open one for a single job, { "purpose": "create_task" }: a new chat with the COO (the member who has held the role longest), or with memberId when you send one, whose greeting is already in it. It closes once the task it proposes is applied or rejected. Refused with unknown_purpose for any other purpose, and no_coo when nobody holds the COO role. |
GET /v1/chats/unread |
chats:read |
How many replies nobody has read yet, in the chats GET /v1/chats lists. |
GET /v1/chats/{id} |
chats:read |
One chat and its messages, oldest first. limit (1 to 200) returns only the newest. Reading it marks it read. |
POST /v1/chats/{id}/messages |
chats:write |
Send a message: { "content": "…" }. The member's reply follows in the chat. |
POST /v1/chats/{id}/tool-calls/{callId}/decision |
chats:write |
Answer a tool call the member is waiting on: allow, always or deny. |
POST /v1/chats/{id}/close |
chats:write |
Close the chat. |
GET /v1/chats/tool-grants |
chats:read |
The "Always allow" answers you have given for one member's tools. Send memberId. |
DELETE /v1/chats/tool-grants/{grantId} |
chats:write |
Withdraw one. |
A token's "Always allow" answers are its own, not a person's, and a person's are not the token's.
Planned
Plans
When a member can propose a change to the company as a plan (Chat and plans), you will read it here and decide it as a gate:
| Call | Scope | What it does |
|---|---|---|
GET /v1/plans |
plans:read |
Plans, newest first, filtered by status, kind, chatSessionId or producedByRunId. |
GET /v1/plans/{id} |
plans:read |
One plan, its items, and the run and gates behind it. |
Memory
What the company has learned. See Memory.
| Call | Scope | What it does |
|---|---|---|
GET /v1/memory |
memory:read |
The notes, with search and filters, a page at a time. |
POST /v1/memory/train |
memory:write |
Train a team or enterprise note. No task is required. layer is team or enterprise; a team train sends teamId, and that team must belong to your enterprise. |
GET /v1/memory/recall-health |
memory:read |
How often memory could be read over the last 24 hours, by runs and by chat messages. |
GET /v1/memory/{id} |
memory:read |
One note and its evidence. |
POST /v1/memory/{id}/tombstone |
memory:write |
Exclude a note from every future answer. |
POST /v1/memory/{id}/rate |
memory:write |
Rate a note up or down, with an optional reason. |
GET /v1/memory/review |
memory:read |
The review queue: conflicts, and notes rated down. |
GET /v1/memory/review/history |
memory:read |
Every review decision made. |
POST /v1/memory/review/{id}/resolve |
memory:write |
Resolve a conflict by applying a correction: correctionId and a reason. |
POST /v1/memory/review/{id}/dismiss |
memory:write |
Dismiss an item, with a reason. |
Recommendations
Self-improvement's proposed changes to a task. See Self-improvement.
| Call | Scope | What it does |
|---|---|---|
GET /v1/recommendations |
recommendations:read |
The recommendations waiting for a decision; taskId narrows them. With view=decided, those decided in the last 60 days. |
GET /v1/recommendations/{id} |
recommendations:read |
One recommendation, in full. |
POST /v1/recommendations/{id}/decision |
recommendations:write |
approve or decline, with a reason to decline. Takes an idempotencyKey. |
Spend
Caps on what runs may cost, and today's spend. See Spend and models.
| Call | Scope | What it does |
|---|---|---|
GET /v1/spend |
spend:read |
Today's spend and runs, and every cap. |
PATCH /v1/spend/caps |
spend:write |
Set the cap on one layer and layerId. Raising a cap queues paused runs again. |
PATCH /v1/spend/enabled |
spend:write |
Turn spend limits on or off: { "enabled": false }. |
Models
Your model connections and the tiers they resolve to. See Spend and models.
| Call | Scope | What it does |
|---|---|---|
GET /v1/llm/connections |
llm:read |
Your model connections, without their keys. |
PATCH /v1/llm/connections/{id} |
llm:write |
Rename a connection, describe it, or set a Claude login's plan. |
GET /v1/llm/connections/{id}/usage |
llm:read |
A connection's usage. |
GET /v1/llm/bindings |
llm:read |
Whether a model key is connected, for the enterprise or, with layer=member and layerId, one member. |
POST /v1/llm/bindings |
llm:write |
Connect a key: apiKey, and provider (openrouter, the default, or claude). layer and layerId connect it for one member. |
DELETE /v1/llm/bindings |
llm:write |
Remove a key, named by provider, layer and layerId in the query. |
POST /v1/llm/claude/oauth/start, …/complete |
llm:write |
Connect a Claude login: start returns the address to sign in at, and complete takes the code and state it gives back. |
GET /v1/llm/tiers |
llm:read |
Which model each tier runs, per provider. |
POST /v1/llm/tiers/override |
llm:write |
Point a tier at another model the provider offers: provider, tier, model. |
GET /v1/llm/models |
llm:read |
The models your connections offer, for a task's exact model. |
Tools
The systems your members reach, and the connections that let them. See Tools.
| Call | Scope | What it does |
|---|---|---|
GET /v1/tools/bindings |
tools:read |
Your tool connections, without their secrets. layer and layerId narrow them. |
POST /v1/tools/bindings |
tools:write |
Connect a tool: an MCP server's address and token, or for a system a member operates in a browser, its sites and start page. |
PATCH /v1/tools/bindings/{id} |
tools:write |
Change a connection, or move it to another layer. Only the CEO may change its mustGate list (the tools a task must gate by name). |
DELETE /v1/tools/bindings/{id} |
tools:write |
Remove it. |
GET /v1/tools/bindings/{id}/sign-ins |
tools:read |
The sign-ins members have saved on a browser connection's sites. |
DELETE /v1/tools/bindings/{id}/sign-ins/{memberId} |
tools:write |
Forget a member's saved sign-in, on one site or all of them. |
GET /v1/tools/oauth/redirect-uri |
tools:read |
The redirect address to register with a provider for OAuth. |
POST /v1/tools/oauth/start |
tools:write |
Start connecting a tool by OAuth. It finishes in the browser of the person who started it, signed in to the portal, so start it there. |
A token connects tools on a team, member, role or task. It cannot connect, change or remove a connection on the
enterprise itself (403 ceo_bind_only).
Teams
A charter, a lead, and the members on it. See Teams and charters.
| Call | Scope | What it does |
|---|---|---|
GET /v1/teams |
teams:read |
Every team. |
POST /v1/teams |
teams:write |
Create one: name, and optionally slug, charter, leadMemberId and concurrentRunLimit. |
GET /v1/teams/{id} |
teams:read |
One team. |
PATCH /v1/teams/{id} |
teams:write |
Change its name, charter, lead or concurrent-run limit. |
DELETE /v1/teams/{id} |
teams:write |
Delete it. Your last team cannot be deleted. |
POST /v1/teams/{id}/members |
teams:write |
Put a member on the team: memberId, and optionally roleId. |
DELETE /v1/teams/{id}/members/{memberId} |
teams:write |
Take a member off it. |
Members
The AI team members, and their inboxes. See Members and inboxes.
| Call | Scope | What it does |
|---|---|---|
GET /v1/members |
members:read |
Every member. |
POST /v1/members |
members:write |
Create one: name, and optionally email and persona. |
GET /v1/members/{id} |
members:read |
One member. |
PATCH /v1/members/{id} |
members:write |
Change their name, email or persona. |
GET /v1/members/{id}/avatar |
members:read |
Their picture, as an image. |
PUT /v1/members/{id}/avatar |
members:write |
Set it: { "dataUrl": "data:image/png;base64,…" }. |
DELETE /v1/members/{id}/avatar |
members:write |
Remove it. |
POST /v1/members/{id}/roles |
members:write |
Give them a role: { "roleId": "…" }. |
DELETE /v1/members/{id}/roles/{roleId} |
members:write |
Take a role away. |
GET /v1/members/{id}/emails |
members:read |
Their inbox, a page at a time. unreadOnly=true for unread mail only. |
GET /v1/members/{id}/emails/{emailId} |
members:read |
One email. Reading it marks it read. |
GET /v1/members/{id}/emails/{emailId}/attachments/{attachmentId} |
members:read |
An attachment, as the file. |
Roles
A job: who holds it, and the tasks it runs. See Roles.
| Call | Scope | What it does |
|---|---|---|
GET /v1/roles |
roles:read |
Every role. |
POST /v1/roles |
roles:write |
Create one: name, and optionally slug and teamId. |
GET /v1/roles/{id} |
roles:read |
One role, its holders and its tasks. |
POST /v1/roles/{id}/members |
roles:write |
Give the role to a member: { "memberId": "…" }. |
DELETE /v1/roles/{id}/members/{memberId} |
roles:write |
Take it from them. |
POST /v1/roles/{id}/tasks |
roles:write |
Point a task at the role: { "taskId": "…" }. Its runs then go to the role's holders on the task's team. This publishes no new version. |
DELETE /v1/roles/{id}/tasks/{taskId} |
roles:write |
Stop the role running it. |
The org
Everything at once: the shape the portal's map draws. See Enterprise.
| Call | Scope | What it does |
|---|---|---|
GET /v1/orgs |
orgs:read |
Your whole organisation as one tree: teams, their members, the roles they hold, and the tasks of each. |
Enterprise settings
Settings that belong to the whole enterprise. See Enterprise.
| Call | Scope | What it does |
|---|---|---|
GET /v1/enterprise/webhook-secret |
enterprise:read |
Which webhook secret is in use and since when: its last characters, never the secret. |
POST /v1/enterprise/webhook-secret/rotate |
enterprise:write |
A new webhook secret, in this response only. The old one stops working at once. |
PUT /v1/enterprise/avatar |
enterprise:write |
Set the enterprise's picture: { "dataUrl": "…" }. |
DELETE /v1/enterprise/avatar |
enterprise:write |
Remove it. |
GET /v1/enterprise/concurrency |
enterprise:read |
How many runs may run at once. |
PATCH /v1/enterprise/concurrency |
enterprise:write |
Change it: { "concurrentRunLimit": 3 }. |
GET /v1/enterprise/chat-model-tier |
enterprise:read |
The model tier chats run on. |
PATCH /v1/enterprise/chat-model-tier |
enterprise:write |
Change it: { "chatModelTier": "mid" }. |
GET /v1/enterprise/chat-memory-depth |
enterprise:read |
How much of memory a chat reply reads, and the depths to choose from. |
PATCH /v1/enterprise/chat-memory-depth |
enterprise:write |
Change it: { "chatMemoryDepth": "large" }. |
GET /v1/enterprise/metrics |
enterprise:read |
The company's own metrics, the ones that belong to no single team. |
PATCH /v1/enterprise/metrics |
enterprise:write |
Set them: { "metrics": ["…"] }. |
No token can manage API tokens, whatever enterprise:write would otherwise reach: see Portal only.
Catalogue
The tasks and roles you can take into your enterprise. See Task directory.
| Call | Scope | What it does |
|---|---|---|
GET /v1/catalog/tasks |
catalog:read |
The catalogue, a page at a time. |
GET /v1/catalog/tasks/{id} |
catalog:read |
One task in it. |
POST /v1/catalog/tasks/{id}/clone |
catalog:write |
Install it, linked to the original: { "teamId": "…" }. It keeps the original's role. |
POST /v1/catalog/tasks/{id}/copy |
catalog:write |
Copy it as your own task: teamId, name and slug, and optionally assigneeRole, which is the original's unless you send one. |
GET /v1/catalog/roles |
catalog:read |
The catalogue's public roles, a page at a time, each with the public tasks on it. |
GET /v1/catalog/roles/{id} |
catalog:read |
One role and the public tasks on it. |
POST /v1/catalog/roles/{id}/clone |
catalog:write |
Install the role and every task on it, linked to the originals, in one go: { "teamId": "…" }. A role you already have with that slug is reused. Deprecated tasks are skipped. If you already have a task with one of the slugs, nothing is installed and the 409 lists those slugs. |
Webhooks
What your enterprise's webhooks received, and replaying it.
| Call | Scope | What it does |
|---|---|---|
GET /v1/webhooks |
webhooks:read |
Deliveries, a page at a time. |
GET /v1/webhooks/{id} |
webhooks:read |
One delivery: its request, response, and what followed. |
POST /v1/webhooks/{id}/replay |
webhooks:write |
Replay it. Send an idempotencyKey. |
Without a token
| Call | What it does |
|---|---|
GET /v1/health |
Whether the API is up, and the version it runs. |
POST /v1/webhooks/{enterprise}/tasks/{task} |
Start a run of a task, named by its slug. Authenticated by your webhook secret. See Webhooks. |
POST /v1/webhooks/{enterprise}/gates/{gateId} |
Decide a gate. Authenticated by your webhook secret. |
Portal only
These belong to a person signed in to the portal, not to a credential. No API token can use them, whatever its scopes:
| Routes | What they are | A token is refused with |
|---|---|---|
/v1/enterprise/api-tokens |
Creating, rotating, changing and revoking API tokens. | 403 api_token_cannot_manage_tokens |
/v1/enterprise/connections |
Apps connected to your enterprise, and revoking them. | 403 api_token_cannot_manage_connections |
/v1/users |
The people in your enterprise and what each may reach. Owners only. | 403 api_token_scope |
/v1/enterprises |
Creating an enterprise, and the pictures of the enterprises a person belongs to. | 403 api_token_scope |
/v1/auth/me, /v1/auth/enterprise |
Who is signed in, and which enterprise their session is in. | 403 api_token_scope |
/v1/consent/enterprises, …/members, …/approve, …/decline |
The screen where a person connects an app to an enterprise. | 403 api_token_scope |
A token with no enterprise scope is refused api_token_scope on the first two, before it gets that far. Signing
in and out (the rest of /v1/auth) happens in a browser, with a session a token does not have.