Errors
Every error uses the same shape, with a stable code you can branch on.
Error shape
{
"error": {
"code": "pricing_not_configured",
"message": "Pricing has not been configured for this model."
}
}Branch on code, not on message — messages may be reworded for clarity, codes stay stable.
Error codes
| HTTP | Code | Meaning |
|---|---|---|
| 401 | auth_missing_or_malformed | Header missing or not in Bearer apl_... form. |
| 401 | auth_invalid | Unknown key. |
| 401 | auth_revoked | Key was revoked. |
| 401 | auth_expired | Key has expired. |
| 400 | invalid_request | Wrong types, missing fields, or out-of-range values. |
| 400 | unknown_model | The model does not exist. |
| 400 | capability_not_supported | The model cannot be used on this endpoint. |
| 402 | insufficient_balance | Not enough balance. |
| 404 | not_found | Not found, or the resource is not yours. |
| 429 | upstream_rate_limited | Rate limited. Retry later. |
| 502 | upstream_error | The provider failed. You are not charged. |
| 503 | pricing_not_configured | The model is implemented but not priced yet. Our side, not yours. |
| 503 | model_disabled | The model is disabled. |
| 503 | model_temporarily_unavailable | The upstream provider is not serving this model right now. Temporary; can clear on its own. |
| 504 | upstream_timeout | The provider did not respond in time. You are not charged. |
Retrying
Retry only on 429, 502 and 504. Back off 1s, 3s, 8s with jitter, at most 2–3 attempts. Do not retry the other 4xx codes — they will fail identically.
For video: once you have a job ID, do not retry the create request. Poll that job ID instead.