Errors
Every error is actionable.
All 4xx/5xx responses use one envelope. There are no bare 403s.
json
{
"error": "forbidden",
"message": "This API key is missing the 'analysis_tab' permission.",
"userMessage": "This API key is not scoped for 'analysis_tab', which this endpoint requires.",
"suggestedAction": "Ask an org owner/admin to add 'analysis_tab' to the key's scope…",
"isRetryable": false,
"request_id": "req_8f2a1c9d4e5b6a7c8d9e0f12"
}The fields
| Field | Use it for |
|---|---|
error | A stable, machine-readable code to branch on. |
userMessage | Text safe to show an end user. |
suggestedAction | What to do to fix it. |
isRetryable | Whether retrying the same request may succeed. |
request_id | Quote this in a support request (also in the request-id header). |
Common cases
| Status | error | When |
|---|---|---|
| 400 | bad_request / missing_idempotency_key | Malformed body, or a write with no Idempotency-Key. |
| 401 | unauthorized / key_revoked | No valid key, or the key was revoked (states when). |
| 403 | forbidden / project_scope_forbidden | The key lacks the permission, or isn't scoped to the project. |
| 404 | not_found | The resource isn't visible to this key's org. |
| 409 | idempotency_in_progress | A same-key request is still being processed. |
| 413 | body_too_large | Inline file too large — use the large-file flow. |
| 422 | idempotency_conflict | Same Idempotency-Key, different body. |
| 429 | rate_limited | Too many requests — respect Retry-After. |