# Cobalt API Documentation > Cobalt provides a unified API for healthcare data, making it easy to read and write to any EHR (Electronic Health Record) system through a single integration. ## Using This File (for agents) This is an index and glossary, not the full documentation. It maps the concepts and endpoints so you can find the right page fast. - **Get the full detail of any page by appending `.md` to its URL.** For example `https://docs.usecobalt.com/api-reference/availability/get.md` returns the raw markdown for Get Availability — every request field, enum, response shape, and error code. Do this instead of guessing request bodies from the one-liners below. - **Per-EMR support is machine-readable in the OpenAPI spec**, not tracked in this file (see EMR Capability Metadata). Do not assume an endpoint or field works on a given EHR from anything written here. ## Key Concepts These are the behaviors that make the Cobalt API distinct. Everything else is a normal REST endpoint — look it up with the `.md` trick above. - **Base URL & Versioning**: All endpoints live under `https://api.usecobalt.com/v1`, EXCEPT the Link token endpoints, which have no `/v1` prefix (`POST /link/token/create`, `GET /link/token/exchange`). Paths below are relative to the base. - **Authentication**: Most API requests require three headers: `client_id`, `client_secret`, and `access_token`. Some need only `client_id` + `client_secret` (the Link token endpoints and `POST /client/lock`). An `access_token` alone is never enough. The credential check runs before every request and can fail with `400` (a header is missing), `401` (unknown or rotated-out credentials), or `403` (`login_required` when the linked EHR account needs re-linking; `pre_live_read_only` when a test token is used on a write; client locked). - **Asynchronous writes**: Most write/fetch operations return a `job_id` immediately and complete later. The outcome is delivered async via a webhook event, or you can poll for it (see Awaiting Results). On success the operation's own resource id (e.g. `patient_id`, `referral_id`) is echoed in both the sync response and the webhook so you can correlate them. - **Dual ID system**: Providers, locations, and pharmacies each have a Cobalt `id` (a UUID, used for Cobalt management endpoints like `PATCH /providers/{id}`) and an `ehr_id` (the EMR's own id, used when referencing them inside an EMR write such as creating an appointment). Using the wrong one is the most common cause of a failed write. Patients are referenced by Cobalt patient `id` on `PATCH /patients/{id}` but by `patient_mrn` on most clinical writes. - **Availability & `calculation_method`**: `GET /availability` computes bookable time. The `calculation_method` query param is the part integrators most often get wrong — it controls what BLOCKS a time from being returned: - `gaps` (default): free time between the provider's working hours and existing appointments; any existing appointment occupies that time. No predefined slots. - `slots`: the EHR's predefined appointment slots, blocked ONLY by an existing appointment of the SAME visit type — a different type can coexist at the same time. - `equal_slots`: predefined slots blocked by ANY appointment at that time, regardless of type. Use when multiple schedulers (clinic staff + automation) book different types into shared slots and you must prevent double-booking. - A `schedule_block` (e.g. Lunch) always blocks the time in all three modes. `visit_type` and capacity fields (`available_appointments`, `max_visits`) appear only under `slots`. Full field list and worked examples: append `.md` to the page. - **Access token lifecycle**: A token maps to one set of EHR credentials. Rotate a possibly-exposed token with `POST /access-token/rotate` (new token issued, old one invalidated, no re-link). Revoke a user with `POST /account/deactivate`. For a broad compromise, `POST /client/lock` is a break-glass stop that invalidates every token and session under the client. - **Reads against an account needing attention**: A `GET` still returns cached data but carries `Cobalt-Link-Action-Required: true` and `Cobalt-Link-Access-Token-Status` headers; writes in that state return `403`. Resolve by re-linking (see Link Update Mode). - **Managed Accounts**: For managed connections, Cobalt owns the full EHR account lifecycle — activation, MFA setup, and password rotation. Your team never logs into the EHR; connect a fresh, never-logged-in account and mark it managed at creation. See the Managed Accounts guides. - **Webhooks**: Real-time notifications with HMAC-SHA256 signature verification. Events share the structure `{ id, access_token_reference_id, object, created, type, job_id, data }`. There is ONE account-wide signing secret. By default events go to all registered account webhook URLs; include a `callback_urls` array of HTTPS URLs in any async request body to deliver that operation's event only to those URLs instead. For the list of event types, see the Operation / Sync / Account event guides. - **Awaiting Results (polling)**: Alternative to webhooks. Poll `GET /webhook-events?job_id={job_id}` at 1-second intervals with a 2-3 minute timeout. - **Response Warnings**: Responses may include a non-fatal top-level `warnings` array (also mirrored in a `Cobalt-Warning` header). The request still succeeds. Unrecognized query parameters are ignored, not applied — a warning names any parameter the endpoint does not recognize so it is visible rather than silent. ### EMR Capability Metadata Per-EMR support lives in the OpenAPI spec, not in this file. An operation's `x-supported-emrs` lists the EMRs that support that endpoint; only use the operation for a listed EMR. A request field's `x-required-for-emrs` lists the EMRs for which that field is required. `x-allowed-values-for-emrs` maps each EMR to the values it accepts for that field. Consult these rather than assuming support. ## Guides - [Introduction](https://docs.usecobalt.com/docs/introduction): Overview of Cobalt's unified healthcare API and getting started - [Authentication](https://docs.usecobalt.com/docs/authentication): The required headers, the full credential-error table, and how to rotate, revoke, or lock tokens - [Managed Accounts Overview](https://docs.usecobalt.com/docs/managed-accounts/overview): Cobalt owns the EHR account lifecycle (activation, MFA, password rotation) - [Managed Accounts Setup](https://docs.usecobalt.com/docs/managed-accounts/setup): Provision a fresh EHR account, connect it via Link, and mark it managed - [Managed Accounts Credentials & Access](https://docs.usecobalt.com/docs/managed-accounts/credentials): The Managed badge, on-demand credential/MFA-code viewing, and encrypted storage - [Link Overview](https://docs.usecobalt.com/docs/link/overview): How the Cobalt Link auth flow works (link_token → Link UI → public_token → access_token) - [Link Setup](https://docs.usecobalt.com/docs/link/setup): Implementation guide with JavaScript/React examples for Lightbox and New Window modes - [Link Update Mode](https://docs.usecobalt.com/docs/link/update-mode): Re-authentication for existing connections when login_required errors occur - [Webhooks Overview](https://docs.usecobalt.com/docs/webhooks/overview): Webhook basics, HTTPS requirements, secret rotation, and best practices - [Webhooks Setup](https://docs.usecobalt.com/docs/webhooks/setup): Register/retrieve/remove webhook URLs and override the destination per request with `callback_urls` - [Receiving Webhooks](https://docs.usecobalt.com/docs/webhooks/receiving): Signature verification using HMAC-SHA256, with code examples - [Operation Events](https://docs.usecobalt.com/docs/webhooks/operation-events): Every event fired when Cobalt performs a write in the EHR, plus their structured error codes (authoritative reference) - [Sync Events](https://docs.usecobalt.com/docs/webhooks/sync-events): Events fired when Cobalt detects changes EHR staff made directly - [Account Events](https://docs.usecobalt.com/docs/webhooks/account-events): Events fired when an end-user's stored EHR credentials need attention - [Awaiting Results Overview](https://docs.usecobalt.com/docs/awaiting-results/overview): Polling-based alternative to webhooks - [Awaiting Results Implementation](https://docs.usecobalt.com/docs/awaiting-results/implementation): Polling code examples in JavaScript, Python, and cURL - [Awaiting Results Best Practices](https://docs.usecobalt.com/docs/awaiting-results/best-practices): Poll intervals, timeouts, and webhooks vs polling ## API Reference One line per endpoint. Append `.md` to any page URL for the full request/response detail, fields, enums, and error codes. ### Link - [Create Link Token](https://docs.usecobalt.com/api-reference/link/create-token): `POST /link/token/create` — Create a link_token (also update mode via `access_token`). No `/v1` prefix. - [Exchange Token](https://docs.usecobalt.com/api-reference/link/exchange-token): `GET /link/token/exchange` — Exchange a public_token for a permanent access_token. No `/v1` prefix. ### Account - [Activate Account](https://docs.usecobalt.com/api-reference/account/activate): `POST /account/activate` — Activate a deactivated account. - [Deactivate Account](https://docs.usecobalt.com/api-reference/account/deactivate): `POST /account/deactivate` — Deactivate an active account. - [Rotate Access Token](https://docs.usecobalt.com/api-reference/account/rotate-access-token): `POST /access-token/rotate` — Issue a new access_token and invalidate the current one. - [Lock Client](https://docs.usecobalt.com/api-reference/account/lock): `POST /client/lock` — Break-glass: invalidate every token and EHR session under the client. - [Last Schedule Sync](https://docs.usecobalt.com/api-reference/system/last-schedule-sync): `GET /last-schedule-sync` — Timestamp of the last successful schedule sync. - [Fetch Org Settings](https://docs.usecobalt.com/api-reference/org-settings/fetch): `POST /org-settings/fetch` — Queue an on-demand sync of the full org config. Async → `org_settings.synced`. ### Appointments - [Create Appointment](https://docs.usecobalt.com/api-reference/appointments/create): `POST /appointments` — Create an appointment. Async → `appointment.created`. - [List Appointments](https://docs.usecobalt.com/api-reference/appointments/get): `GET /appointments` — List appointments with filtering and pagination. - [Get Appointment](https://docs.usecobalt.com/api-reference/appointments/get-by-id): `GET /appointments/{id}` — Full detail for one appointment. - [Update Appointment](https://docs.usecobalt.com/api-reference/appointments/update): `PATCH /appointments/{id}` — Update an appointment (editable fields depend on its status). - [Fetch Appointments](https://docs.usecobalt.com/api-reference/appointments/fetch): `POST /appointments/fetch` — Live-fetch from the EMR. Async → `appointment.live_fetch_completed`. ### Diagnosis Codes - [Add Diagnosis Codes](https://docs.usecobalt.com/api-reference/codes/add): `POST /appointments/{appointment_id}/codes` — Add ICD-10 codes to an encounter. Async → `codes.added`. - [Remove Diagnosis Codes](https://docs.usecobalt.com/api-reference/codes/remove): `DELETE /appointments/{appointment_id}/codes` — Remove ICD-10 codes. Async → `codes.removed`. ### Patients - [Create Patient](https://docs.usecobalt.com/api-reference/patients/create): `POST /patients` — Create a patient. Async → `patient.created` (carries the EMR-assigned `mrn`). - [List Patients](https://docs.usecobalt.com/api-reference/patients/get): `GET /patients` — List patients with first_name/last_name filtering. - [Update Patient](https://docs.usecobalt.com/api-reference/patients/update): `PATCH /patients/{id}` — Update a patient (editable fields depend on its status). Async → `patient.updated`. - [Fetch Patient](https://docs.usecobalt.com/api-reference/patients/fetch): `POST /patients/fetch` — Live-fetch a patient with optional includes. Async → `patient.live_fetch_completed`. - [Add Patient Insurance](https://docs.usecobalt.com/api-reference/patients/insurances/add): `POST /patients/{patient_mrn}/insurances` — Add an insurance record. Async → `patient.insurance.added`. - [Update Patient Insurance](https://docs.usecobalt.com/api-reference/patients/insurances/update): `PATCH /patients/{patient_mrn}/insurances/{emr_insurance_id}` — Update an insurance record. Async → `patient.insurance.updated`. ### Providers - [List Providers](https://docs.usecobalt.com/api-reference/providers/get): `GET /providers` — Returns Cobalt id, ehr_id, status, NPI, timezone, schedule. - [Update Provider](https://docs.usecobalt.com/api-reference/providers/update): `PATCH /providers/{id}` — Update status, availability visibility, and working hours (by Cobalt id). - [Update Provider by EHR ID](https://docs.usecobalt.com/api-reference/providers/update-by-ehr): `PATCH /providers/ehr/{ehr_id}` — Same, addressed by the EMR's provider id. ### Availability - [Get Availability](https://docs.usecobalt.com/api-reference/availability/get): `GET /availability` — Bookable slots; behavior driven by `calculation_method` (see Key Concepts). - [Fetch Availability](https://docs.usecobalt.com/api-reference/availability/fetch): `POST /availability/fetch` — Live-fetch + compute availability in one pass. Async → `availability.live_fetch_completed`. ### Locations - [List Locations](https://docs.usecobalt.com/api-reference/locations/get): `GET /locations` — Returns Cobalt id, ehr_id, name, address, phone, fax, status. - [Update Location](https://docs.usecobalt.com/api-reference/locations/update): `PATCH /locations/{id}` — Update status (active/inactive). ### Visit Configuration - [List Visit Types](https://docs.usecobalt.com/api-reference/visit-types/get): `GET /visit-types` — Available visit type codes and descriptions. - [List Visit Statuses](https://docs.usecobalt.com/api-reference/visit-statuses/get): `GET /visit-statuses` — Available appointment status codes for use in updates. ### Insurance - [Search Insurance Providers](https://docs.usecobalt.com/api-reference/insurance-providers/get): `GET /insurance-providers` — Search by name. Returns id, name, payer_id, active status. ### Eligibility - [Get Eligibility Checks](https://docs.usecobalt.com/api-reference/eligibility-checks/get): `GET /eligibility-checks` — 270/271 check headers with benefits summary. - [Get Eligibility Benefits](https://docs.usecobalt.com/api-reference/eligibility-checks/benefits): `GET /eligibility-checks/{id}/benefits` — Per-benefit 271 detail lines. ### Fee Schedules - [Get Fee Schedules](https://docs.usecobalt.com/api-reference/fee-schedules/get): `GET /fee-schedules` — Fee schedule headers with item counts and effective dates. - [Get Fee Schedule Items](https://docs.usecobalt.com/api-reference/fee-schedules/items): `GET /fee-schedules/{feeScheduleId}/items` — Paginated per-code pricing. ### Pharmacies - [List Pharmacies](https://docs.usecobalt.com/api-reference/pharmacies/get): `GET /pharmacies` — Returns Cobalt id, ehr_id, address, phone, email, status. ### Referring Providers - [List Referring Providers](https://docs.usecobalt.com/api-reference/referring-providers/get): `GET /referring-providers` — Filter by name, phone, fax, NPI. - [Create Referring Provider](https://docs.usecobalt.com/api-reference/referring-providers/create): `POST /referring-providers` — Create a referring provider. Async → `referring_provider.created`. ### Clinical Operations - [Create Note](https://docs.usecobalt.com/api-reference/notes/create): `POST /notes` — Create a note on an appointment. Async → `note.uploaded`. - [Create Patient Note](https://docs.usecobalt.com/api-reference/patient-notes/create): `POST /patient-notes` — Create a free-standing chart note on a patient. Async → `patient_note.created`. - [Upload Document](https://docs.usecobalt.com/api-reference/documents/upload): `POST /documents` — Multipart document upload. Async → `document.uploaded`. - [Get Document](https://docs.usecobalt.com/api-reference/documents/get): `GET /documents/{id}` — Download a document's raw file bytes. - [Send Message](https://docs.usecobalt.com/api-reference/messages/create): `POST /messages` — Send a message to a provider. Async. - [Create Task](https://docs.usecobalt.com/api-reference/tasks/create): `POST /tasks` — Create a task. Async → `task.created`. - [Create Task Note](https://docs.usecobalt.com/api-reference/tasks/notes/create): `POST /tasks/notes` — Append a note to an existing EMR task. Async → `task_note.created`. - [Create Payment](https://docs.usecobalt.com/api-reference/payments/create): `POST /payments` — Post a patient payment to the EMR ledger. Async → `payment.created`. ### Telephone Encounters - [Create Telephone Encounter](https://docs.usecobalt.com/api-reference/telephone-encounters/create): `POST /telephone-encounters` — Create an encounter. Async → `telephone_encounter.created`. - [Create Encounter Action](https://docs.usecobalt.com/api-reference/telephone-encounters/create-action): `POST /telephone-encounters/actions` — Append a timestamped action to an encounter. ### Claims & Orders - [Create Claim](https://docs.usecobalt.com/api-reference/claims/create): `POST /claims` — Create a claim for an appointment. Async → `claim.created`. - [List Claims](https://docs.usecobalt.com/api-reference/claims/get): `GET /claims` — Query claims by date range. - [Get Claim by ID](https://docs.usecobalt.com/api-reference/claims/get-by-id): `GET /claims/{id}` — One claim with line items, payments, and billing detail. - [List Orders](https://docs.usecobalt.com/api-reference/orders/get): `GET /orders` — Query lab/imaging orders by patient and date range. ### Referrals - [Create Referral](https://docs.usecobalt.com/api-reference/referrals/create): `POST /referrals` — Queue a referral, optionally with inline documents. Async → `referral.created`. - [List Referrals](https://docs.usecobalt.com/api-reference/referrals/get): `GET /referrals` — Query referrals by date range with filters. - [Update Referral](https://docs.usecobalt.com/api-reference/referrals/update): `PATCH /referrals/{id}` — Partial update of an existing referral. Async → `referral.updated`. ### Forms & Services - [List Forms](https://docs.usecobalt.com/api-reference/forms/get): `GET /forms` — Cached form metadata (id, emr_form_id, name, type, version, status). - [Get Form](https://docs.usecobalt.com/api-reference/forms/get-by-id): `GET /forms/{id}` — One form with its full definition (categories → questions → answers). - [Sync Forms](https://docs.usecobalt.com/api-reference/forms/fetch): `POST /forms/fetch` — Queue an on-demand sync of form definitions. Async → `forms.synced`. - [Create Service](https://docs.usecobalt.com/api-reference/services/create): `POST /services` — Write an episode visit with form documentation. Async → `service.created`. ### Recalls - [Get Recalls](https://docs.usecobalt.com/api-reference/recalls/list): `GET /recalls` — List recalls for the connected account. - [Create Recall](https://docs.usecobalt.com/api-reference/recalls/create): `POST /recalls` — Create a recall. Async → `recall.created`. - [Update Recall](https://docs.usecobalt.com/api-reference/recalls/update): `PATCH /recalls/{id}` — Change a recall's status and/or add a note. - [Add Action to Recall](https://docs.usecobalt.com/api-reference/recalls/create-action): `POST /recalls/{id}/actions` — Add an action; a closing action closes the recall. Async → `recall_action.created`. ### Webhooks Management - [Create Webhook](https://docs.usecobalt.com/api-reference/webhooks/create): `POST /webhook` — Register a webhook URL. Returns the account-wide signing secret. - [List Webhooks](https://docs.usecobalt.com/api-reference/webhooks/get): `GET /webhook` — List configured webhook URLs. - [Delete Webhook](https://docs.usecobalt.com/api-reference/webhooks/delete): `DELETE /webhook/{id}` — Remove a webhook. - [Rotate Secret](https://docs.usecobalt.com/api-reference/webhooks/rotate-secret): `POST /webhook/rotate-secret` — Rotate the account-wide signing secret. - [Send Test Webhook](https://docs.usecobalt.com/api-reference/webhooks/send-test-webhook): `POST /webhook/test` — Send a signed `test.event` to every configured URL. - [Get Webhook Events](https://docs.usecobalt.com/api-reference/webhook-events/get): `GET /webhook-events` — Query events by job_id, type, delivery status, date range. - [Get Webhook Event by ID](https://docs.usecobalt.com/api-reference/webhook-events/get-by-id): `GET /webhook-events/{id}` — A specific event with audit trail. ### Settings - [Get Settings](https://docs.usecobalt.com/api-reference/settings/get): `GET /settings` — Returns visit types/statuses, required patient fields, staff list, timezone. - [Update Settings](https://docs.usecobalt.com/api-reference/settings/update): `POST /settings` — Update `access_token_reference_id`. ## Common Patterns ### Creating an Appointment (End-to-End) 1. `GET /providers` to find the provider's `ehr_id` 2. `GET /locations` to find the location's `ehr_id` 3. `GET /visit-types` to find valid visit type codes 4. `GET /availability` to find open slots 5. `POST /appointments` with the above (`ehr_id`s, not Cobalt ids) — returns `job_id` 6. Listen for `appointment.created` webhook or poll `GET /webhook-events?job_id={job_id}` ### Creating a Patient (End-to-End) 1. `POST /patients` with demographics — returns `patient_id` and `job_id` 2. Listen for `patient.created` webhook — includes the EMR-assigned `mrn` 3. Optionally `POST /patients/{mrn}/insurances` to add insurance ### Authentication Flow 1. `POST /link/token/create` with `user_id` and `org_id` — returns `link_token` 2. Initialize Cobalt Link UI with the `link_token` 3. User completes EHR authentication in Link 4. `GET /link/token/exchange?public_token={token}` — returns permanent `access_token` ### Handling a Possibly-Exposed Token - Single token: `POST /access-token/rotate` — store the new token; the old one now returns `401`. No re-link required. - Whole client compromised: `POST /client/lock` — break-glass; invalidates every token and session. Contact support to unlock.