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

SegmentFHIR resourceNotes
MSHMessageHeaderEvent 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
ERROperationOutcomeOne 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
PIDPatientIdentifiers, 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
MRGPatientAn inactive Patient carrying the prior identifiers, linked from the surviving one with replaces
PDA-Enriches the Patient - the death advice marks the patient deceased
NK1RelatedPersonOne per NK1 - name, relationship, address, telecom
GT1RelatedPersonOne per GT1 - the guarantor's name, relationship, address, telecom
PV1EncounterClass, 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
OBXObservationValue 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
AL1AllergyIntoleranceOne per AL1 - code, category, type, criticality, severity, reactions
IAMAllergyIntoleranceOne per IAM - the AL1 successor with action codes and onset
DG1ConditionOne per DG1, also appended to Encounter.diagnosis with its use and rank - a working diagnosis is provisional, a final one confirmed
PRBConditionOne per PRB in problem list messages - code, identifier, category problem-list-item, onset, resolution, confirmation and life cycle statuses
PR1ProcedureOne per PR1
IN1CoverageOne per IN1, plus the payor Organization
IN2-Enriches the Coverage - everything IN2 carries is preserved on it
FT1ChargeItemOne per FT1 - code, quantity, occurrence, performer
ORC and OBRServiceRequestOne per order group in order and result messages, an ORC with no OBR after it still becomes one
OBRDiagnosticReportIn 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
SPMSpecimenOne per SPM, appended to the current report's specimen
SAC-Enriches the Specimen - the container identifier
SCHAppointmentIn scheduling messages - identifiers, status, timing, duration, the appointment reason from SCH-7, the contact people and the SCH-20 enterer as participants
ARQAppointmentIn scheduling requests - a proposed Appointment
AIS, AIG, AIL, AIP-Enrich the Appointment - service type and participants, with Location and Practitioner resources where applicable
RXAImmunizationIn immunization messages - vaccine code, occurrence, dose, performer, lot number, manufacturer Organization, primarySource and reportOrigin from RXA-9
RXAMedicationAdministrationIn every other message - medication, effective time or period, dose, performer
RXOMedicationRequestThe original pharmacy order - medication, dose, dosage instructions, dispense request
RXEMedicationRequestThe encoded pharmacy order - medication, dose, dispense request
RXGMedicationRequestThe give instruction - medication, dose
RXDMedicationDispenseThe dispense - medication, quantity, handed-over time
RXR-Enriches the medication resource it follows - route and site
BPOServiceRequestA 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
RF1ServiceRequestThe referral - status, priority, type, identifiers, dates
PRD-Enriches the referral - the referring provider becomes requester, the referred-to one performer, both as Practitioners
TXADocumentReferenceIn document messages, body gathered from the text OBX segments that follow
STFPractitionerIn 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-segmentsBasicPreserved 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:

FamilyMessage structuresAdds on top of the common segments
Admissions and the restADT and everything not listed belowNothing - the common segments alone
OrdersORM, OML, OMG, OMI, OMB, ORL, ORRServiceRequest per ORC/OBR group
ResultsORU, OULServiceRequest and DiagnosticReport per group, with Observations in result and Specimens in specimen
SchedulingSIU, SRM, SRRAppointment with participants
ImmunizationsVXU, VXR, RSP answering a CDC immunization queryImmunization per RXA
MedicationsRAS, RGV, RDE, RDS, OMPMedicationAdministration, MedicationRequest or MedicationDispense per pharmacy segment
DocumentsMDMDocumentReference from TXA and the text OBX body
ProblemsPPR, PGL, PRR, PPPCondition per PRB
ReferralsREF, RRIServiceRequest from RF1 with the PRD providers
Master filesMFNPractitioner 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-2FHIR element
NMvalueQuantity, with units from OBX-6
ST, TX, FTvalueString
CE, CWE, CNE, CF, ISvalueCodeableConcept
SNvalueQuantity, valueRange or valueRatio, depending on the structured numeric
DT, DTM, TSvalueDateTime
TMvalueTime
EDAn attachment extension with the decoded content type and data - R4 observations have no attachment value of their own
RPvalueString 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

PageWhat it covers
ExamplesMessages next to the FHIR they become, with the code that converts them
Automatic conversionOne call, a complete MLLP-to-FHIR service and validation
References and deduplicationHow the resources point at each other and identical entities merge
Customizing code mappingsStandard tables, local values and unknown codes
Z-segmentsCustom 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