04 · Visit
Opening a clinical visit touches no payer. It is an encounter and its account, written together in one atomic step, so the clinical record can start even while every payer is down.
Everything below elaborates this sentence.
Why this stop exists
The visit is the container everything else attaches to. It is an encounter first — conditions, observations, CDSS and generated documents hang off it — so it has to be clinically native before it is ever billable.
Opening it is local. The rail writes an Encounter and an Account to its own clinical
store in a single atomic write and calls no payer. A visit with no covered lines is a purely
clinical visit and stays that way until one is added. Everything that touches a payer — the
authorization, the claim — happens on the lines, each its own answer. Lines sent at open are
the exception to "never un-opens": a refused one voids the open (below). Lines added afterwards
never do.
A patient can have one open visit. A second open is refused 409 VISIT_ALREADY_OPEN, and
its detail names the open visit and the service-lines endpoint to add to instead.
409 MULTIPLE_VISITS_OPEN means the patient already has several open; close the finished ones.
Every v2 call here takes the X-Facility-Id and X-Facility-Id-Type headers. Without them the
answer is 400 FACILITY_CONTEXT_MISSING.
Open the visit
Open an encounter and its account. unique_patient_id, service_type — OUTPATIENT or
INPATIENT — and consent_ref are always required; service_type becomes the encounter's
class and the service type every later authorization carries.
visit_refIdentity, a service type and the consent are the whole of a clinical visit:
unique_patient_idconsent_refservice_typevisit_refTo open against a cover, send the committed selection_ref from 02 · Verify
cover, the consent_ref the consent ceremony minted (below), and one
or more service_lines, each naming its cover:
Code
consent_ref is required on every open, a clinical visit included. selection_ref is required
once service_lines is present, and every line's cover must be one that selection carries.
Open takes a single selection; a further cover joins later through a service line (below).
| Call | What it does | What you keep |
|---|---|---|
callback_url | Optional. Where the visit's later state changes are reported, chiefly preauth decisions a payer makes asynchronously. Steps under the visit inherit it. | — |
visit_number | The provider's own number for this visit, such as the encounter number the HMIS created. Send it on every open. Required, with invoice_number, for covers billed through Slade EDI; without both, that line is refused. | — |
invoice_number | The provider's own number for the visit's bill, such as the pending bill created when the visit was saved. Send it on every open. It is the invoice on the cover's first claim, and on SHA it is the invoice on the one claim sent for the visit. | — |
The visit and invoice numbers
Both are the provider's own numbers, given rather than minted, so the payer's record can be reconciled against yours. A number invented by the rail would name nothing in your books. Send them on every open: both exist as soon as the visit is saved.
- On Slade EDI covers the invoice number names the cover's first claim. A later bill item that names a different invoice number opens a further claim, so a visit can carry several. See which invoice a charge belongs to.
- On SHA the visit goes as one comprehensive claim under this invoice number, however many invoices you hold for it. See Why SHA gets one claim.
What comes back is the visit_ref, the encounter_ref and account_ref, status
in_progress, consent_redeemed_at, one entry per line under service_lines, the covers in
use (an empty list on a clinical visit), any cover_bindings, and a next_action:
add_service_line when no line is authorized yet, add_bill_line once one is.
A refused line voids the open. If the payer refuses any line sent at open, the whole open
fails 422 VISIT_LINE_REFUSED: the encounter is cancelled, the claims minted for that open are
withdrawn, and detail maps each refused intervention code to the payer's verdict. Fix or drop
the line and open again. Only a pending line — the payer did not answer — survives an open.
The consent it spends is a reference, not a proof
The consent ceremony happens end to end in the consent surface at 03 ·
Consent — the decision, the OTP or biometric, the verification. What
opening a visit receives is the consent_ref that ceremony produced: a redeemable
reference to a verified consent, not the raw proof. Open spends it once, by binding it to the
encounter. It must have been taken for the visit_start purpose. A principal's consent can open a
registered dependent's visit, where the household check is wired.
Service lines — the authorization unit
A service line is one intervention plus the cover it draws on. It is the unit a payer authorizes and reserves balance against, and it is payer-first: the rail writes the line as pending, asks the payer, and moves it to the answer the payer gave.
Authorize a cover for a named intervention. The same thing a line at open does, available after the fact — a visit opened clinical becomes billable here, and a second cover joins here.
service_line_refThe body is code and cover, plus three optional fields that carry a cover the visit does not
hold yet: selection_ref (defaults to the visit's own), consent_ref (defaults to the one the
visit opened with) and callback_url (turns on the step-up check below). A visit opened
clinical has no selection, so its first covered line must send selection_ref; without it the
answer is 409 SELECTION_UNUSABLE, and with no consent on the visit or the request, 400 CONSENT_REQUIRED. A one-time code is spent at open and cannot back a new cover, so send a
fresh consent_ref for that cover, or the line is refused 409 CONSENT_NOT_REDEEMABLE with
detail.refusal AUTHN_CONSUMED. A strong factor still fresh can be reused.
codecoverthe payer's answerFour outcomes at this endpoint, and only one is an error you resolve by changing the line:
| Call | What it does | What you keep |
|---|---|---|
authorized | The payer reserved balance against the intervention | service_line_ref → add bill lines under it |
refused | The payer declined; 200 with its verdict relayed verbatim in `refusal` | read the verdict, then fix or drop the line |
pending | The payer did not answer; the line is kept durably and is retryable | PAYER_UNREACHABLE (502) → retry the same request |
consent_required | 200, sent only when callback_url was: the cover needs a stronger factor than the visit's consent, and next_action is step_up_consent, naming the consent surface | run the ceremony, then send the line again |
At this endpoint a refused or unreachable payer never un-opens the visit. The line carries the outcome; the encounter and everything clinical proceed regardless. (At open it is different: see above.)
A second cover
Record the practitioner
Who performed a service is stated once on the visit and referenced by every bill line, rather than re-typed per line. Where a Health Worker Registry is wired, the identification is checked when it is added, so a bad registration number is refused at the desk — not when the payer's claim bounces a week later. Without a registry the check is skipped and the payer's claim is the backstop.
Record a performer. Where a registry is wired, verified under its regulator before it is stored.
practitioner_refSend id, id_type and regulation_body, or send name alone to record a hospital doctor
who is not in the registry. The two forms are alternatives, and a name entry skips the
registry check entirely. role is optional.
It can happen at any time after open — nothing about opening a visit or authorizing a service line waits on a clinician being known.
Record a diagnosis
A diagnosis is a clinical fact first and a claim field second: it exists on visits that
never bill, it is recorded by a clinician rather than the desk, and it changes over a visit.
It is written to the clinical record — a Condition on the encounter — so CDSS, document
generation and the claim builder all read the same one.
Record a diagnosis against the encounter. No cover appears here — a clinical diagnosis needs none, and a payer that requires one enforces that on the claim.
diagnosis_refWhat breaks here
| Where it surfaces | What the desk sees | What actually went wrong |
|---|---|---|
| Visit | "Open answers 400: consent_ref is required" | Every open needs a consent_ref, a clinical visit included. Run the consent ceremony first and pass the reference it returns. On a service line, CONSENT_REQUIRED means neither the request nor the visit holds one. |
| Visit | "The open failed and the visit is gone" | A payer refused a line sent at open, so the open was voided (422 VISIT_LINE_REFUSED, verdicts in detail). Slade EDI covers refuse a line sent without visit_number and invoice_number, so send both on every open. Fix or drop the line and open again. |
| Visit | "Already open" | The patient has an open visit (409 VISIT_ALREADY_OPEN). Add the line to that visit; detail names it. |
| Visit | "Consent not redeemable" | The consent expired, was already spent, or was taken for a different purpose. detail.refusal names which. It is a fresh ceremony, not a retry — the redemption policy decides. |
| Visit | "That cover is not in the selection" | A service line named a cover the selection does not carry. A cover outside it needs its own selection_ref and consent_ref, sent on the service line. |
| Bill | "No authorized service line for this charge" | A bill line drew on a service line that is pending or refused. There is no authorization for the charge to draw down until the line is authorized. |
| Bill | "Practitioner not on the visit" | The bill line referenced a practitioner_ref that was never added. Record the practitioner first; it is validated once, there. |
Errors
The rail's own refusals, before any payer is asked, carry a stable error code. Everything
else is the payer's verdict, relayed with its status intact. Validation failures on open and on a
service line (a missing consent_ref, a bad service_type, a missing selection_ref) carry no
code: error is the plain sentence, so switch on the status and read the message.
| HTTP | error | When |
|---|---|---|
| 400 | FACILITY_CONTEXT_MISSING | X-Facility-Id or X-Facility-Id-Type is missing or invalid. |
| 400 | CONSENT_REQUIRED | A service line names a cover and neither the request nor the visit holds a consent_ref. Not raised by open. |
| 400 | CONSENT_NOT_FOUND | consent_ref is not a UUID. |
| 404 | PATIENT_NOT_FOUND | The clinical store holds no patient under that identity. |
| 404 | CONSENT_NOT_FOUND | consent_ref resolves to nothing. |
| 404 | VISIT_NOT_FOUND | No visit under that reference. |
| 409 | VISIT_ALREADY_OPEN | The patient has an open visit; detail names it and its service-lines endpoint. |
| 409 | MULTIPLE_VISITS_OPEN | The patient has several open visits; detail.visit_refs lists them. |
| 409 | CONSENT_NOT_REDEEMABLE | Expired, consumed, unverified, wrong subject or wrong purpose — detail.refusal carries the AUTHN_* code. |
| 409 | SELECTION_UNUSABLE | The selection is unknown, inactive or another patient's, or a clinical visit sent no selection_ref with its first covered line. |
| 409 | COVER_NOT_IN_SELECTION | A line named a cover the selection does not carry. |
| 409 | VISIT_NOT_OPEN | The visit exists but no longer admits changes. |
| 409 | SERVICE_LINE_MISSING | A bill line named no authorized service line. |
| 409 | SERVICE_LINE_NOT_AUTHORIZED | The service line is pending or refused. |
| 409 | PRACTITIONER_NOT_ON_VISIT | The referenced practitioner was never added. |
| 422 | VISIT_LINE_REFUSED | A payer refused a line at open and the open was voided; detail maps each intervention code to the verdict. |
| 422 | PRACTITIONER_INVALID | The registry did not resolve the identification under its regulator. |
| 502 | PAYER_UNREACHABLE | The payer did not answer; the line stays pending and the call may be retried. |
| 502 | VISIT_WRITE_FAILED | The clinical store failed; nothing was recorded. Retry. |
| 502 | CONSENT_NOT_REDEEMABLE, SELECTION_UNUSABLE | The consent could not be checked, or the selection could not be read. Retry. |
Also registered
Other calls on the visit, listed so they are not a surprise. Each takes the facility headers. They have no reference entry yet.
| Call | What it does |
|---|---|
GET /api/v2/visits | The facility's visits; narrow with status and service_type. |
GET /api/v2/visits/{visit_ref}/service-lines | Every service line on the visit, across every cover. |
POST …/service-lines/{service_line_ref}/switch | Replace a line's intervention; the old line is superseded and a new one authorized. |
POST …/service-lines/{service_line_ref}/retire | Withdraw a line. Refused if it would leave a cover with no active line. |
POST …/service-lines/{service_line_ref}/restore | Bring a retired line back to authorized. |
POST …/service-lines/{service_line_ref}/coverage-check | Preview the coverage verdict and balance for billing an amount; no side effects. |
POST /api/v2/visits/{visit_ref}/cancel | Cancel a visit and withdraw every used cover's unsubmitted claim. |
POST /api/v2/visits/{visit_ref}/pause | Hold an open visit (encounter on hold); it admits no charges until resumed. |
POST /api/v2/visits/{visit_ref}/resume | Return a paused visit to in-progress. |
POST /api/v2/visits/{visit_ref}/copay/settle | Record a manual copay collection and return the copay ledger. |
POST /api/v2/visits/{visit_ref}/copay/collect | Send an M-Pesa STK prompt for the outstanding copay. |
POST /api/v2/visits/{visit_ref}/claim-attachments | Attach a supporting document to a cover's claim (multipart). |
POST /api/v2/visits/{visit_ref}/preauth-attachments | Attach a document to a submitted preauth (multipart). |
GET /api/v2/visits/{visit_ref}/attachment | Stream a stored attachment by its url query parameter. |
Next
Next: 05 · Treat — the clinical record on the open encounter, then 07 · Bill to charge under an authorized line.

