Errors
All errors use a consistent envelope and an appropriate HTTP status:
{
"error": {
"code": "validation_failed",
"message": "The 'amount' field is required.",
"details": [
{ "field": "amount", "issue": "required" }
],
"request_id": "req_8f3a1c9e"
}
}
request_id is also returned in the X-Request-Id response header — include it in support
requests.
| HTTP | error.code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed request / invalid JSON |
| 401 | unauthorized | Missing / invalid / expired credentials |
| 403 | insufficient_scope | Key lacks the required scope |
| 403 | origin_not_allowed | Request origin not in the key's allow-list |
| 404 | not_found | Resource does not exist (or not in this company) |
| 409 | conflict | Idempotency or state conflict (e.g. already paid) |
| 422 | validation_failed | Body failed validation (see details) |
| 429 | rate_limited | Rate limit exceeded |
| 500 | server_error | Unexpected error — safe to retry idempotent calls |
Auth-failure messages are deliberately generic and never disclose whether a resource exists in another company.