Skip to main content
Every request is authenticated with a single bearer key — there is no OAuth flow, no client ID/secret pair, and no session cookie in this API.

Key format

Every key starts ehr_live_ or ehr_test_. Treat the whole string as one opaque secret; don’t try to parse meaning out of it beyond the prefix. A clinic’s own key (created in Settings → API access) is always ehr_live_ — there is no test mode for a clinic-owned key, because it never has anything to test against but its own real data. Test mode exists for an organization’s key, so you can build against a sandbox before a real clinic ever grants you a connection.

Sending the key

Send it as an HTTP Authorization header, using the Bearer scheme:
Never send the key as a query parameter, and never call the API directly from a browser or a mobile app. A key in a URL ends up in server logs, browser history, and proxy logs. A key in client-side code (a web page’s JavaScript, or a mobile app’s bundle) can be read out by anyone who opens it. Call the API from your own backend, and let your backend talk to your frontend or app.

Where the key comes from

Keys are created and revoked in one of two places, never through this API itself:
  • A clinic’s own key — created and revoked in ClinikEHR by the clinic itself, under Settings → API access. See Getting a key.
  • An organization’s key — created and revoked in the developer portal, by a workspace member.
In the portal, the Test / Live switch in the header chooses which keys, request logs and webhook endpoints you are looking at. A strip under the header always names the mode (red on Live). Test keys reach only your sandbox; live keys reach real clinics. A live key also needs the workspace to have accepted the API Terms of Use — see Workspace settings. There is no endpoint in this API for creating, listing, or rotating keys. A key’s secret is shown once, when it is created. Afterwards, the portal and ClinikEHR list each key by a masked ID (ehr_live_•••• and its last four characters) with a Copy key ID button. That ID names the key — for support, logs and revocation — but cannot authenticate a request. Select a key in the list to open a read-only panel with its permissions, dates, allowed addresses and status; the key itself is never shown again.

Verifying your workspace domain

A live key needs a verified workspace, and verification starts with proving you control a domain. In the portal, open Settings → Verification, enter your domain under Domain, and select Save domain. The page then shows one DNS record to publish where you manage that domain: Each of Host, Full name and Value has its own copy button. The record shows Not checked yet, Not found or Verified. You do not have to come back and press a button. We check the record on our own — every few minutes for the first hour, then hourly for a day, then every few hours for up to two weeks — and the page says Last checked and Next automatic check so you can see it working. Check domain looks straight away. If the two weeks pass without the record appearing, automatic checks pause; press Check domain after you publish it and they start again. DNS changes can take from a few minutes to a day to spread. Changing the domain issues a new value and starts the checks again. Once the domain reads Domain verified, complete the business profile and select Submit for review.

What a key can reach

A clinic-owned key can only ever read the one clinic that created it — asking it for a different clinic_id fails exactly the same way as a clinic_id that doesn’t exist at all (see Errors). An organization’s key reaches every clinic that has approved a connection to that workspace — a live key reaches real, connected clinics; a test key reaches only the workspace’s own sandbox, never a real clinic, and a live key can never reach the sandbox either. Confirm what a key currently reaches, and with what scopes, with:
See Connections for the full response shape — for a clinic-owned key, that list always has exactly one entry: the clinic itself, with connected_at/expires_at both null.

Authentication failures

The first four all return the same code on purpose. The response never tells you which of those four happened — that distinction isn’t yours to have, and revealing it would let someone probe for which keys used to exist.
A 401 means the key itself is the problem. A 403 means the key is valid but isn’t allowed to do the specific thing you asked — see Permissions and Errors for the complete list of codes.