Skip to content

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.

json
{
  "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: true is safe to retry with exponential backoff. Add jitter so a fleet of clients does not synchronize.
  • retryable: false will keep failing until something changes. Surface it rather than looping.

Request and validation

CodeMeaning
INVALID_REQUESTThe body or query failed validation. details names the field.
INVALID_CURSORThe pagination cursor is malformed or expired. Restart from the first page.

Authentication and identity

CodeMeaning
TOKEN_INVALIDThe bearer token is not recognized.
TOKEN_EXPIREDThe token has expired. Refresh it or run the device flow again.
TOKEN_REVOKEDThe token was revoked, by regenerating or deleting an access token, or by signing out everywhere.
ANONYMOUS_NOT_ALLOWEDThis endpoint needs an authenticated caller.
EMAIL_NOT_VERIFIEDThe account's email is not yet verified.
ACCOUNT_SELECTION_INVALIDThe 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_INVALIDThe selection is not one this credential may act on, such as a company token asked to act personal.
ACCOUNT_NOT_MEMBERThe caller is not a member of that account.
ACCOUNT_NOT_FOUNDNo such account.

Permissions and quota

CodeMeaning
PERMISSION_DENIEDThe account's role does not permit this action.
PLAN_LIMIT_REACHEDThe 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_ALLOWEDThe active team's role does not permit this way of reaching the API. See OAuth device flow.
DOMAIN_LOCKEDThe caller's email domain is claimed by a company and the active account is not that company.
INSUFFICIENT_BALANCEThe account does not have enough tokens.
TOKEN_LIMITThe account hit its configured token ceiling.
TOKEN_COOLDOWNThe account is in a spending cooldown.

Not found

CodeMeaning
TOOL_NOT_FOUNDNo tool with that id, or it is not visible to this caller.
TOOL_TAG_NOT_FOUNDNo tool tag with that id.
BOARD_NOT_FOUNDNo board with that id, or it is not visible to this caller.
NODE_NOT_FOUNDNo node with that id on that board.
LIBRARY_ITEM_NOT_FOUNDNo generation with that id, or it is not visible to this caller.
UPLOAD_NOT_FOUNDNo upload with that id, or it has been deleted.
REQUEST_NOT_FOUNDNo run with that request_id.
LIBRARY_REF_NOT_FOUNDA 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

CodeMeaning
TOOL_SCHEMA_STALEThe tool changed after you fetched it. details.expected_tool_fields_hash carries the live value. Re-fetch the tool and rebuild.
NUM_RESULTS_LIMITnum_results exceeds what the tool or the account's role permits.
ACTIVE_RUN_CAPToo many runs already in flight for this identity. Wait for one to finish.
IDEMPOTENCY_KEY_CONFLICTThe Idempotency-Key was reused with a different body. Use a fresh key.
CONTENT_POLICY_VIOLATIONThe request was blocked. Do not retry it unchanged.
NSFWA result was withheld for content reasons. The run itself completed.
PROVIDER_FAILUREThe upstream model provider failed. Retryable.
TOOL_NOT_RUNNABLE_V1The tool needs a MODEL input, which this API cannot supply yet. Pick a different tool.

Inputs and uploads

CodeMeaning
TOO_MANY_INPUT_FILESMore than 12 files across multipart parts and UPLOAD_REF / LIBRARY_REF references combined.
UPLOAD_TOO_LARGEA file exceeds the 50 MB per-file limit.
UNSUPPORTED_MEDIA_TYPEThe file's type is not accepted.
METADATA_TOO_LARGEmetadata exceeds 8 KB serialized.
INVALID_WEBHOOK_URLwebhook_url is not a public HTTPS URL. See Webhooks.

Concurrent edits

CodeMeaning
BOARD_CHANGEDThe 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

CodeMeaning
AUTHORIZATION_PENDINGExpected. The user has not finished approving yet. Keep polling.
SLOW_DOWNExpected. You are polling too fast. Increase your interval.
DEVICE_CODE_NOT_FOUNDThe device code is unknown. Restart the flow.
DEVICE_CODE_EXPIREDThe device code expired before approval. Restart the flow.

Infrastructure

CodeMeaning
INTERNAL_ERRORSomething failed on our side. Retryable with backoff.
UPSTREAM_UNAVAILABLEA dependency was unavailable. Retryable with backoff.
RATE_LIMITEDYou 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.

View as Markdown