Errors
Every error response uses the same shape. Status codes follow HTTP conventions, and the body's error field gives a stable machine-readable code.
Response shape
{
"ok": false,
"error": "machine_code",
"message": "Human-readable",
"request_id": "uuid"
}Status code map
| Code | Meaning | Retry? |
|---|---|---|
| 400 | invalid_argument | no, fix request |
| 401 | auth_required / invalid_credential | depends |
| 403 | rbac_denied / mfa_required | no, raise scope |
| 404 | not_found | no |
| 409 | conflict (idempotency mismatch) | no |
| 422 | validation_failed | no |
| 429 | rate_limited | yes, after Retry-After |
| 500 | internal | yes, exponential backoff |
| 502 | upstream_error | yes, idempotent ops only |
| 503 | unavailable | yes, exponential backoff |
| 504 | upstream_timeout | yes, idempotent ops only |
Stable error codes
Name
Type
Required
Description
auth_required
string
required
Authentication required for this tool
invalid_credential
string
required
API key or Client ID is invalid
rbac_denied
string
required
Insufficient permissions for this operation
mfa_required
string
required
MFA challenge required for destructive operation
scope_missing
string
required
OAuth scope is missing
rate_limited
string
required
Request rate exceeded the allowed limit
validation_failed
string
required
Request body failed schema validation
upstream_error
string
required
Upstream API returned an error
upstream_timeout
string
required
Upstream API did not respond in time
conflict
string
required
Idempotency key mismatch
not_found
string
required
Resource not found
internal
string
required
Internal server error
state_invalid
string
required
OAuth state token expired or replayed
code_exchange_failed
string
required
Provider rejected the OAuth code
redirect_uri_mismatch
string
required
Redirect URI not pre-registered
balance_insufficient
string
required
Organization wallet balance is insufficient
Retry policy
- Always honor
Retry-After. - Default backoff for 5xx: 500ms, 1s, 2s, 4s, then give up.
- Use idempotency keys for ANY retry on a non-GET endpoint.
- Never retry 400/401/403/422 — they will fail again.