Skip to main content
All errors follow a consistent JSON format with a machine-readable code and human-readable message.

Error response format

{
  "error": {
    "code": "validation_error",
    "message": "keyword: Required",
    "details": { ... },
    "request_id": "req_abc123"
  }
}
FieldDescription
codeMachine-readable error code (see table below)
messageHuman-readable explanation
detailsAdditional context (optional)
request_idUnique request identifier for support (optional)
Always include the request_id when contacting support about a failed request. It allows the team to trace the exact request through the system.

Error Handling Decision Tree

Use this diagram to determine the correct recovery strategy for each error class:
Do not retry 4xx errors (except 429). These indicate a problem with the request itself — retrying the same request will always fail. Fix the issue first.

HTTP status codes

StatusMeaning
200Request succeeded
201Resource created
202Async operation accepted and started
204Deleted (no response body)
400Invalid request parameters
401Authentication failed
403Authenticated but lacking permissions
404Resource not found or not accessible
409Idempotency conflict
429Rate limit exceeded
500Server error

Error codes

CodeStatusDescription
validation_error400Request body or parameters failed validation
unauthorized401Missing or invalid API key
key_expired401API key has expired
key_revoked401API key has been revoked
forbidden403Key lacks the required scope
not_found404Resource does not exist or is not accessible to this key
idempotency_conflict409Same idempotency key used with different parameters
rate_limit_exceeded429Too many requests
internal_error500Unexpected server error
For 429 errors, see the Rate Limiting guide for retry logic examples with exponential backoff.

Handling errors

const response = await fetch(url, { headers });

if (!response.ok) {
  const { error } = await response.json();

  switch (error.code) {
    case "validation_error":
      console.error("Bad request:", error.message);
      break;
    case "rate_limit_exceeded": {
      const retryAfter = response.headers.get("Retry-After");
      await new Promise((r) => setTimeout(r, Number(retryAfter) * 1000));
      break;
    }
    case "unauthorized":
    case "key_expired":
    case "key_revoked":
      console.error("Auth issue:", error.message);
      break;
    default:
      console.error("API error:", error.code, error.message);
  }
}
Last modified on March 1, 2026