Errors
The native endpoints (/v1/tts, /v1/stt) return errors in one consistent
JSON structure. The compatible APIs re-wrap the same catalog
codes in their vendor’s envelope (OpenAI error.code, ElevenLabs
detail.status, Cartesia error_code), so everything on this page applies
there too.
Error response shape
{
"error": {
"code": "<error-code>",
"message": "<human-readable description>",
"request_id": "<unique request identifier>"
}
}code— machine-readable code. Use this field in your error-handling logic (notmessage, which may change).message— human-readable description intended for logs and debugging.request_id— include this when contacting support to help us trace the request.
Error catalog
unauthorized — HTTP 401
The API key is missing, malformed, invalid, revoked, or expired.
Common causes
- Authorization header is absent
- Bearer token does not start with the
rvl_live_prefix - Key was deleted from the dashboard or has expired
Recovery — Send Authorization: Bearer rvl_live_<your-key> and confirm
the key is active in your API Keys page.
{
"error": {
"code": "unauthorized",
"message": "Invalid API key format. Keys must start with 'rvl_live_'.",
"request_id": "req_01HXYZ..."
}
}forbidden — HTTP 403
The API key is valid but its scope does not permit this endpoint.
Common causes
- A
tts-onlykey calledPOST /v1/stt(or vice versa) - The key lacks the scope required by the route
Recovery — Use a key whose scope includes this endpoint, or create a new key with the required scope.
{
"error": {
"code": "forbidden",
"message": "API key scope does not permit this endpoint.",
"request_id": "req_01HXYZ..."
}
}validation_error — HTTP 400 / 413 / 415
The request body or file is invalid.
Common causes
- Unknown model name (400)
- Text exceeds the 500-character limit (400)
- Invalid
voice_id— not in the voice catalog (400) speedis outside the 0.5–2.0 range (400)- STT file exceeds 50 MB or the 30-minute duration cap (413, or 400 when the over-length duration is detected by probing)
- Unsupported or mismatched audio format (415)
Recovery — Check the error message for the specific field that failed validation. Consult the TTS API or STT API reference for allowed values.
{
"error": {
"code": "validation_error",
"message": "Unknown model 'nada-2.0'. Valid models: ['nada-1.0-flash-lite', 'nada-1.0-flash', 'nada-1.0-pro']",
"request_id": "req_01HXYZ..."
}
}model_rejected — HTTP 422
The upstream model rejected the request payload.
Common causes
- Input the model could not process
- Unsupported combination of parameters for the selected model
Recovery — Adjust the request per the message and retry. This is not retryable unchanged.
{
"error": {
"code": "model_rejected",
"message": "The model rejected the request.",
"request_id": "req_01HXYZ..."
}
}malware_detected — HTTP 422
The uploaded audio file failed GuardDuty malware scanning.
Common causes
- File contains malicious content
- File was tampered or corrupted in transit
Recovery — Do not retry with the same file. If you believe this is a false
positive, contact support with the request_id.
{
"error": {
"code": "malware_detected",
"message": "The uploaded file failed malware scanning.",
"request_id": "req_01HXYZ..."
}
}insufficient_balance — HTTP 402
The organization’s usage allowance is exhausted.
Common causes
- The available usage allowance has been fully consumed
Recovery — wait for your usage allowance to reset, or contact support to increase it.
{
"error": {
"code": "insufficient_balance",
"message": "Insufficient balance to complete this request.",
"request_id": "req_01HXYZ..."
}
}rate_limited — HTTP 429
A rate limit was exceeded — request count or usage units (audio-minutes) — in one of the active windows (per-minute and per-day, with per-model limits possible on top).
Common causes
- Too many requests in the current per-minute or per-day window
- The audio-minute (usage-unit) allowance for the window is used up
- A per-model limit tripped even though the overall limit still had room
- Burst traffic without backoff
Recovery — Honor the Retry-After header (seconds until the soonest
tripped limit resets), then retry with exponential backoff plus jitter. Do not
retry non-429 errors this way — only 429s are safe to retry unchanged. Note
that rejected (429) requests still count toward your request limits, so
hammering a tripped limit extends the outage. Watch the X-RateLimit-*
response headers (below) to stay under your limits; contact Revolab for a
higher tier.
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded.",
"request_id": "req_01HXYZ..."
}
}quota_exceeded — HTTP 429
The monthly quota for the requested model has been exhausted. This applies to the free models only — see Free allowances.
Common causes
- The 60-minute monthly allowance for a free model (
nada-1.0-flash-lite,aisyah-1.0-flash) is used up
Recovery — Wait for the quota to reset at the start of next month, or
switch to the equivalent paid model, which bills against your balance instead
of a monthly cap. Honor the Retry-After header.
{
"error": {
"code": "quota_exceeded",
"message": "Monthly quota for model 'nada-1.0-flash-lite' has been exhausted.",
"request_id": "req_01HXYZ..."
}
}concurrency_limit_exceeded — HTTP 429
Too many requests are in flight at once for your key.
Common causes
- More concurrent requests than your concurrency cap allows
Recovery — Reduce in-flight concurrency and retry after the Retry-After
delay.
{
"error": {
"code": "concurrency_limit_exceeded",
"message": "Too many concurrent requests. Retry shortly.",
"request_id": "req_01HXYZ..."
}
}endpoint_unavailable — HTTP 502
The upstream TTS or STT model endpoint returned an error or malformed audio.
Common causes
- Model server is temporarily overloaded
- TTS endpoint returned audio with an unparseable WAV header
- STT model returned an unexpected response format
Recovery — Retry after a short delay. If the issue persists, check the status page or contact support.
{
"error": {
"code": "endpoint_unavailable",
"message": "The upstream TTS service returned an unexpected response.",
"request_id": "req_01HXYZ..."
}
}voice_not_ready — HTTP 503
The requested voice is still enrolling and cannot synthesize yet.
Common causes
- A cloned voice is still processing after creation
Recovery — Wait until the voice finishes enrolling (check the Voices page), then retry.
{
"error": {
"code": "voice_not_ready",
"message": "Voice is not available yet.",
"request_id": "req_01HXYZ..."
}
}service_unavailable — HTTP 503
The TTS or STT service is under maintenance or its configuration is missing.
Common causes
- Planned maintenance window
- Endpoint configuration not yet provisioned in this region
Recovery — Wait and retry. Check the status page for maintenance windows.
{
"error": {
"code": "service_unavailable",
"message": "TTS service is temporarily unavailable.",
"request_id": "req_01HXYZ..."
}
}Rate limit headers
Rate-limited endpoints return two families of headers so your client can pace itself instead of discovering limits through 429s. The request family is always present; the units family appears when an audio-minute (usage-unit) limit applies to the request. Each family reports the tightest (soonest-limiting) window.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Request allowance in the tightest window |
X-RateLimit-Remaining | Requests left before a 429 |
X-RateLimit-Reset | Seconds until the request window resets |
X-RateLimit-Limit-Units | Audio-minute allowance in the tightest window |
X-RateLimit-Remaining-Units | Audio-minutes left before a 429 |
X-RateLimit-Reset-Units | Seconds until the unit window resets |
On a 429, Retry-After carries the seconds until the soonest tripped limit
resets — always prefer it over a fixed sleep.
FastAPI validation errors (422)
If the request body is structurally invalid (e.g., JSON parse failure or a
required field is missing), FastAPI returns a 422 with a detail array before
the gateway error contract is applied:
{
"detail": [
{
"loc": ["body", "text"],
"msg": "field required",
"type": "value_error.missing"
}
]
}This happens at the framework layer before the endpoint handler runs. Handle
it by checking for the presence of error vs detail in the response body.
Related
- TTS API — endpoint-specific status codes
- STT API — endpoint-specific status codes
- Authentication — fixing
unauthorizederrors - Rate Limits & Quotas — limit values and backoff guidance