API errors

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.

CODEHTTPWHAT IT MEANS
invalid_request400The request failed schema validation before any work happened; detail names the field.
unauthorized401No usable credential was presented, so VoiceLabs could not identify the caller.
insufficient_scope403The key is valid but was minted without the scope this operation requires.
feature_not_enabled403The account's plan does not include this capability — not a spent allowance.
not_found404No resource with that id exists for this account.
method_not_allowed405The path exists, but not for this HTTP method; Allow names the one it takes.
idempotency_key_in_progress409The first request carrying this Idempotency-Key is still running.
idempotency_key_reused422The same Idempotency-Key came back with a different request body.
rate_limit_exceeded429This key sent too many requests in the current window; the ceiling clears itself.
quota_exhausted429The account's monthly audio allowance is spent; only time or an upgrade clears it.
upstream_error502The generation service could not answer — a VoiceLabs-side failure, not your request.
internal_error500An unexpected failure inside VoiceLabs, already reported to our error tracking.
service_unavailable503A 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.