Errors
The error envelope every failed request returns, and the stable error codes you can expect.
On this page
Every non-2xx response uses the same envelope, including validation failures and rate limiting. There is no second error format to handle.
{
"error": {
"code": "INVALID_CURSOR",
"message": "Cursor is not valid base64-encoded JSON.",
"retryable": false,
"details": {
"param": "cursor"
}
}
}details carries whatever structured context that specific code has to offer,
and it is omitted entirely when there is none. Read it per code rather than
expecting a fixed shape.
codestring- A stable machine-readable identifier. Branch on this, never on the message.
messagestring- Human-readable explanation. Wording may change at any time, so do not parse it.
retryableboolean- Whether retrying the identical request could plausibly succeed. When false, something must change first.
detailsobject- Additional context for the specific error, such as which field failed validation.
Retry behavior
Treat retryable as the signal for whether to try again.
retryable: trueis safe to retry with exponential backoff. Add jitter so a fleet of clients does not synchronize.retryable: falsewill keep failing until something changes. Surface it rather than looping.
Request and validation
| Code | Meaning |
|---|---|
INVALID_REQUEST | The body or query failed validation. details names the field. |
INVALID_CURSOR | The pagination cursor is malformed or expired. Restart from the first page. |
Authentication and identity
| Code | Meaning |
|---|---|
TOKEN_INVALID | The bearer token is not recognized. |
TOKEN_EXPIRED | The token has expired. Refresh it or run the device flow again. |
TOKEN_REVOKED | The token was revoked, by regenerating or deleting an access token, or by signing out everywhere. |
ANONYMOUS_NOT_ALLOWED | This endpoint needs an authenticated caller. |
EMAIL_NOT_VERIFIED | The account's email is not yet verified. |
ACCOUNT_SELECTION_INVALID | The team_id selection is malformed: an empty value, a list with blank entries, too many teams, or several IDs where the endpoint acts on one team. |
ACCOUNT_HEADER_INVALID | The selection is not one this credential may act on, such as a company token asked to act personal. |
ACCOUNT_NOT_MEMBER | The caller is not a member of that account. |
ACCOUNT_NOT_FOUND | No such account. |
Permissions and quota
| Code | Meaning |
|---|---|
PERMISSION_DENIED | The account's role does not permit this action. |
PLAN_LIMIT_REACHED | The account's plan caps something it has reached, such as the number of nodes on a board. The fix is a plan change, not a role change. details carries limit and current. |
PLUGIN_NOT_ALLOWED | The active team's role does not permit this way of reaching the API. See OAuth device flow. |
DOMAIN_LOCKED | The caller's email domain is claimed by a company and the active account is not that company. |
INSUFFICIENT_BALANCE | The account does not have enough tokens. |
TOKEN_LIMIT | The account hit its configured token ceiling. |
TOKEN_COOLDOWN | The account is in a spending cooldown. |
Not found
| Code | Meaning |
|---|---|
TOOL_NOT_FOUND | No tool with that id, or it is not visible to this caller. |
TOOL_TAG_NOT_FOUND | No tool tag with that id. |
BOARD_NOT_FOUND | No board with that id, or it is not visible to this caller. |
NODE_NOT_FOUND | No node with that id on that board. |
LIBRARY_ITEM_NOT_FOUND | No generation with that id, or it is not visible to this caller. |
UPLOAD_NOT_FOUND | No upload with that id, or it has been deleted. |
REQUEST_NOT_FOUND | No run with that request_id. |
LIBRARY_REF_NOT_FOUND | A LIBRARY_REF in inputs points at a generation that does not exist. details carries the field_key. |
A missing resource and a resource you cannot see return the same code, so absence never confirms that something exists.
Generation
| Code | Meaning |
|---|---|
TOOL_SCHEMA_STALE | The tool changed after you fetched it. details.expected_tool_fields_hash carries the live value. Re-fetch the tool and rebuild. |
NUM_RESULTS_LIMIT | num_results exceeds what the tool or the account's role permits. |
ACTIVE_RUN_CAP | Too many runs already in flight for this identity. Wait for one to finish. |
IDEMPOTENCY_KEY_CONFLICT | The Idempotency-Key was reused with a different body. Use a fresh key. |
CONTENT_POLICY_VIOLATION | The request was blocked. Do not retry it unchanged. |
NSFW | A result was withheld for content reasons. The run itself completed. |
PROVIDER_FAILURE | The upstream model provider failed. Retryable. |
TOOL_NOT_RUNNABLE_V1 | The tool needs a MODEL input, which this API cannot supply yet. Pick a different tool. |
Inputs and uploads
| Code | Meaning |
|---|---|
TOO_MANY_INPUT_FILES | More than 12 files across multipart parts and UPLOAD_REF / LIBRARY_REF references combined. |
UPLOAD_TOO_LARGE | A file exceeds the 50 MB per-file limit. |
UNSUPPORTED_MEDIA_TYPE | The file's type is not accepted. |
METADATA_TOO_LARGE | metadata exceeds 8 KB serialized. |
INVALID_WEBHOOK_URL | webhook_url is not a public HTTPS URL. See Webhooks. |
Concurrent edits
| Code | Meaning |
|---|---|
BOARD_CHANGED | The board was modified between your read and your write, so the order you sent no longer describes it. Re-read the board and reapply. |
Device code flow
| Code | Meaning |
|---|---|
AUTHORIZATION_PENDING | Expected. The user has not finished approving yet. Keep polling. |
SLOW_DOWN | Expected. You are polling too fast. Increase your interval. |
DEVICE_CODE_NOT_FOUND | The device code is unknown. Restart the flow. |
DEVICE_CODE_EXPIRED | The device code expired before approval. Restart the flow. |
Infrastructure
| Code | Meaning |
|---|---|
INTERNAL_ERROR | Something failed on our side. Retryable with backoff. |
UPSTREAM_UNAVAILABLE | A dependency was unavailable. Retryable with backoff. |
RATE_LIMITED | You exceeded a rate limit. See Rate limits. |
If one of the first two keeps coming back for the same request, backoff is not going to fix it. Send the endpoint, the code, and roughly when it happened to our support team.
