Skip to content

API reference / Authentication

Bearer tokens, in detail

Every HyperCRM API request carries one header: `Authorization: Bearer <token>`. This page covers exactly what that token can be, how a malformed or invalid header is rejected, and the specific error code returned for each failure mode.

The header

Every endpoint requires Authorization: Bearer <token>. There are two valid kinds of token: a Firebase ID token from a signed-in HyperCRM session, or an opaque OAuth access token (hcrm_at_...) issued by HyperCRM's own OAuth 2.1 authorization server for the MCP endpoint. Both are accepted wherever a bearer token is expected — the server checks whether the token starts with hcrm_at_ and, if not, falls back to Firebase ID token verification.

No separate signup step

There is no API-key dashboard and no registration endpoint for a Firebase-authenticated caller. On the first successful verification of a given Firebase identity, HyperCRM finds or creates the corresponding user, practice, and owner membership row. Every subsequent call resolves the same practice from the token — a request never supplies its own practiceId.

OAuth access tokens

For MCP clients, HyperCRM issues its own opaque hcrm_at_... access tokens and hcrm_rt_... refresh tokens through a standards-compliant OAuth 2.1 flow: dynamic client registration, a consent screen backed by the same Firebase sign-in, and a mandatory PKCE (S256) authorization code exchange. Tokens are never JWTs — only their SHA-256 hash is stored — and a refresh token rotates on every use, invalidating the previous one.

When authentication fails

A missing header returns missing_authorization; a header that isn't Bearer <token> returns invalid_authorization_header; an unparseable or unverifiable token returns invalid_auth_token or auth_token_verification_failed. An expired token returns expired_auth_token, and a revoked one returns revoked_auth_token — all four are HTTP 401. A disabled account is HTTP 403, not 401: the token itself still verifies correctly, but the identity behind it is disabled, surfaced as disabled_auth_token or user_disabled depending on which side flagged it. unsupported_auth_provider and auth_provider_email_required (both 403) cover sign-in providers HyperCRM doesn't support for API access. auth_configuration_missing (503) means the server itself has no Firebase project configured.

See the full error reference for how these codes fit into the overall error envelope, and the API reference hub for the other resource pages.

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.

Yes, using an OAuth access token instead. HyperCRM runs its own OAuth 2.1 authorization server for MCP clients: a client registers itself, a user approves access through a consent screen backed by their normal Firebase sign-in, and the client receives an opaque access token to use as the bearer token.

Because the token itself is still valid and verifies correctly — it's the account behind it that's disabled, which is a distinct failure from an invalid or expired credential. HyperCRM treats that as an authorization problem (403, forbidden) rather than an authentication problem (401, unauthenticated), and documents it as a deliberate exception.

Yes. OAuth access tokens are short-lived, and a refresh token can be exchanged for a new access/refresh pair without the user approving consent again. Refresh tokens rotate on every use, so the previous refresh token stops working the instant a new pair is issued, which limits the damage of a leaked token.