Errors and retries
Every error code, and whether to retry it.
Failures return JSON with a stable code, safe message, and retryable flag.
{ "status": "failed", "error": { "code": "UPSTREAM_FAILURE", "message": "All eligible execution backends failed.", "retryable": true }}| HTTP | Typical code | Retry guidance |
|---|---|---|
400 |
INVALID_REQUEST |
Fix the request |
400 |
FEATURE_NOT_ALLOWED |
Do not retry as-is. A requested feature is not enabled on your contract; remove it or ask to have it added |
401 |
AUTHENTICATION_FAILED |
Check or rotate the API key |
403 |
TARGET_NOT_ALLOWED |
This target is not permitted; contact support |
409 |
IDEMPOTENCY_CONFLICT |
Use the original payload or a new key |
429 |
RATE_LIMITED |
Wait for Retry-After, then retry with backoff |
502 |
TARGET_ERROR |
Do not retry. The target itself answered this way — typically 410, or 404 if your contract narrows billing to 2xx only — and your contract does not cover it. See X-Target-Status. You are not charged. A refusal such as 403 or 429 is handled internally by trying another route and surfaces as UPSTREAM_FAILURE if every route is refused. |
502 |
RESPONSE_TOO_LARGE |
Do not retry as-is. The response exceeded your contract’s size ceiling (the platform default, or your contract’s own lower or higher override, whichever applies). You are not charged. Every eligible backend was tried; a target this large will not fit under the same ceiling on a retry |
502 |
UPSTREAM_FAILURE |
Retry with exponential backoff and jitter |
503 |
NO_ELIGIBLE_ROUTE |
Retry later |
504 |
TIMEOUT |
Retry if the operation is still useful |
For retryable errors, retain the same Idempotency-Key when retrying the same logical operation.