Rate limits & errors
Rate limits
Each API key is rate-limited independently. Your default per-minute limit is set by your plan; you can also set a tighter per-key limit when you create a key (see Authentication).
When you exceed the limit, the API responds with 429 Too Many Requests. Back
off and retry — an exponential backoff starting around 1s works well. Voice
generation is compute-heavy, so prefer concurrency limits in your client over
firing large bursts.
Error format
Voice endpoints return FastAPI's error envelope — a JSON object with a single
detail string — alongside the HTTP status code:
{ "detail": "VocaBusta is not active for this account. Manage it in Billing." }
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Bad request — empty audio/video, invalid segments/voice_map JSON, or unsupported target_language. | Fix the request; don't retry as-is. |
401 | Authentication failed — missing or invalid key. | Check the Authorization header. |
403 | VocaBusta isn't active on the account. | Activate VocaBusta in Billing. |
404 | Not found — unknown voice or history item. | Verify the id. |
429 | Rate limit exceeded. | Back off and retry. |
500 | Unexpected server error. | Retry; if it persists, report it. |
502 | The voice/GPU engine was unreachable (Pod TTS/STT unavailable, dubbing failed). | Transient — retry with backoff. |
503 | A dependency is unavailable — the subscription service, or the GPU engine isn't configured for dubbing. | Retry shortly. |
Retry guidance
- Retry
429,500,502,503with exponential backoff + jitter. - Do not retry
400,401,403,404without changing the request. - Long jobs — dubbing analyze/render are async. Don't treat a slow poll as a
failure; keep polling
GET /voice/dub/jobs/{job_id}untilstatusisdoneorerror. See Dubbing.
History
Every generation is recorded to your account history:
GET /voice/history?limit=50&offset=0&feature=tts— most recent first; filter byfeature(tts|stt|clone|dub).DELETE /voice/history/{item_id}— remove one item.