Skip to content

API reference / Errors

Every error code, in one place

Every HyperCRM API response, success or failure, follows one of two envelope shapes. This page lists both shapes, how request ids work, and the full table of error codes and HTTP statuses an endpoint can return.

The two envelopes

Successful responses (2xx) always look like this, with data holding the resource and requestId for correlation:

{
  "data": { "...": "resource-specific shape" },
  "requestId": "req_5f2c1e40-..."
}

POST endpoints that create a resource return 201 with the same shape. Error responses (4xx/5xx) share the mirror shape, with a stable code, a safe-to-display message, the same requestId, and an optional details array present only when there are field-level issues (e.g. field validation entries with path/message):

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed.",
    "requestId": "req_5f2c1e40-...",
    "details": [ { "path": ["firstName"], "message": "firstName is required" } ]
  }
}

Request ids

Every response carries an x-request-id header, and the same value appears as requestId in the body. If the incoming request supplies its own x-request-id (or x-correlation-id) header matching a safe pattern, that value is echoed back for client-side log correlation; otherwise the server generates one of the form req_<uuid>.

Back to the API reference hub for the other resource pages.

Every error code

Statuses are fixed per code. Some endpoints override the message with something more specific while keeping the same code and status, so match on the code — never on the message text.

CodeStatusWhen it happens
validation_failed400A field failed validation, the body carried an unrecognized field, or the JSON was malformed. Carries details.
bad_request400A malformed request that is not a field-level validation failure.
unauthorized401Authentication is required. Distinct from the bearer-token codes below, which describe the token itself.
forbidden403Authenticated, but not allowed to do this — for example exporting data as a non-owner.
not_found404No such resource in your practice. Also returned for a malformed path id, so the two are indistinguishable.
conflict409The request conflicts with current state — a duplicate tag title, for instance.
already_submitted409A public form link that has already been submitted.
entries_not_billable409Issuing a receipt or invoice for chosen charges when one of them is not an unbilled charge of that patient.
appointment_already_charged409Charging an appointment that already has a charge that is not voided. Void that charge first.
appointment_not_chargeable409Charging an appointment that is not a confirmed patient appointment: a request, a declined, cancelled or expired booking, a reminder or a blocked slot.
token_expired410A public link has expired.
payload_too_large413The request body exceeds the maximum accepted size.
recipient_tax_id_required422A tax invoice was requested for a patient with no tax id on file. Add it, or issue a receipt.
rate_limit_exceeded429A rate limit was reached.
internal_error500An unexpected server error. Nothing about the cause is returned; quote the requestId when reporting it.
service_unavailable503A dependency is temporarily unavailable.
missing_authorization401No Authorization header was sent.
invalid_authorization_header401The header was present but not in the form Bearer <token>.
invalid_auth_token401The token is not valid.
expired_auth_token401The token has expired. Refresh it and retry.
revoked_auth_token401The token has been revoked.
auth_token_verification_failed401The token could not be verified for a reason with no more specific code.
disabled_auth_token403The token verifies, but the identity behind it is disabled — hence 403 rather than 401.
unsupported_auth_provider403That sign-in provider is not accepted for API access.
auth_provider_email_required403The sign-in provider did not supply an email address, which is required to create an account.
user_disabled403The HyperCRM account itself is disabled.
auth_configuration_missing503Authentication is not configured on the server.

Common questions

Patient records are encrypted in transit and at rest, files are stored privately and served through short-lived signed links, and every change is written to an audit log. Staff accounts sign in with passkeys rather than shared passwords.

No. It's included only when there are structured, field-level issues to report, such as field validation failures, each with a path and a message. When there's nothing field-specific to say, the key is omitted entirely from the response body rather than sent as an empty array.

Use the requestId value from the response body, or the identical x-request-id response header. If your own request already sent an x-request-id or x-correlation-id header in the expected format, that same value is echoed back, so you can generate your own id up front and match on it end to end.

Because the bearer token itself is still valid and verifies correctly — the identity behind it is disabled, which HyperCRM treats as an authorization failure rather than an authentication failure. It's a deliberate exception from the more common convention, documented explicitly on the authentication reference page.