Full enumeration of 4xx and 5xx error codes returned by the REST API.
Error envelope
Every non-2xx response shares the same JSON shape:
{
"error": {
"code": "rate_limited",
"message": "Human-readable description.",
"param": "optional field name",
"retryAfterSec": 32,
"requestId": "req_01HSXXXX"
}
}
code — a stable machine-readable identifier. Switch on this in your client code.
message — for humans. Don't parse.
param — present on 422s when a specific field is at fault.
retryAfterSec — on 429 and select 503s.
requestId — always present. Include in support tickets.
400 — Bad Request
| Code |
Meaning |
bad_request |
Generic malformed request. Check the message. |
invalid_query_param |
A query parameter has an invalid value. |
cursor_mismatch |
Cursor was generated against a different filter set. |
cursor_expired |
Cursor older than 24 hours. Restart pagination. |
malformed_json |
Request body is not valid JSON. |
401 — Unauthorized
| Code |
Meaning |
missing_auth |
No Authorization header. |
invalid_key |
Bearer token doesn't match a known key. |
revoked_key |
Key was revoked. Create a new one. |
expired_key |
Test-mode keys can have an explicit expiry; this fires past it. |
403 — Forbidden
| Code |
Meaning |
scope_insufficient |
Token doesn't have the required scope (e.g. write on a read-only key). |
company_out_of_scope |
Token is scoped to a specific company; request was for a different one. |
tier_required |
Endpoint requires a higher plan tier (e.g. API access is Domination-only). |
feature_disabled |
Feature is disabled for your workspace by admin policy. |
404 — Not Found
| Code |
Meaning |
not_found |
Generic. The requested resource doesn't exist or isn't visible to your token. |
audit_not_found |
Audit id doesn't exist or has been purged. |
company_not_found |
Company id doesn't exist. |
content_not_found |
Content item id doesn't exist. |
409 — Conflict
| Code |
Meaning |
audit_in_progress |
Tried to start an audit while one is already running. Wait for it. |
stale_resource |
If-Match precondition failed. Re-fetch and retry. |
422 — Unprocessable Entity
| Code |
Meaning |
validation_error |
Generic field validation failure. param names the field. |
required |
Field is required and was missing. |
invalid_format |
Field exists but doesn't match expected format. |
length_out_of_range |
String / array length outside allowed bounds. |
429 — Too Many Requests
| Code |
Meaning |
rate_limited |
You exceeded the per-minute or per-day limit. See retryAfterSec. |
concurrent_limit |
Too many in-flight requests. Limit concurrency. |
500 — Server Error
| Code |
Meaning |
internal_error |
Something on our side failed. Include requestId in your bug report. |
502 / 503 / 504
Transient infrastructure issues. Retry with exponential backoff. We aim to publish status at /status.
| Code |
Meaning |
bad_gateway |
Upstream returned an unexpected response. |
service_unavailable |
Server overloaded or in maintenance. See retryAfterSec. |
gateway_timeout |
Request took longer than 60 seconds. |
Retry policy recommendations
| Code class |
Retry? |
Backoff |
| 400–422 |
No (fix the request) |
— |
| 429 |
Yes |
Respect retryAfterSec |
| 500 |
Cautious |
Exponential, 3 attempts max |
| 502 / 503 / 504 |
Yes |
Exponential with jitter |
Including request IDs in support
Every error response carries a requestId. Include it when filing a bug — we can find the request in our logs and tell you exactly what happened.
Was this article helpful?