HL7v2 to FHIR - what you get per message
The FHIR resources produced for ADT, ORU, ORM, SIU, VXU, RDE, MDM, REF and MFN messages, and the segments each resource comes from.
An HL7v2 message is one flat list of segments, while FHIR splits the same information into separate resources - the patient in PID becomes a Patient, the visit in PV1 an Encounter, each OBX result an Observation. The tables below spell that mapping out, segment by segment and message family by message family.
What a converted bundle contains follows the segments actually present in the message, not a fixed list per message type. Every bundle opens with the MessageHeader built from MSH, followed by the Organization resources for the sending and receiving facilities from MSH-4 and MSH-6, which the header references as sender and receiver.
Segments and their resources
| Segment | FHIR resource | Notes |
|---|---|---|
| MSH | MessageHeader | Event coding from MSH-9, source and destination endpoints, focus points at the Patient and the Encounter, the MSH-4 and MSH-6 facilities become Organization resources referenced as sender and receiver, the MSH-17 country lands on the sender's address, MSH-19 is the header's language and each MSH-21 profile keeps a message-profile extension |
| SFT | - | Enriches the MessageHeader - the sending software's name and version go into source |
| MSA | - | Enriches the MessageHeader - the acknowledged control ID and outcome become response |
| ERR | OperationOutcome | One per ERR, pointed at from MessageHeader.response.details |
| EVN | - | Backs the Encounter period up when PV1-44 is empty - the event occurred time first, the recorded time second |
| PID | Patient | Identifiers, names, birth date, gender, addresses, telecoms, language, marital status, birth place, race, citizenship, multiple-birth and deceased indicators, the PID-12 county fills the address's district |
| PD1 | - | Enriches the Patient - organizations and practitioners become generalPractitioner |
| MRG | Patient | An inactive Patient carrying the prior identifiers, linked from the surviving one with replaces |
| PDA | - | Enriches the Patient - the death advice marks the patient deceased |
| NK1 | RelatedPerson | One per NK1 - name, relationship, address, telecom |
| GT1 | RelatedPerson | One per GT1 - the guarantor's name, relationship, address, telecom |
| PV1 | Encounter | Class, status, locations, attending, referring, consulting and admitting practitioners, service type, admit source, visit number, period |
| PV2 | - | Enriches the Encounter - admit reason and visit description become reasonCode, the prior pending location a planned location, the expected admit and discharge times the R5 planned start and end date extensions, the actual length of stay length, the referral source a participant, the visit priority priority and the mode of arrival its standard extension |
| ROL | - | Enriches the Encounter - each role becomes a participant with its Practitioner |
| ZBE | - | Enriches the Encounter - the IHE PAM movement IDs become identifiers |
| OBX | Observation | Value typing follows OBX-2, see below - plus the body site, the instance identifier, the analysis time and the performing organization with its address. In document messages a text OBX is the document body and an ED one an attachment, in result messages an ED OBX is the report's presentedForm |
| AL1 | AllergyIntolerance | One per AL1 - code, category, type, criticality, severity, reactions |
| IAM | AllergyIntolerance | One per IAM - the AL1 successor with action codes and onset |
| DG1 | Condition | One per DG1, also appended to Encounter.diagnosis with its use and rank - a working diagnosis is provisional, a final one confirmed |
| PRB | Condition | One per PRB in problem list messages - code, identifier, category problem-list-item, onset, resolution, confirmation and life cycle statuses |
| PR1 | Procedure | One per PR1 |
| IN1 | Coverage | One per IN1, plus the payor Organization |
| IN2 | - | Enriches the Coverage - everything IN2 carries is preserved on it |
| FT1 | ChargeItem | One per FT1 - code, quantity, occurrence, performer |
| ORC and OBR | ServiceRequest | One per order group in order and result messages, an ORC with no OBR after it still becomes one |
| OBR | DiagnosticReport | In result messages, one per OBR, linked basedOn its ServiceRequest |
| TQ1 | - | Enriches the ServiceRequest - start and end times become the occurrence. After a pharmacy segment it is the dosage timing of the medication resource, after an SCH the Appointment's start, end and duration |
| NTE | - | Becomes a note on the resource it follows - an Observation, a ServiceRequest or a medication resource - or the comment of an Appointment. With nothing to attach to it is preserved on the MessageHeader |
| SPM | Specimen | One per SPM, appended to the current report's specimen |
| SAC | - | Enriches the Specimen - the container identifier |
| SCH | Appointment | In scheduling messages - identifiers, status, timing, duration, the appointment reason from SCH-7, the contact people and the SCH-20 enterer as participants |
| ARQ | Appointment | In scheduling requests - a proposed Appointment |
| AIS, AIG, AIL, AIP | - | Enrich the Appointment - service type and participants, with Location and Practitioner resources where applicable |
| RXA | Immunization | In immunization messages - vaccine code, occurrence, dose, performer, lot number, manufacturer Organization, primarySource and reportOrigin from RXA-9 |
| RXA | MedicationAdministration | In every other message - medication, effective time or period, dose, performer |
| RXO | MedicationRequest | The original pharmacy order - medication, dose, dosage instructions, dispense request |
| RXE | MedicationRequest | The encoded pharmacy order - medication, dose, dispense request |
| RXG | MedicationRequest | The give instruction - medication, dose |
| RXD | MedicationDispense | The dispense - medication, quantity, handed-over time |
| RXR | - | Enriches the medication resource it follows - route and site |
| BPO | ServiceRequest | A blood product order and its ORC - product, processing requirements, quantity, intended use time, indications |
| IPC | - | Enriches the imaging ServiceRequest - accession number, procedure and protocol codes |
| ZDS | - | Enriches the imaging ServiceRequest - the study instance UID |
| RF1 | ServiceRequest | The referral - status, priority, type, identifiers, dates |
| PRD | - | Enriches the referral - the referring provider becomes requester, the referred-to one performer, both as Practitioners |
| TXA | DocumentReference | In document messages, body gathered from the text OBX segments that follow |
| STF | Practitioner | In master file notifications - identifiers, names, active flag, telecoms, addresses |
| PRA | - | Enriches the Practitioner - specialties become qualification, practitioner ID numbers identifiers |
| PRT | - | Enriches the nearest report, order, observation, condition, document or encounter with a participation |
| Z-segments | Basic | Preserved as extensions |
Repeating segments become multiple resources - three NK1 segments produce three RelatedPerson resources, five OBX segments five Observations, and so on.
Practitioner, Location and Organization resources are created on demand when a field references one, e.g. the attending doctor in PV1-7 or the assigned location in PV1-3, and identical entities are deduplicated across the whole bundle. A PL location such as WARD1^101^A^GENHOSP becomes a hierarchy of Location resources - the facility, the point of care, the room and the bed, each partOf the one before it and carrying its physicalType - and the Encounter points at the most specific one, which also takes the PL-5 location status as operationalStatus and the PL-6 person location type as type.
Any standard segment without a mapping of its own, and an enriching segment that arrives without the resource it enriches - a PV2 with no PV1, an RXR with no pharmacy segment - becomes a Basic resource the same way a Z-segment does.
Message families
The message structure from MSH-9 selects a conversion family, which determines how order-related segments group together:
| Family | Message structures | Adds on top of the common segments |
|---|---|---|
| Admissions and the rest | ADT and everything not listed below | Nothing - the common segments alone |
| Orders | ORM, OML, OMG, OMI, OMB, ORL, ORR | ServiceRequest per ORC/OBR group |
| Results | ORU, OUL | ServiceRequest and DiagnosticReport per group, with Observations in result and Specimens in specimen |
| Scheduling | SIU, SRM, SRR | Appointment with participants |
| Immunizations | VXU, VXR, RSP answering a CDC immunization query | Immunization per RXA |
| Medications | RAS, RGV, RDE, RDS, OMP | MedicationAdministration, MedicationRequest or MedicationDispense per pharmacy segment |
| Documents | MDM | DocumentReference from TXA and the text OBX body |
| Problems | PPR, PGL, PRR, PPP | Condition per PRB |
| Referrals | REF, RRI | ServiceRequest from RF1 with the PRD providers |
| Master files | MFN | Practitioner per STF |
An ORU^R01 example
from zato.hl7v2 import parse_hl7
raw = (
'MSH|^~\\&|LAB|FACILITY|EHR|FAC|20260315101112||ORU^R01^ORU_R01|CTL002|P|2.9\r'
'PID|||12345^^^HOSP^MR||SMITH^JOHN^A||19800115|M\r'
'ORC|RE|PLACER001|FILLER001\r'
'OBR|1|PLACER001|FILLER001|24331-1^Lipid panel^LN|||202603150930||||||||||||||||||F\r'
'OBX|1|NM|2093-3^Cholesterol^LN||187|mg/dL^^UCUM|<200|N|||F\r'
'NTE|1||Fasting sample\r'
'OBX|2|NM|2085-9^HDL cholesterol^LN||62|mg/dL^^UCUM|>40|N|||F\r'
'OBX|3|NM|2571-8^Triglycerides^LN||145|mg/dL^^UCUM|<150|N|||F\r'
'SPM|1|SPM001||SER^Serum\r'
)
msg = parse_hl7(raw, validate=False)
bundle = msg.to_fhir()
for entry in bundle.entry:
print(entry.resource.resource_type)
MessageHeader
Organization
Organization
Patient
ServiceRequest
DiagnosticReport
Observation
Observation
Observation
Specimen
Each Observation has a valueQuantity - 187, 62 and 145 mg/dL - and the NTE comment is stored in the first one's note. The DiagnosticReport is final from the F in OBR-25, lists all three Observations in result and the Specimen in specimen, and everything points back at the Patient.
Observation values
The OBX-2 value type determines how OBX-5 is represented:
| OBX-2 | FHIR element |
|---|---|
| NM | valueQuantity, with units from OBX-6 |
| ST, TX, FT | valueString |
| CE, CWE, CNE, CF, IS | valueCodeableConcept |
| SN | valueQuantity, valueRange or valueRatio, depending on the structured numeric |
| DT, DTM, TS | valueDateTime |
| TM | valueTime |
| ED | An attachment extension with the decoded content type and data - R4 observations have no attachment value of their own |
| RP | valueString with the whole reference pointer |
A valueQuantity carries system and code only when OBX-6 names a coding system, e.g. mg/dL^^UCUM. Units with no system keep the unit text alone, as the FHIR invariant on Quantity requires.
A value type the parser does not recognize is read as ST, so the value arrives as valueString. A recognized type outside this table, e.g. MO or CP, has no FHIR element to go to, so the type and the value are preserved as unmapped/OBX-2 and unmapped/OBX-5 extensions. Either way the value stays in the output.
See also
| Page | What it covers |
|---|---|
| Examples | Messages next to the FHIR they become, with the code that converts them |
| Automatic conversion | One call, a complete MLLP-to-FHIR service and validation |
| References and deduplication | How the resources point at each other and identical entities merge |
| Customizing code mappings | Standard tables, local values and unknown codes |
| Z-segments | Custom segments preserved as Basic resources with extensions |
Learn more
Schedule a meaningful demo
Book a demo with an expert who will help you build meaningful systems that match your ambitions
"We evaluated 12 integration platforms and Zato was the only one to score 100%."
Philip Zuñiga, Assistant Professor, University of the Philippines