Orders, results and prescriptions
An order and a prescription have the same shape. Something is requested here, performed somewhere else, and answered back. Write the routing once and it covers both.
Everything below elaborates this sentence.
What changes when the request leaves the building
Inside one HMIS, ordering a test is a database write. The requester and the performer share a schema, so "routed to the lab" means a row with a status on it.
On the rail the performer may be a different organisation, running different software, in a different town. That works because neither side integrates with the other. Both are already on the rail, and the rail does the routing.
| Call | What it does | What you keep |
|---|---|---|
You order | A lab test, an image or a procedure. You name what you want and who should do it, and you never connect to them directly. | order_id |
They see it | The order lands in the performing facility's inbox as work, whether they run your software or somebody else's. | their queue |
They answer | Results are returned against the order and reach you as the requester. You do not build a second integration, and you do not poll a result mailbox per partner. | result_ref |
Orders
Order a lab, an image or a procedure, with the diagnosis that justifies it.
Three things about the response are worth building for.
| Call | What it does | What you keep |
|---|---|---|
Panels expand | An ordered panel comes back as its constituent parameters, each with its own code and reference range. The rail does that expansion, so do not keep a panel-to-parameter table of your own. | expanded_parameters[] |
Routing is a state you read | routed means the performer has it. If they are briefly unreachable the order is held and retried. That is not a failure, and it must not make you raise a second order. | status |
The reason travels | The diagnosis on the order is what a payer reads later to decide whether the test was indicated. An order with no reason can still be billed, and it can just as easily be rejected. | reason[] |
The orders routed to this facility. This is your work queue, and it holds requests from every requester on the rail.
A facility that only ever posts orders has built half the feature. The inbox is what makes you a performer as well as a requester, and it is the same call whether the request came from your own clinician or from a facility two counties away.
Results
Return the result. It reaches the requester, and it lands in the patient's record.
Return observations against the expanded parameter list the order came back with, rather than
against your own panel definition. A result that carries observations the order did not ask
for, or misses ones it did, is refused with RESULT_ORDER_MISMATCH instead of being stored
quietly against the wrong codes.
A result written this way does three jobs at once. It answers the requester, it becomes an
Observation in the shared record, and it is the evidence behind the line when the claim is
assessed. That is why you record clinically instead of billing directly.
Prescriptions
The prescription is the case where routing matters most, because the patient chooses where to fill it, and that is usually not where it was written.
Prescribe, routed to the pharmacy the patient names.
Per item
Required
medicationdoseroutefrequencyduration_daysquantity
Optional
substitution_allowedinstructions
medication is coded, with KEML as the national list. A free-text drug name gives you a prescription no other system can dispense against.
Per prescription
Required
diagnosisprescriber
Optional
route_to_facility
Omit route_to_facility and the prescription is open, so any pharmacy on the rail can claim it. Name one and only that pharmacy sees it.
Pulling what was routed to you
Prescriptions written anywhere on the rail and routed to this pharmacy.
This call is what takes paper off the pharmacy counter. The patient arrives with an identity rather than a slip, and you pull what was written for them and dispense against it.
Record what was actually handed over, including a partial fill or a substitution.
| Call | What it does | What you keep |
|---|---|---|
Partial fills accumulate | Dispensing 10 of 24 leaves 14. The next dispense, possibly at another pharmacy, reads what remains, and anything over that is refused. | quantity_remaining |
Substitution follows the prescriber's flag | Where the prescriber set substitution_allowed: false, a different product is refused. Send it back to the prescriber instead. | substitution_allowed |
Bill what was dispensed | A pharmacy line traces back to the dispense record rather than to the prescription, so bill the fill. | dispense_id |
What breaks here
| Where it surfaces | What the desk sees | What actually went wrong |
|---|---|---|
| Treat | "We raised the order twice because it looked stuck" | routed means held and retrying rather than failed. A duplicated order produces a duplicated specimen and two results against one clinical question. |
| Treat | "The result came back and the codes did not match anything" | Results were returned against a local panel definition rather than the expanded parameters the order carried. |
| Treat | "The pharmacy cannot see the prescription" | It was routed to a named facility that is not this one. Re-route it rather than re-writing it. |
| Bill | "We billed the prescription and were short-paid" | The patient took a partial fill. The dispense is the billable event, not the prescription. |
Errors
| HTTP | error | When |
|---|---|---|
| 502 | ORDER_PERFORMER_UNREACHABLE | The performing facility has not accepted the order yet. |
| 409 | RESULT_ORDER_MISMATCH | Observations returned do not match the order's parameters. |
| 403 | PRESCRIPTION_NOT_ROUTED_HERE | Dispensing against another pharmacy's prescription. |
| 409 | DISPENSE_EXCEEDS_PRESCRIBED | Cumulative dispensed quantity is over the prescribed one. |
| 409 | SUBSTITUTION_NOT_ALLOWED | A substitute was dispensed where the prescriber forbade it. |
Sending a specimen to a hub is an order that also has to travel. The authorisation the patient gave you moves with the referral, so they do not have to give it again at the other end.

