Errors and limits
Every non-2xx response uses the same envelope. The request_id matches the X-Request-ID header, and it is what makes a specific failure traceable.
The envelope
json
{
"error": {
"code": "not_found",
"message": "Resource not found",
"request_id": "b3f1c2a4-..."
}
}Validation errors return 422 with code "validation_error". The message lists the offending fields, as field: reason.
json
{
"error": {
"code": "validation_error",
"message": "body.email: value is not a valid email address; body.name: field required",
"request_id": "b3f1c2a4-..."
}
}| Status | Code | When it shows up |
|---|---|---|
| 401 | unauthorized | Token missing, invalid or expired. |
| 403 | forbidden | Authenticated, but not allowed to do that. |
| 404 | not_found | It does not exist, or you are not a member of its organization. |
| 409 | conflict | State conflict: a duplicated unique value, for instance. |
| 422 | validation_error | The body or the parameters fail validation. |
| 429 | too_many_requests | You went over the limit. Retry later. |
Usage limits
Sensitive endpoints —authentication above all— are limited by source IP and by account, on a fixed window. Go over it and the API answers 429 with the usual envelope.
The limiter is fail-open: if the service that counts them is unavailable, the request is NOT blocked — availability wins. Even so, design your clients to retry with exponential backoff on a 429, and avoid bursts you do not need.