Errors
Every error uses one envelope. message is human-readable and localized (English by
default, Romanian with Accept-Language: ro); branch on code, never on
the message.
{
"error": {
"code": "insufficient_scope",
"message": "The API key is missing the required scope: read:doctors.",
"details": { "required_scope": "read:doctors" }
}
} Codes
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Missing, malformed, revoked or expired key |
| 403 | insufficient_scope | The key lacks the scope in details.required_scope |
| 404 | not_found | Resource does not exist — including resources of other organizations (no existence leaks) |
| 409 | slot_taken | The appointment slot was taken concurrently — refetch availability |
| 422 | validation_failed | Field-level validation failed; details maps fields to messages |
| 422 | outside_working_hours | The requested time is outside the doctor's/location's schedule |
| 422 | http_error | A domain rule rejected the request (message explains) |
| 429 | rate_limited | Per-key rate limit exceeded — see rate limits |
Retry guidance
429— wait forX-RateLimit-Reset, then retry.409 slot_taken— refetch/availabilityand offer a new slot; never blind-retry the same time.5xx— safe to retry reads with exponential backoff. For writes, re-check state first (e.g. list appointments) — the request may have succeeded.4xxother than 429 — fix the request; retrying unchanged will fail again.