Reference
HTTP API and errors
The console, CLI, MCP server and SDK all use this versioned API. Prefer the typed SDK client over hand-written requests.
Authentication
- Owner session
- Browser or CLI management session. Manages devices, Agent access, approvals and settings. Changes must come from the deployment origin.
- Agent credential
- Revocable Bearer token bound to one Agent access. It can only call the tools, folders and devices in that grant.
- Device identity
- Ed25519 or Android Keystore P-256 signatures with a timestamp and one-time nonce. Not accepted on owner or Agent routes.
Main endpoints
| Method | Path | Caller | Purpose |
|---|---|---|---|
GET | /api/v1/me | Owner or Agent | Current identity and scope. |
GET | /api/v1/nodes | Owner | Paired devices and capabilities. |
POST | /api/v1/pairing-codes | Owner | Create a one-time pairing code. |
GET · POST | /api/v1/grants | Owner | List or create Agent access. |
PATCH · DELETE | /api/v1/grants/:grantId | Owner | Update (with revision) or delete Agent access. |
POST | /api/v1/invocations | Agent | Submit a tool call. |
GET | /api/v1/invocations/:invocationId | Owner or Agent | Follow a call through approval and dispatch. |
GET | /api/v1/tasks/:jobId | Agent | Task state or final result. |
POST | /api/v1/tasks/:jobId/cancel | Agent | Cancel a running task. |
GET | /api/v1/approvals | Owner | Pending or resolved approvals (cursor paging). |
GET | /api/v1/audit | Owner | Activity records (cursor paging). |
Approvals and audit page newest-first: pass limit (1–100) and the returned nextCursor as cursor.
Invocation
Official clients fill identity fields from the Agent credential. Paths must stay inside the grant; changing tools also need an idempotency key.
JSON
{
"schemaVersion": "0.1",
"invocationId": "inv_example001",
"attemptId": "att_example001",
"accountId": "acct_example001",
"actor": { "type": "agent", "id": "actor_example001" },
"target": { "nodeId": "node_example001" },
"authorization": { "grantId": "grant_example001", "rootIds": ["root_workspace001"] },
"tool": "file.read",
"args": { "path": "/Users/me/work/README.md" },
"issuedAt": "2026-09-29T10:00:00.000Z",
"expiresAt": "2026-09-29T10:05:00.000Z",
"metadata": { "source": "sdk" }
}A 200 response can still carry denied, approval_required or offline in status. queued and running results include a jobId to follow.
Error codes
| Code | Retry | What to do |
|---|---|---|
invalid_request | No | Fix the arguments. |
expired | No | Submit a new call with a new deadline. |
denied | No | Review Agent access, device policy and local scope. |
approval_required | After approval | Approve before it expires. |
offline | Yes | Wait for the device to reconnect. |
conflict | Conditionally | Refresh; never overwrite a newer revision. |
lease_expired | Conditionally | Read the task state before creating new work. |
unknown_outcome | Never automatically | Check the device and receipt first. |
internal | When retryable | Back off and keep the same request identity. |
Never turn unknown_outcome into an automatic retry. The same idempotency key can recover a stored receipt; a new key can repeat the change.