HL7 v2 to FHIR mapping
Segment-to-resource and OBX field-by-field mapping from HL7 v2 ORU^R01 to FHIR R4, the traps that break integrations, and a converter you call over HTTPS.
Mapping HL7 v2 to FHIR means turning each segment of a pipe-delimited v2 message into FHIR R4 resources: PID into a Patient, OBR into a DiagnosticReport (or ServiceRequest), each OBX into an Observation, with codes, units, ranges and times carried over field by field. HL7 publishes an official V2-to-FHIR implementation guide with concept maps for the common segments. This page gives the practical mapping for laboratory results (ORU^R01), the traps that break real integrations, and a converter you can call over HTTPS: the Anpheros lab connector.
- MSHSeparators, message type, message id → MessageHeader or provenance
- PIDPatient identity → Patient (or, in Anpheros, the patient in the URL)
- OBRThe order and report → DiagnosticReport, report id and date
- OBXOne result each → Observation with LOINC, value, range, flag
- FHIR recordCoded, versioned resources your apps can read
Segment to resource
| HL7 v2 segment | What it carries | FHIR R4 resource | In the Anpheros lab connector |
|---|---|---|---|
| MSH | Separators, sending system, message type, message id | MessageHeader (or provenance) |
Separators read from MSH; type checked for ORU^R01; message id kept for traceability |
| PID | Patient identifiers, name, birth date, sex | Patient |
Not used: the patient is the one in the request URL, so a message cannot write into the wrong record |
| PV1 | Visit | Encounter |
Not used |
| ORC / OBR | Order and report: filler/placer id, date | ServiceRequest, DiagnosticReport |
OBR-3 (or OBR-2) is the report id, OBR-7 the default date |
| OBX | One result | Observation |
One laboratory Observation per OBX |
| NTE | Free-text note | Observation.note |
Not used |
OBX field by field
| OBX field | FHIR Observation element | Notes |
|---|---|---|
| OBX-2 value type (NM, SN, ST, CWE) | choice of value[x] |
NM and SN become valueQuantity; text stays text |
OBX-3 identifier code^text^system |
code.coding |
LN in OBX-3.3 means LOINC; other systems are the lab's local code |
| OBX-5 value, OBX-6 unit | valueQuantity.value, .unit / .code (UCUM) |
<5 and 6,4 must be parsed deliberately |
| OBX-7 reference range | referenceRange.low / .high |
3.5-5.1, <200, >40 |
| OBX-8 abnormal flag | interpretation |
H, L, HH, LL, A, N |
| OBX-11 result status | status |
F → final, C → amended, P → preliminary, I → registered |
| OBX-14 observation time | effectiveDateTime |
v2 times often lack a time zone; FHIR requires one |
Convert a message with one request
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/labs/import" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: x-application/hl7-v2+er7" \
-H "Idempotency-Key: $(uuidgen)" \
--data-binary @oru_r01.hl7
The answer lists how many Observations were created, how many were skipped as already imported, which markers could not be mapped, and the new Observations with their codes. Each one gets a stable identifier derived from the report, the test, the time and the value, so a laboratory that resends the same message creates no duplicates.
Traps that break real integrations
- Time zones.
20261002074500has no offset; decide the sender's zone explicitly. - Local codes. Keep the lab's own code when there is no LOINC; never drop it.
- Resends. Without a stable identifier per result, retries become duplicates.
- Corrections. OBX-11
Cis a correction; decide whether it replaces or adds, and mark the old result. - Non-numeric values.
positive,<5,6,4need explicit rules, not a guess.
What the connector does not do
It accepts ORU^R01 laboratory results over HTTPS. It does not receive ADT or order messages, does not speak MLLP over TCP (an interface engine in front can forward), does not create a DiagnosticReport, and does not match patients from PID.
Frequently asked questions
How do you map HL7 v2 to FHIR?
Segment by segment: PID to Patient, PV1 to Encounter, ORC/OBR to ServiceRequest and DiagnosticReport, OBX to Observation, NTE to notes. HL7's V2-to-FHIR implementation guide defines the field-level concept maps.
Is there an HL7 v2 to FHIR converter?
Yes. Interface engines and open-source libraries convert messages; for laboratory results, the Anpheros lab connector converts an ORU^R01 message into FHIR R4 Observations in one HTTPS request and stores them in the patient's record.
Which HL7 v2 message types does Anpheros accept?
ORU^R01 laboratory results. A message of another type gets a warning, and only its OBX segments are read; ADT, order and other messages are not supported.
How are HL7 v2 abnormal flags represented in FHIR?
OBX-8 becomes Observation.interpretation using the HL7 ObservationInterpretation codes (H, L, HH, LL, A, N).