Sign in
DocsErrors & Rate Limits

Errors & Limits

Error Envelope and Rate Limits

All failures use a consistent error object. Use status code + error.code to implement safe retry and fallback behavior.

Error envelope

REST failures return { "error": { ... } } with optional details payload.

jsonError shape9 lines
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Please retry shortly.",
    "details": {
      "retry_after": 12
    }
  }
}

Status and code mapping

HTTPCodeMeaning
400VALIDATION_ERRORInput shape or field values are invalid.
401UNAUTHORIZEDMissing, malformed, or expired API key.
403FORBIDDENKey revoked or not allowed for requested org resource.
404NOT_FOUNDResource id does not exist or is not accessible to the org.
412PRECONDITION_FAILEDAudio is unavailable for current resource state.
429RATE_LIMITEDRoute limit exceeded for current window.
500INTERNAL_ERRORUnexpected server error.

Rate limit rules

RouteLimitNotes
POST /api/v1/generations20 requests / 60 seconds429 responses include Retry-After in seconds.
POST /api/v1/voices5 requests / 60 secondsUse batching/queueing for bulk voice ingest.
GET /api/v1/*120 requests / 60 secondsCovers authenticated GET endpoints under /api/v1.

Backoff recommendation

On 429, respect Retry-After when present. On 5xx, use bounded exponential backoff with jitter and idempotent retry behavior.

Retry snippet

tsRetry on 4297 lines
const retryAfter = Number(response.headers.get("Retry-After") ?? "0");
const delay = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : 1000;

if (response.status === 429) {
  await new Promise((resolve) => setTimeout(resolve, delay));
  // retry request
}

Search documentation

Find pages, endpoints, and sections.