Errors¶
Error responses use a single JSON shape:
{
"error": {
"type": "invalid_request_error",
"code": "NOT_FOUND",
"message": "Resource not found.",
"request_id": "01H…",
"details": {
"resource": "subscriber",
"id": "cust_123"
}
}
}
Clients show error.message. Branch on code and HTTP status. Include request_id when you contact support.
Types¶
type |
Use |
|---|---|
invalid_request_error |
4xx — bad input or business rule |
api_error |
5xx — something failed on our side |
Common codes¶
The fallback message is used only when nothing more specific applies.
| HTTP | code |
Fallback message |
When |
|---|---|---|---|
| 401 | UNAUTHORIZED |
Authentication required. | Missing or invalid credentials |
| 403 | FORBIDDEN |
You don't have permission to do that. | Key is missing a required scope. message does not include the scope name. |
| 404 | NOT_FOUND |
Resource not found. | Unknown key or subscriber id, or not in your organization |
| 409 | CONFLICT |
That already exists. | Duplicate key, subscription history still references the plan, feature still on a plan/override, delete blocked |
| 422 | VALIDATION_ERROR |
That doesn't look right. | Bad body or query (including unknown feature key on check) |
| 429 | RATE_LIMITED |
Too many requests. Try again in a moment. | GET entitlements and POST check share 100 requests per second per organization. |
| 500 | INTERNAL_ERROR |
An unexpected error occurred. | Unexpected server error |
| 503 | SERVICE_UNAVAILABLE |
Service temporarily unavailable. | Temporary outage; safe to retry with backoff |
Details¶
details is optional (fields for validation, resource + id for not found). message is always present. For 429, use Retry-After or details.retry_after_seconds, not message.