HL7v2 Isn’t Legacy - It’s the Backbone
HL7v2 is so embedded in healthcare that people often forget to explain what it actually is. HL7v2 (Health Level Seven version 2) is a messaging standard that hospitals and clinics have used for decades to send and receive clinical and administrative data between systems. Think of it as the common language that lets an electronic health record, a lab system, a billing platform, and a patient registration system talk to each other without custom code for every connection.
Here’s the quick breakdown: It’s not a document or an API. HL7v2 messages are structured text strings, usually pipe-and-hat (|, ^, ~) delimited, that get fired off over a network - typically via TCP/IP - when something happens in the real world. It’s event-driven. A patient is admitted? That triggers an ADT^A01 message. A lab result is finalized? An ORU^R01 message goes out. The sending system doesn’t wait to be asked; it pushes the message because an event occurred.
It defines a set of message types that map to real workflows:
- ADT (Admit/Discharge/Transfer) – for patient demographics, movement, and registration.
- ORU (Observation Result Unsolicited) – for lab, radiology, and other results.
- ORM (Order Message) – for placing orders like a lab test or imaging.
- MDM (Medical Document Management) – for clinical notes and documents.
- SIU (Scheduling Information Unsolicited) – for appointment booking and updates.
It was born in 1989 and has been patched, profiled, and customized by nearly every major EHR vendor. That’s why it’s the workhorse: the interfaces already exist, and the EMR knows exactly how to process an ORU message into a flowsheet or an ADT into a patient chart update. In short, HL7v2 is the behind-the-scenes plumbing that makes real-time, event-driven healthcare data flow possible - and it’s still running most of the interoperability in the U.S. today.
1. ADT^A01 – Patient Admission
A patient arrives and is registered. The EMR sends out this ADT message so every downstream system (lab, pharmacy, billing) knows the patient exists.
Raw message:
MSH|^~\&|ADT_SYS|HOSPITAL|LAB_SYS|LAB|20260701120000||ADT^A01|123456|P|2.5
EVN|A01|20260701120000
PID|1||12345^^^HOSPITAL^MR||DOE^JOHN^||19800101|M|||123 MAIN ST^^METROPOLIS^NY^10001
PV1|1|I|WEST^201^A|2|||1234^SMITH^WILLIAM^A|5678^JONES^LISA^B|MED
Segment breakdown:
- MSH (Message Header): Sender (
ADT_SYS), receiver (LAB_SYS), message typeADT^A01, control ID123456, version 2.5. - EVN (Event Type): Confirms it’s an A01 admission event with a timestamp.
- PID (Patient Identification): Patient MRN
12345, name Doe, John, DOB, gender, address. - PV1 (Patient Visit): Inpatient admission (
I), room WEST 201 A, attending doctor Smith, referring doctor Jones, service MED.
2. ORU^R01 – Observation Result (Lab)
A lab result is finalized. The lab system pushes this unsolicited result message back to the EMR, and the EMR drops the value directly into the patient’s flowsheet.
Raw message:
MSH|^~\&|LAB_SYS|LAB|EMR_SYS|EMR|20260701130000||ORU^R01|987654|P|2.5
PID|1||12345^^^HOSPITAL^MR||DOE^JOHN^||19800101|M
OBR|1||L00123456|CBC^Complete Blood Count^L||20260701110000|20260701110000|||NORMAL|20260701110000
OBX|1|NM|26453-1^WBC^LN||7.2|10*3/uL|4.0-11.0|N|||F
OBX|2|NM|26454-0^RBC^LN||5.1|10*6/uL|4.5-5.9|N|||F
Segment breakdown:
- MSH: Message type
ORU^R01, sender lab, receiver EMR. - PID: Same patient identifier.
- OBR (Observation Request): Order number
L00123456, test CBC (Complete Blood Count), specimen collected time, status NORMAL. - OBX (Observation/Result): Each OBX is one result line. First OBX: WBC 7.2 x10³/μL, reference range 4.0-11.0, flagged N (normal). Second OBX: RBC 5.1 x10⁶/μL, reference range 4.5-5.9, normal.
The field separator | and component separator ^ let the receiving system parse 26453-1^WBC^LN into a LOINC code, test name, and coding system all from one string.
HL7v2 messages aren’t pretty - they’re a pipeline of events encoded as terse strings. But because nearly every EMR already knows how to handle an ADT, an ORU, or an ORM, these messages fire and land without custom API integration. That’s the practical power that keeps the standard alive.
Comments
No comments yet. Start the discussion.