Short answer: in HL7 v2, an order (a lab test, an imaging exam, a medication) is sent as an ORM^O01 message in versions up to 2.5.1, or as an OML^O21 laboratory order message from version 2.4 onwards. Both carry the patient (PID), the visit (PV1), the ORC segment that controls the order (new, cancel, hold, status change, with placer and filler numbers) and the OBR segment that says what was ordered, by whom and for when. The filler system answers with an ORR (or ORL for OML) and later returns results as an ORU. The FHIR equivalent of ORC+OBR is a ServiceRequest.
A lab order, segment by segment
An HL7 v2 lab order message (ORM^O01) is built from segments: MSH names the message type and version, PID identifies the patient, PV1 describes the visit, ORC carries the order control code, placer and filler order numbers, priority and ordering provider, OBR names the requested test with a LOINC code and collection time, and DG1 gives the justifying diagnosis.
MSH|^~\&|EHR|GENHOSP|LIS|CENTRALLAB|20260314091200||ORM^O01^ORM_O01|MSG0001|P|2.5.1
PID|1||MRN-00012345^^^GENHOSP^MR||DOE^JANE||19800523|F|||12 High Street^^Leeds^^LS1 4AB^GB
PV1|1|O|CLINIC-3^^^GENHOSP||||42^SMITH^JOHN^^^Dr
ORC|NW|PLC-778812^EHR|||||^^^20260314093000^^R||20260314091200|42^SMITH^JOHN
OBR|1|PLC-778812^EHR||4548-4^Hemoglobin A1c/Hemoglobin.total in Blood^LN|||20260314093000||||||||42^SMITH^JOHN
DG1|1||E11.9^Type 2 diabetes mellitus without complications^I10
- MSH-9
ORM^O01^ORM_O01names the message type, trigger event and structure. MSH-12 gives the version. - PID identifies the patient; PID-3 holds the identifier with its assigning authority and type (
MR, medical record number). - PV1 gives the visit: outpatient (
O), the location, the attending clinician. - ORC-1 is the order control code:
NWnew order,CAcancel request,OCorder cancelled,HDhold,RLrelease,SCstatus changed,OKorder accepted,UAunable to accept,XOchange order,DCdiscontinue. ORC-2 is the placer order number (assigned by the ordering system), ORC-3 the filler order number (assigned by the lab, empty until it replies). ORC-7 holds timing and priority (Rroutine,Sstat,Aasap). ORC-12 is the ordering provider. - OBR-4 is the universal service identifier: what was ordered, coded (here LOINC,
LN). OBR-7 is the observation or collection date-time. OBR-16 repeats the ordering provider. In lab orders, specimen details sit in OBR-15 in older versions and in a dedicated SPM segment from 2.5. - DG1 carries the diagnosis that justifies the order.
The same order with multiple tests repeats the ORC/OBR pair once per test, each with its own OBR-1 set ID.
ORM vs OML
ORM^O01 is the general HL7 v2 order message, one loose structure for lab, radiology, pharmacy and supplies. OML, introduced in version 2.4, is the laboratory-specific order message with triggers O21, O33 and O35 and explicit SPM and SAC segments for specimens and containers. Most hospital-to-lab interfaces still run ORM^O01; OML appears in newer laboratory systems and IHE profiles.
ORM^O01 is the general order message: one structure for lab, radiology, pharmacy, dietary and supplies, which made it loose. From version 2.4, HL7 introduced OML (laboratory order) with several triggers, O21 (order by test), O33 (order by specimen) and O35 (order by specimen and container), and a stricter structure with SPM and SAC segments for specimens and containers. OMG (general clinical order), OMI (imaging), OMP (pharmacy) followed the same pattern. In practice, most hospital-to-lab interfaces still run on ORM^O01 in version 2.3.1 or 2.5.1, and OML appears in newer laboratory systems and in IHE's Laboratory Testing Workflow profile.
Responses
An HL7 v2 order receives two responses. An immediate ACK (MSA-1 AA, AE or AR) confirms the message was received and parsed. Then an application response, ORR^O02 for ORM or ORL^O22 for OML, repeats the ORC with OK or UA and fills in ORC-3, the filler order number. Results later return as ORU^R01 carrying both order numbers.
The receiving system answers twice. Immediately, with an ACK (MSA-1 AA accept, AE error, AR reject) that confirms the message was received and parsed. Then, as an application response, with ORR^O02 (for ORM) or ORL^O22 (for OML), repeating the ORC with OK or UA and filling in ORC-3, the filler order number, which both sides use from then on. Results come back as ORU^R01, with the same placer and filler numbers in OBR-2 and OBR-3, which is how a result finds its order. See HL7 v2 messages explained: ADT and ORU.
Where orders break
HL7 v2 orders break most often on mismatched placer and filler numbers when the ORR was not processed, local test codes in OBR-4 without a LOINC code, cancellations sent without the original placer number, version mismatches such as an SPM segment sent to a 2.3.1 receiver, and priority written in a free-text NTE instead of ORC-7 or OBR-5.
- Numbers that do not match: the ORU comes back with a filler number the EHR never saw, usually because the ORR was not processed.
- Local codes in OBR-4: a lab's internal test code instead of (or without) a LOINC code, so the receiving record cannot map the test. The fix is a code with both:
GLU^Glucose^L~2345-7^Glucose [Mass/volume] in Serum or Plasma^LN. - Cancellations without the original numbers:
CAmust carry the placer number of the order it cancels. - Version mismatches: an SPM segment sent to a 2.3.1 receiver is dropped or rejected.
- Priority in the wrong field:
STATin a free-text NTE instead of ORC-7 or OBR-5.
The same order in FHIR
In FHIR, an HL7 v2 order's ORC and OBR segments collapse into one ServiceRequest with status, intent order, priority, a LOINC code, subject, encounter, requester, occurrenceDateTime, reasonCode for the diagnosis and identifiers for the placer and filler numbers. The resulting Observation and DiagnosticReport reference it through basedOn, as HL7's v2-to-FHIR implementation guide maps.
In FHIR, ORC and OBR collapse into one ServiceRequest: status (active, on-hold, revoked, completed), intent (order), priority (routine, urgent, asap, stat), code (the LOINC test), subject, encounter, requester, occurrenceDateTime, reasonCode (the ICD-10 diagnosis) and identifier for the placer and filler numbers. The result Observation and DiagnosticReport point back with basedOn. HL7 publishes the field-by-field mapping in the v2-to-FHIR implementation guide.
Anpheros Platform supports ServiceRequest, Observation and DiagnosticReport, and its lab connector accepts results as HL7 v2 ORU, CSV or JSON. It does not send or receive orders; ordering stays in the hospital's or laboratory's systems, and the finished result joins the patient's record.
Related pages
- HL7 v2 messages explained: ADT and ORU
- HL7 vs FHIR
- PACS vs RIS vs VNA
- Lab connector: HL7 v2, CSV or JSON to FHIR
- What is a LOINC code?
- HL7 v2 to FHIR mapping (developers)
- How to integrate a laboratory information system with an EHR
- Interface engines explained
Sources
- HL7 Version 2 product suite
- HL7 v2.5.1 ORM_O01 reference (Caristix)
- HL7 v2.5.1 OML_O21 reference (Caristix)
- HL7 v2-to-FHIR implementation guide
- HL7 FHIR R4: ServiceRequest
- IHE Laboratory Testing Workflow (LTW)
Frequently asked questions
What is the difference between ORC and OBR?
ORC is about the order as an administrative object: who placed it, its numbers, its status, its priority. OBR is about the service requested: which test, on which specimen, when. Every OBR is preceded by its ORC.
What is a placer and a filler?
The placer is the system that asks for the service (the EHR or ordering physician's system); the filler is the system that performs it (the laboratory or radiology system). Each assigns its own order number, and messages carry both so either side can find the order.
Should I implement ORM or OML for a new lab interface?
If the partner supports OML^O21 in version 2.5.1 or later, prefer it: specimen handling is explicit and IHE profiles are built on it. If the partner is an older LIS, ORM^O01 is what it speaks, and you adapt.
How does an HL7 v2 order map to FHIR?
ORC and OBR together become a ServiceRequest; the placer and filler numbers become identifiers; ORC-1 and ORC-5 map to status; OBR-4 to code; DG1 to reasonCode; the ordering provider to requester. The HL7 v2-to-FHIR guide publishes the detailed tables.
Try it free in the sandbox
Your first FHIR call in 5 minutes. An HL7 FHIR R4 API with the patient's consent built in: try it in the sandbox, then connect your own app or clinic system.
Free · 30 synthetic patients · no card

The more you log, the clearer your record
Your health history in one place, under your control.
Free · Works in your browser · No card
