Errors
Status codes and the consistent error response shape.
Vocenza uses conventional HTTP status codes and returns a consistent JSON error
body. On the Realtime API, the same shape arrives as an
error event.
{
"error": {
"type": "invalid_request",
"message": "Field 'input' is required.",
"param": "input"
}
}Status codes
| Status | type | Meaning |
|---|---|---|
400 | invalid_request | A parameter is missing or malformed. |
401 | authentication_error | Missing or invalid API key. |
403 | permission_error | Key revoked, or model not enabled for the project. |
404 | not_found | Resource (voice, file, session) does not exist. |
413 | payload_too_large | Audio or text exceeds the size limit. |
429 | rate_limit | Too many requests — back off and retry. |
500 | server_error | Something failed on our side. Safe to retry. |
503 | overloaded | Temporary capacity issue. Retry with backoff. |
Retries
Retries are safe on 429, 500, 502, 503, and 504. Use exponential
backoff with jitter and cap attempts.
async function withRetry<T>(fn: () => Promise<T>, attempts = 4): Promise<T> {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (err) {
const status = (err as { status?: number }).status;
const retryable = status && [429, 500, 502, 503, 504].includes(status);
if (!retryable || i === attempts - 1) throw err;
await new Promise((r) => setTimeout(r, 2 ** i * 250 + Math.random() * 100));
}
}
throw new Error("unreachable");
}Respect Retry-After
On 429, honor the Retry-After response header when present — it tells you
exactly how long to wait before the next attempt.