Every call that fails answers in the same shape:
{
"ok": false,
"error": {
"code": "insufficient_scope",
"message": "This API key is missing the required 'lists:read' scope (read your Lists and their rows, and download them).",
"scope": "lists:read"
}
}codeis short and never changes. Write your code against it.messageis one plain sentence for a person to read. Its words may change.- Some codes add a field, such as
scope,limit,resets_in_secondsorcurrent.
Every answer has an X-Request-Id header, even a failed one. Tell us that id if you ask for help with a call.
| Status | Code | What it means | What to do |
|---|---|---|---|
401 | missing_or_malformed_key | No key was sent, or the header is not Authorization: Bearer <key>. | Send the header with the word Bearer, a space, then the whole key. |
401 | invalid_key | The key is not known. It may be revoked, or copied wrong. | Check you copied the whole key. Make a new key if it was revoked. |
403 | insufficient_scope | The key does not have the scope this call needs. error.scope names it. | Make a key with that scope. A key's scopes cannot be changed after it is made. |
403 | person_required | The call tried to decide a change the assistant proposed. Only a person in the app can. | Open the link in the app and decide there. |
404 | not_found | Nothing with that id exists, or it belongs to another account. | Check the id. Ids come from a list or read call. |
409 | revision_conflict | Someone changed the work after you read it. error.current holds the newer version. | Read error.current, make your change to it, and send it again. |
409 | step_changed | That step changed after you read it. | Read the plan again, then send the change. |
409 | idempotency_conflict | You sent an Idempotency-Key you used before, with a different body. | Use a new key for a new request. Reuse a key only to retry the same request. |
409 | conversation_busy | The assistant is still answering in that conversation. | Wait for that answer, then ask again. |
409 | paused | Assistant work is paused for now. Nothing is wrong with your call. | Try again later. |
422 | invalid_query | A query parameter did not make sense, such as a bad date. | Read the message, fix the parameter, and send it again. |
422 | invalid_request | The body did not make sense, or it has a field the route does not take. | Read the message, fix the body, and send it again. |
422 | thread_too_long | The conversation is too long to carry on. | Start a new conversation. |
429 | rate_limited | The key made too many calls. | Wait for the seconds in the Retry-After header, then try again. |
429 | budget_exhausted | The assistant has used all it may spend today. | Try again after the Retry-After header's seconds. |
503 | database_unavailable | The API cannot reach its data right now. | Try again in a little while. |
503 | model_unavailable | The assistant could not answer right now. | Try again in a little while. |
A call that changes work takes an Idempotency-Key header. Send the same key and the same body to retry, and the work is done once, not twice.
Retry a 429 or a 503 after a wait. Do not retry a 401, 403, 404 or 422 without a change; it fails the same way again.