Error handling.
Understanding structured error responses and retry strategies.
Every Agent API response follows a predictable structure. Success and error responses use the same envelope format, so AI agents and automation tools can parse them without special cases.
Response envelope
Success response
{
"error": false,
"data": {
"id": "9e1a...",
"name": "Downtown Club"
}
}
Paginated list responses include pagination metadata:
{
"error": false,
"data": [...],
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 42
}
}
All responses include rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1741260060
Error response
{
"error": true,
"code": "VALIDATION_FAILED",
"message": "The request data did not pass validation.",
"retry_strategy": "fix_request",
"details": {
"errors": {
"card_id": ["The card_id field is required."],
"purchase_amount": ["The purchase_amount must be at least 0.01."]
}
}
}
Error fields
| Field | Type | Description |
|---|---|---|
error |
boolean | Always true for error responses |
code |
string | Machine-readable error code (e.g., AUTH_INVALID_KEY) |
message |
string | Human-readable description |
retry_strategy |
string | How the caller should handle this error |
details |
object | Optional additional context (validation errors, limits, etc.) |
Retry strategies
The retry_strategy field tells AI agents and automation tools how to handle the error:
| Strategy | Meaning | What To Do |
|---|---|---|
no_retry |
The request itself is invalid | Fix the integration. Wrong key, wrong scope, resource not found. |
fix_request |
Request body has errors | Fix the request payload and try again (validation errors). |
backoff |
Temporary issue | Retry with exponential backoff. Rate limit hit, server error. |
contact_support |
Requires human intervention | Feature disabled, limit reached, account deactivated. |
Retry strategy examples
no_retry: Don't retry. The request was wrong.
{
"code": "AUTH_INVALID_KEY",
"retry_strategy": "no_retry"
}
fix_request: Fix the data and try again.
{
"code": "VALIDATION_FAILED",
"retry_strategy": "fix_request",
"details": {
"errors": {
"card_id": ["The card_id field is required."]
}
}
}
backoff: Wait and retry with exponential backoff.
{
"code": "INTERNAL_ERROR",
"retry_strategy": "backoff"
}
Recommended backoff: 1s → 2s → 4s → 8s → 16s → stop.
contact_support: Human intervention needed.
{
"code": "FEATURE_DISABLED",
"retry_strategy": "contact_support",
"details": {
"permission": "loyalty_cards_permission"
}
}
Error code reference
Authentication errors (401/403)
| Code | HTTP | Retry | Description |
|---|---|---|---|
AUTH_MISSING_KEY |
401 | no_retry |
No X-Agent-Key header |
AUTH_INVALID_KEY |
401 | no_retry |
Key format wrong or hash mismatch |
AUTH_KEY_REVOKED |
401 | no_retry |
Key is no longer active |
AUTH_KEY_EXPIRED |
401 | no_retry |
Key past its expiration date |
AUTH_OWNER_INACTIVE |
403 | contact_support |
Owner account deactivated |
AUTH_ANONYMOUS_MEMBER |
403 | no_retry |
Anonymous members cannot use keys |
AUTH_INSUFFICIENT_SCOPE |
403 | no_retry |
Key lacks required scope |
AUTH_WRONG_ROLE |
403 | no_retry |
Key role doesn't match endpoint |
Validation errors (422)
| Code | HTTP | Retry | Description |
|---|---|---|---|
VALIDATION_FAILED |
422 | fix_request |
Request body failed validation |
LIMIT_REACHED |
422 | contact_support |
Partner resource limit hit |
Resource errors (404)
| Code | HTTP | Retry | Description |
|---|---|---|---|
NOT_FOUND |
404 | no_retry |
Resource not found or doesn't belong to partner |
Permission errors (403)
| Code | HTTP | Retry | Description |
|---|---|---|---|
FEATURE_DISABLED |
403 | contact_support |
Feature not enabled for partner |
Server errors (500)
| Code | HTTP | Retry | Description |
|---|---|---|---|
INTERNAL_ERROR |
500 | backoff |
Unexpected server error |
Rate limiting (429)
| Code | HTTP | Retry | Description |
|---|---|---|---|
RATE_LIMITED |
429 | backoff |
Exceeded requests per minute limit |
The 429 response includes extra headers and details:
Retry-After: 23
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1741260023
See Rate limiting in Authentication for full details.
For AI agent developers
If you're building an AI agent that consumes this API, branch on retry_strategy:
response = call_agent_api(endpoint, data)
if response["error"]:
match response["retry_strategy"]:
case "no_retry":
log_error(response["code"], response["message"])
raise PermanentError(response["message"])
case "fix_request":
fix_fields(response["details"]["errors"])
retry_with_fixed_data()
case "backoff":
wait_exponential(attempt)
retry()
case "contact_support":
notify_human(response["message"])
raise NeedsHumanIntervention(response["message"])
Related topics
- Authentication: Auth error codes in detail
- Scopes & Permissions: Scope enforcement errors
- Partner Endpoints: Endpoint-specific error cases