Error handling
Error codes and how to handle them
All error responses follow this format:
json
{
"error": {
"code": "machine_readable_code",
"message": "Human-readable description in English."
}
}Common codes
| Status | Code | Meaning | |
|---|---|---|---|
| 400 | invalid_request | — | Invalid body or malformed fields. |
| 401 | unauthorized | — | API key missing, invalid or revoked. |
| 402 | quota_exceeded | — | Not enough storage. |
| 403 | forbidden | — | Key lacks required scope. |
| 403 | plan_restricted | — | Feature requires a higher plan. |
| 404 | not_found | — | Resource does not exist or is not yours. |
| 429 | rate_limited | — | Too many requests. Respect Retry-After. |
| 500 | internal_error | — | Our fault. Retry with backoff. |
Retry policy
Retry recommendations by status:
- 4xx (except 429): DO NOT retry. The error is permanent until you change something (fix body, generate new key, buy more storage).
- 429: respect the Retry-After header. Implement exponential backoff.
- 5xx: retry with backoff (1s, 2s, 4s, 8s, 16s). If it persists >5 min, open a ticket.
Recommended: log the code (machine-readable) in your system, not the message. Messages are in English and may change; codes are stable.