Every error code, explained.
Every failure on the VoiceLabs API is an application/problem+json document carrying a stable code. That is the field to branch on: several problems share a status, and detail is prose written for humans that may be reworded. Each code below has its own page — the same URL the type member of the response points at.
| CODE | HTTP | WHAT IT MEANS |
|---|---|---|
| invalid_request | 400 | The request failed schema validation before any work happened; detail names the field. |
| unauthorized | 401 | No usable credential was presented, so VoiceLabs could not identify the caller. |
| insufficient_scope | 403 | The key is valid but was minted without the scope this operation requires. |
| feature_not_enabled | 403 | The account's plan does not include this capability — not a spent allowance. |
| not_found | 404 | No resource with that id exists for this account. |
| method_not_allowed | 405 | The path exists, but not for this HTTP method; Allow names the one it takes. |
| idempotency_key_in_progress | 409 | The first request carrying this Idempotency-Key is still running. |
| idempotency_key_reused | 422 | The same Idempotency-Key came back with a different request body. |
| rate_limit_exceeded | 429 | This key sent too many requests in the current window; the ceiling clears itself. |
| quota_exhausted | 429 | The account's monthly audio allowance is spent; only time or an upgrade clears it. |
| upstream_error | 502 | The generation service could not answer — a VoiceLabs-side failure, not your request. |
| internal_error | 500 | An unexpected failure inside VoiceLabs, already reported to our error tracking. |
| service_unavailable | 503 | A dependency was briefly unreachable, so the request was refused rather than guessed. |
Two pairs are worth keeping apart, because they share a status and call for opposite client behaviour. rate_limit_exceeded clears itself and should be backed off; quota_exhausted will not clear until the period turns or the plan changes, so a retry loop only wastes requests. Likewise insufficient_scope is fixed by minting a different key, while feature_not_enabled is fixed by changing the plan.
The full contract — operations, schemas, and the statuses each one can return — lives in the generated OpenAPI document.