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.
curl -s https://api.albastov.com/v1/models -H "Authorization: Bearer abk_not_a_key"{"error": {"message": "The API key is unknown or revoked", "type": "invalid_request_error", "code": "invalid_api_key"}}| Field | Value |
|---|---|
code | Error code |
type | OpenAI error type |
message | Human-readable text |
param | Audio routes: the parameter at fault, or null |
| Other fields | Per code: model, state and retry_after_s on model_loading; job_id on queued |
Albastov shape
Every other route, the docs routes included, returns errors in the Albastov shape.
curl -s https://api.albastov.com/v1/media/voices -H "Authorization: Bearer abk_not_a_key"{"ok": false, "error": "invalid-key", "code": "invalid_key", "message": "unknown or revoked api key"}| Field | Value |
|---|---|
ok | false |
code | Error code |
message | Human-readable text |
error | code with hyphens for underscores (legacy; use code) |
param | The parameter at fault, when one is |
| Other fields | Per code, e.g. resets_at on budget-exhausted |
Codes appear exactly as each route returns them; some use hyphens (bad-param, too-large). Codes per route:
API reference.
Status codes
| Status | Meaning |
|---|---|
| 400 | Invalid request: a missing, unknown or malformed parameter |
| 401 | Missing, unknown or revoked key |
| 403 | Key without the scope the route needs, or account without access to the product |
| 404 | Unknown route, model, voice or job |
| 413 | Request body or file over its limit |
| 429 | Call, token, open-request or daily limit reached |
| 500 | Internal error |
| 502 | No reply from the model |
| 503 | Model loading, request queued, or service unavailable for now |
| 524 | Non-streamed request with no response within about 100 s |
Key errors
| Failure | Language model routes | Other routes |
|---|---|---|
No Authorization header | 401 missing_api_key | 401 unauthorized |
| Unknown or revoked key | 401 invalid_api_key | 401 invalid_key |
| Key without the route's scope | 403 insufficient_scope | 403 scope_missing |
| Account without access to the product | none | 403 account_cannot |
| Key over its calls per minute or per day | 429 rate_limited | 429 rate_limited |
A 401 on the language model routes carries WWW-Authenticate: Bearer. Language model routes are
GET /v1/models and POST /v1/chat/completions.
Plain-text errors
Two errors arrive as plain text, not JSON. Check Content-Type before parsing an error body as JSON.
| Status | Body | Cause |
|---|---|---|
| 403 | error code: 1010 | Default Python-urllib User-Agent; send a User-Agent header |
| 524 | error code: 524 | Non-streamed request with no response within about 100 s; send it with "stream": true |
Retries
| Status and code | Retry |
|---|---|
| 400, 401, 403, 404, 413 | No; fix the request or the key |
429 daily_limit, daily_tokens, budget-exhausted | After 00:00 UTC |
429 rate_limited | Within 60 s for the per-minute limit; the per-day limit frees calls over a rolling 24 hours |
| 429, other codes | After Retry-After, or after an open request or job ends |
| 500 | Once; then report the X-Request-Id |
| 502 | After 5 to 10 s |
| 503 | After Retry-After |
| 524 | No; stream the request |
Every limit and its code: Rate limits.