Skip to main content
Agent management endpoints are called by humans (dashboard session) and by orchestrators (an organization API key) — never by the agents themselves. Agents interact through the MCP server. The org key needs the scope for what it’s doing: agents:read to list or read agents, agents:write for the mutations (create, budget policy, pause/resume, archive). A write-only key cannot list — the scopes are independent, not a hierarchy.
Orchestrators can drive most of these as MCP tools instead of REST — create, list, budget policy, pause/resume, archive — see the management band. Listing needs agents:read; the mutations need agents:write. Not everything on this page is machine-callable: PATCH /v1/agents/:id (name/description) and the key mint/revoke routes remain session-only and have no management tool — they fail even with agents:write.

Create agent

Creates an agent with a non-custodial crypto wallet, a spending policy, and (bundled) its first API key.
The response includes the agent and its API key. Store it immediately — you get one delivery. Precisely how “one delivery” works depends on the caller:
  • Dashboard session: the key is shown once and never again. If it’s lost, revoke and mint a new one.
  • Organization API key: the key is returned once, but a replay of the same idempotencyKey and payload re-delivers it for roughly 30 minutes — a deliberate recovery window for a lost response. After that window it is gone the same way, and the replay returns apiKey: null.
Machine callers must send idempotencyKey. Omitting it returns 400 IDEMPOTENCY_KEY_REQUIRED. Persist a stable, high-entropy value before you call: on any ambiguous failure (timeout, network error, code-less 5xx, 409 REQUEST_IN_PROGRESS, 409 ORG_NOT_READY, 503 CREATE_RETRYABLE) you replay the same key and payload to recover the committed agent. Without it, a lost response means an orphaned agent and an unrecoverable credential.
Key re-delivery is time-boxed to roughly 30 minutes — act on an ambiguous failure immediately. A replay only re-delivers the raw apiKey while that window is open. After it closes, the replay still returns the agent but with apiKey: null, mcpConfigBlock: null, and keyDelivery: "expired". Retry promptly and store the key the moment you receive it. Creation draws on the key’s daily quota; replaying an already-completed create is free.
keyDelivery: "expired" does NOT mean the key was never delivered — check your own records before acting on it. It means only that the response arrived after the ~30-minute delivery window — which can happen on a late replay or on the very first response of a slow create that spent long enough provisioning. If your original create response actually arrived, that key is still live and the agent is perfectly usable; the server cannot tell the two cases apart. So do not treat an expired result as proof the agent is stranded. Confirm from your own delivery records that no credential was ever stored, and only then treat it as unrecoverable — the undelivered credential is still the agent’s one active key, so a human must DELETE /v1/agents/:id/key before POST /v1/agents/:id/key (minting straight away returns 409 KEY_ALREADY_EXISTS). The machine alternative is the zombie-archive sequence — but note an expired result from a first response has not stamped the durable non-delivery proof the archive gate needs, so a direct archive_agent there returns 409 KEY_DELIVERY_UNPROVEN and you must replay the create (to stamp it) before archiving — and because that stamp is best-effort, retry the replay + archive a few times with backoff if the code recurs, escalating (not looping) if it persists. Archiving on the expired flag alone can destroy an agent whose key you are holding.

List agents

Returns the organization’s agents. Optional filters: projectId, teamId.

Update agent

The budget-policy endpoint updates budgetCents, autoApprovalThresholdCents, perTransactionLimitCents, dailySpendLimitCents, and hourly/daily velocity limits. It takes a version token from the last read for optimistic concurrency — a stale token returns 409 VERSION_CONFLICT, so re-read and retry rather than blind-writing.
Step-up applies to human callers. A session must re-verify (passkey or TOTP). An organization API key does not — minting the key was itself performed by a human under step-up, and that ceremony is what authorizes it, so a headless caller is never re-challenged. Reading the current policy via GET /v1/agents/:id/budget-policy requires agents:write for a key, because it is a write precondition.

Pause and resume

Pausing is instant and reversible — every payment is denied while paused, and the API key stays intact. See Agent Lifecycle.

API keys

One active key per agent. Minting for an archived agent returns 409 AGENT_ARCHIVED.

Archive agent

Terminal: revokes the key and detaches the wallet policy. Requires step-up auth for human callers. Archived agents cannot be reactivated.
Organization API keys are heavily restricted here. A key may archive only a zombie of its own making — an agent that key lineage created, whose bundled-key re-delivery window has closed, that never authenticated and has no activity, holds a zero balance, and whose keys no human has ever minted or revoked (any human key management permanently disqualifies the machine path — the agent is no longer a machine orphan). Note the server cannot prove the key was never delivered (only that it can no longer be re-delivered and was never used), so confirm from your own records before archiving.403 MACHINE_ARCHIVE_DENIED is terminal — a human must archive from the dashboard. But not every non-success is terminal. Two 409s are recoverable — KEY_STILL_DELIVERABLE (replay the create to recover the key and keep the agent) and KEY_DELIVERY_UNPROVEN — and so are 409 BALANCE_UNVERIFIABLE (balance couldn’t be confirmed zero; retry later) and a 200 carrying a non-empty walletsFailed array (the local archive committed but a wallet detach failed; re-issue the DELETE until it comes back empty). Full sequences on the management band.
For an emergency hard stop, pause the agent and revoke its API key. Everything halts immediately, and it’s fully reversible.