Error Response Format
All API errors return a consistent JSON structure with an error message and HTTP status code. Some errors include additional fields like retry_after or details.
Error response shape
json
{
"error": "Character limit exceeded for your plan.",
"code": 429,
"retry_after": 30,
"details": {
"characters_used": 500000,
"characters_limit": 500000
}
}HTTP Status Codes
The API uses standard HTTP status codes to indicate success or failure.
- 200 OK — Request succeeded.
- 201 Created — Resource created successfully (e.g., new voice, new API key).
- 400 Bad Request — Invalid parameters or missing required fields. Check the error message for details.
- 401 Unauthorized — Missing or invalid API key. Ensure your Authorization header is correct.
- 403 Forbidden — Your plan does not include this feature. Upgrade at /pricing.
- 404 Not Found — The requested resource does not exist.
- 409 Conflict — Resource already exists (e.g., duplicate voice name).
- 422 Unprocessable Entity — Valid JSON but invalid data (e.g., text too long, invalid voice ID).
- 429 Too Many Requests — Rate limit exceeded. Check the Retry-After header.
- 500 Internal Server Error — Something went wrong on our end. Try again or contact support.
- 503 Service Unavailable — System is temporarily overloaded or under maintenance.
Common Errors
These are the most frequently encountered errors and how to resolve them.
Missing API key
json
{
"error": "Missing or invalid API key. Include 'Authorization: Bearer origin_sk_...' header.",
"code": 401
}Character limit exceeded
json
{
"error": "Character limit exceeded for your plan.",
"code": 429,
"details": {
"characters_used": 500000,
"characters_limit": 500000,
"resets_at": "2026-03-01T00:00:00Z"
}
}Invalid voice ID
json
{
"error": "Voice not found: voice_nonexistent",
"code": 404
}Text too long
json
{
"error": "Text exceeds maximum length of 200 characters for demo endpoint.",
"code": 422,
"details": {
"length": 350,
"max_length": 200
}
}Rate Limits
Rate limits are applied per API key. When you exceed your limit, the API returns 429 with a Retry-After header indicating how many seconds to wait.
Rate limit headers
bash
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1707307260
Retry-After: 30
Content-Type: application/jsonRetry Logic
For production applications, implement retry logic with exponential backoff. Only retry on transient errors (429, 500, 503). Do not retry client errors (400, 401, 403, 404, 422).
- Always respect the Retry-After header when present — it's more accurate than exponential backoff for 429 errors.
- Add jitter to your backoff delays to avoid thundering herd issues.
- Log retry attempts for observability.
Exponential backoff
javascript
async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
const status = error.status;
const isRetryable = [429, 500, 503].includes(status);
if (!isRetryable || i === maxRetries - 1) throw error;
const delay = Math.min(1000 * Math.pow(2, i), 30000);
await new Promise(r => setTimeout(r, delay));
}
}
}