insurance_no, pa_code, hmo_status, qty_approved,
sub_total_billed), so an insurer that already speaks Curacel maps across with little work. It is ClinikEHR’s own
API, with its own routes, errors and rules.
Two ways to use it, and who decides
A clinic decides what each connected organization is. Nothing is assumed from the name on the key.
An insurer sees only its own rows. A claim, enrollee, plan, authorization request or payment advice that belongs to a
different insurer is not hidden behind a permission error: it answers
404, the same as one that does not exist. An
insurer also never sees what the clinic has not sent yet: a claim still being prepared, or an authorization request
not yet sent for approval.
The clinic owner or manager links an organization to an insurer under Settings → API access → Insurer links. A
link can be ended at any time, and your access to that insurer’s data stops with it.
What you need
- A live key that belongs to your organization, with the insurance permissions below. See Permissions.
- An approval for the Insurer claims, authorizations and enrollees kind of patient data on your organization, and the data-protection addendum accepted. See Getting access to patient data.
- A connection to the clinic that grants those permissions. See Connections.
- The clinic’s link from your organization to your insurer record, if you are an insurer.
The endpoints
Lists use the cursor paging described on Pagination. Every write needs an
Idempotency-Key, so a retry
returns the first answer instead of doing the work twice. See Retries and duplicates.
Verify an enrollee
Send the number the patient presented. It matches the enrollee’s number and their alternate number.status uses Curacel’s codes: AA active, IA inactive, SX suspended, XX cancelled, PP pending, WP in a
waiting period. An enrollee the clinic holds under a different insurer is not found.
Read claims
GET …/insurance/claims lists the claims the clinic has submitted to you. Filter by status, hmo_status,
enrollee_id and updated_since. A list row has no lines; read the claim to get them.
A claim has two statuses. status is the clinic-side lifecycle (submitted, approved, partially_approved,
denied, partially_paid, paid, and so on). hmo_status is your verdict (PENDING, APPROVED,
PARTIALLY_APPROVED, REJECTED). paid_amount and written_off_amount are what the clinic has recorded: no API
call changes them.
Each line carries what was billed (qty_billed, unit_price_billed, sub_total_billed) and, once vetted, what was
approved (qty_approved, unit_price_approved, sub_total_approved, hmo_item_status). Attached documents come with
their name, type and size only; the files themselves are not served by this API.
Vet a claim
decision is required and sets what every line gets: approved at the billed figures, or rejected at zero.
items then overrides individual lines, so “approve everything except this line” is one declined entry. A rejection
needs a reason; so does a declined line, unless the body has a reason of its own.
The claim’s status follows its lines:
The rules the clinic’s books depend on:
- You cannot approve more than was billed, for a quantity or a price.
- Vetting never moves money. There is no field for a paid or written-off amount, and sending one is refused as an unknown field.
- Once the clinic has recorded a payment or a write-off against a claim, it can no longer be vetted. It answers
409withcode: "invalid_status_transition". - Until then you can vet again, for example after the clinic sends more information.
pa_code to tie the claim to an authorization you issued.
Authorization requests
GET …/insurance/pre-authorizations lists the requests the clinic has sent to you. Read one for its lines,
diagnoses and the clinical reason given for each line.
pa_code; a denial needs a reason. approved_amount defaults to the estimated cost and cannot
exceed it. Lines you do not list follow the decision. A request is decided once: a second decision answers 409
with code: "invalid_status_transition".
Tell the clinic what you paid
A payment advice says “we paid this much, by this method, against these claims”. It is a message to the clinic. It does not change a claim, the clinic’s payments or its books. Clinic staff record the money themselves, and only then does a claim move topartially_paid or paid.
amount. If you send a currency it must be the clinic’s currency.
Submit a claim or an authorization request
For a developer, or the clinic’s own key. A claim is saved assubmitted with no money on it and answers 201 with
the claim. patient_id must be a patient the clinic has linked to your organization. An organization that is linked
to an insurer cannot submit: it answers 403 with code: "role_required".
POST …/insurance/pre-authorizations with request_type, the lines (with
unit_cost) and, optionally, the diagnosis and the clinical reason for each line. The request is saved as
sent_for_authorization.
Events
Subscribe a webhook endpoint, or read the change feed. An insurer receives these events only for its own insurer records, and only while its connection grants the matching permission. Each carries ids, a number, a status and amounts, never a patient’s name or identifier.Test keys
A test key reaches only its own sandbox clinic, which holds no insurance data. Lists answer an empty page and reads answer404. Writes also answer 404. Use a live key against a clinic that has linked your organization to try the
routes.
Errors you will meet
See Errors for the codes shared by every route.