Skip to main content
Every error response — auth failures, validation problems, rate limits, internal hiccups — follows the same shape. There is no field that’s only present on some errors and not others.

The envelope

  • code — one of the codes in the table below. Treat this as the machine-readable identifier; key your client logic off it.
  • message — a human-readable explanation. Phrasing may evolve; don’t string-match on it.
  • request_id — quote this in support tickets. Logged on our side; lets us find your exact request.
  • docs_url — deep link to the troubleshooting page for this code.
Successful responses use a different envelope (data + pagination + meta); see Pagination for that shape.

All error codes

The set of codes is closed — you can write an exhaustive switch over them and trust we won’t add a new code without a version bump.

Handling errors

The minimum responsible client treats codes in three buckets:
  • 4xx that you fix in code. bad_request, invalid_cursor, unauthorized, forbidden, not_found. Don’t retry — your code or config is wrong, and retrying with the same input gets the same answer.
  • 4xx that you fix by waiting. rate_limit_exceeded, quota_exceeded. Respect Retry-After. See Rate limits for backoff strategy.
  • 5xx that you fix by retrying. internal_error, service_unavailable. Retry with exponential backoff and a cap (e.g., 5 attempts, then surface the failure).

When to involve support

Open a ticket when:
  • A 5xx recurs across multiple request_ids within a few minutes.
  • A 4xx doesn’t match what the API Reference describes for the endpoint.
  • A not_found is returned for a resource you can see exists in another endpoint’s response.
Always include the request_id from at least one failing call. Without it, support gets to triangulate from a heap of haystacks.