Developer Guide
Errors
Error model, status codes, and recommended handling.
CanalAPI returns errors in the same shape as OpenAI: a non-2xx HTTP status code plus a JSON body containing an error object.
{
"error": {
"message": "Invalid API key.",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}Status codes
| Status | Meaning | Typical cause |
|---|---|---|
| 400 | Bad Request | Malformed JSON, missing required fields, invalid parameters. |
| 401 | Unauthorized | Missing, malformed, or revoked API key. |
| 403 | Forbidden | Valid key but no access to the requested model or feature. |
| 404 | Not Found | Unknown endpoint or model. |
| 408 | Request Timeout | Client took too long to send the request. |
| 409 | Conflict | Idempotency or state conflict. |
| 413 | Payload Too Large | Request body or context exceeds limits. |
| 422 | Unprocessable Entity | Validation error on a structurally valid request. |
| 429 | Too Many Requests | Rate limit or quota exceeded. |
| 500 | Internal Server Error | Unexpected server-side error — safe to retry with backoff. |
| 502 / 503 / 504 | Bad Gateway / Service Unavailable / Gateway Timeout | Upstream provider problem — retry with backoff. |
Retryable vs non-retryable
- Retryable:
408,409(with care),429,500,502,503,504. - Not retryable without code change:
400,401,403,404,413,422.
Use exponential backoff with jitter (for example: 1s, 2s, 4s, 8s, max ~30s, plus ±25% jitter). Cap the number of retries (typically 5).
Reading error fields
error.message— human-readable description.error.type— broad category (for exampleinvalid_request_error,rate_limit_error).error.code— machine-readable code; use this for branching logic rather than parsing the message.
Reporting
When opening a support ticket, include the request ID (when returned in response headers) and the timestamp. This drastically shortens diagnosis time.