Every failure returns the same envelope — a success:false flag, a human-readable message, and an errors array. Branches on the HTTP status and reads the message; do not parse prose.
{
"success": false,
"message": "API key does not have the required scope: ReadCustomer",
"errors": ["API key does not have the required scope: ReadCustomer"]
}| Status | Meaning | When |
|---|---|---|
| 400 | Bad Request | A parameter or body is invalid. The message names the field. |
| 401 | Unauthorized | Missing, malformed, expired, or inactive API key. |
| 403 | Forbidden | The key lacks the required scope, is outside its IP allowlist, or named another tenant. |
| 404 | Not Found | No such resource in the key’s tenant. |
| 409 | Conflict | The request conflicts with current state (e.g. a duplicate, or a booking slot taken). |
| 422 | Unprocessable Entity | The request was understood but failed a business rule. |
| 429 | Too Many Requests | Rate limited — see Rate limits. |
| 500 | Internal Server Error | Unexpected server error. Retry with backoff; contact support if it persists. |
Tip
429 and 5xx with exponential backoff. Treat 401 as a configuration problem (a bad or revoked key) rather than retrying. Read the missing scope from a 403 and grant exactly that — see Authentication.