Skip to content

Errors

Error shapes, status codes, key errors and retry rules.

Every JSON error body carries a code and a message. Branch on the HTTP status and code; the message text may change.

OpenAI shape

POST /v1/chat/completions, GET /v1/models, POST /v1/audio/speech and POST /v1/audio/transcriptions return errors in the OpenAI shape. The OpenAI SDKs raise AuthenticationError, PermissionDeniedError, NotFoundError, RateLimitError and APIStatusError for these errors.

Shell
curl -s https://api.albastov.com/v1/models \
  -H "Authorization: Bearer abk_not_a_key"
Response
{
  "error": {
    "message": "The API key is unknown or revoked",
    "type": "invalid_request_error",
    "code": "invalid_api_key"
  }
}
FieldValue
codeError code
typeOpenAI error type
messageHuman-readable text
paramAudio routes: the parameter at fault, or null
Other fieldsPer code: model, state and retry_after_s on model_loading; job_id on the audio routes when a job exists

Albastar shape

Every other route, the docs routes included, returns errors in the Albastar shape.

Shell
curl -s https://api.albastov.com/v1/media/voices \
  -H "Authorization: Bearer abk_not_a_key"
Response
{
  "ok": false,
  "error": "invalid-key",
  "code": "invalid_key",
  "message": "unknown or revoked api key"
}
FieldValue
okfalse
codeError code
messageHuman-readable text
errorcode with hyphens for underscores (legacy; use code)
paramThe parameter at fault, when one is
Other fieldsPer code, e.g. resets_at on budget-exhausted

Codes appear exactly as each route returns them. Codes per route: the route's page under API reference.

Known issue, 2026-11-03: error codes mix snake_case and kebab-case, such as too_large on POST /v1/chat/completions and too-large on the media routes, or not_found on the docs routes and not-found on media jobs. Each route keeps its codes as listed on its page; a change to a code appears in the changelog first.

Status codes

StatusMeaning
400Invalid request: a missing, unknown or malformed parameter, or over the model's open requests per account
401Missing, unknown or revoked key
403Key without the scope the route needs, or account without access to the product
404Unknown route, model, voice or job
409A voice that is not ready, or an idempotency key used with another request
413Request body or file over its limit
415A body or file of a type the route does not take
422A voice the model needs is missing, a voice the model does not speak, a missing consent, or the account's saved-voice limit
429Call, token, open-request or daily limit reached
500Internal error
502No valid answer from the model, or a speech or transcription job that failed
503Model loading, request queued, a job past its queue timeout, or service unavailable for now
524Non-streamed request with no response within about 100 s

Key errors

LLM routes are GET /v1/models and POST /v1/chat/completions; other routes are every other route that needs a key.

FailureLLM routesOther routes
Unknown or revoked key401 invalid_api_key401 invalid_key
Key without the route's scope403 insufficient_scope403 scope_missing
Account without access to the productnone403 account_cannot
Key over its calls per minute or per day429 rate_limited429 rate_limited

A request without an Authorization header fails with 401 and a code per route family:

RoutesCode
GET /v1/models, POST /v1/chat/completionsmissing_api_key
POST /v1/audio/speech, POST /v1/audio/transcriptions, /v1/media/jobs, /v1/media/models, /v1/media/uploads, /v1/media/voicesunauthorized
POST /v1/events, POST /v1/events/batch, PATCH /v1/events/sources/selfpublish_key_required
GET /v1/events, GET /v1/events/sources, GET /v1/events/stream, POST and DELETE /v1/events/{id}/dismissunauthorized
GET /v1/events/infoevents_key_required

The docs, status and samples routes and GET /v1/events/docs need no key. POST /v1/events/hooks/in/{token} takes the token in its URL. A 401 on the LLM routes carries WWW-Authenticate: Bearer.

Plain-text errors

Two errors arrive as plain text, not JSON. Check Content-Type before parsing an error body as JSON.

StatusBodyCause
403error code: 1010A request with the default Python-urllib User-Agent; send a User-Agent header (API reference)
524error code: 524Non-streamed request with no response within about 100 s; send it with "stream": true

Retries

Status and codeRetry
400 too_many_parallel, parallel_unsupportedAfter one of the account's open requests on that model ends
409 voice_not_ready with status pendingAfter the voice's status is ready
400, other codes; 401, 403, 404, 409, 413, 415, 422No; fix the request or the key
429 daily_limit, daily_tokens, budget-exhaustedAfter 00:00 UTC
429 rate_limitedWithin 60 s for the per-minute limit; the per-day limit frees calls over a rolling 24 hours
429, other codesAfter Retry-After, or after an open request or job ends
500Once; then report the X-Request-Id
502After 5 to 10 s
503After Retry-After; device_offline carries no Retry-After: after 5 to 10 s
524No; stream the request

Every limit and its code: Rate limits.