Errors
Failures use the same envelope as success responses: data and meta are null, and error carries a stable code, a human message, and optional details. HTTP status is authoritative.
Error shape
json
{
"data": null,
"meta": null,
"error": {
"code": "forbidden",
"message": "Requested facility is out of scope for this client.",
"details": null
}
}Match on error.code (a stable machine string), not the human message, which may change.
Status codes
| Status | error.code | Meaning |
|---|---|---|
400 | invalid_request / unsupported_grant_type / invalid_scope | Token endpoint (RFC 6749 §5.2). Missing client_id/secret, a grant_type other than client_credentials, or a requested scope your client wasn't granted. |
401 | invalid_client / unauthenticated | Credentials failed at the token endpoint (invalid_client), or a resource call was made without a valid/expired bearer token (unauthenticated). |
403 | forbidden | The token is missing a required scope, or the path org_id/facility_id is out of scope for your client. Deny by default. |
404 | not_found | The resource id does not exist within your tenant. |
422 | validation_error | Request validation failed. `details` carries field locations only — never your echoed input (no PHI in errors). |
429 | rate_limited | Per-client rate limit exceeded. Back off using the X-RateLimit-* headers and retry. |
500 | internal_error | An unexpected server error. The body is generic; internals are never leaked. |
No PHI in errors
Validation errors (
422) return field locations in details — never your echoed input. Unexpected errors return a generic internal_error with no internals leaked. Tokens are never logged or reflected.Token-endpoint errors
The OAuth2 token endpoint is the one exception to the envelope: it follows the RFC 6749 §5.2 error shape ({ "error": "invalid_client" }) so standard OAuth clients handle it. See Authentication for the full list.
Retrying
429— back off using theX-RateLimit-*headers, then retry.401— your token likely expired; fetch a new one and retry once.5xx— retry with exponential backoff; these are transient.400 / 403 / 404 / 422— do not blindly retry; fix the request.