HL7 v2 is the language hospitals use to talk to each other. Here's how to read it — one picture at a time.
HL7 v2 has been the backbone of hospital messaging since 1987. Version 2.5.1 is the most widely deployed today.
A message is not a blob of text. It's a carefully structured document with three levels of nesting: segments → fields → components.
PID = Patient Identification|. Position 1, 2, 3, ...^. Sub-parts of a field.One line = one segment. Starts with a 3-letter code (MSH, PID, PV1...). Each carries a specific kind of information.
Parts of a segment, separated by the pipe |. Each position has a fixed meaning (PID-5 is always the patient name).
Parts of a field, separated by ^. Patient name DOE^JOHN^A = Family DOE, Given JOHN, Middle A.
Repeating values inside a field, separated by ~. Multiple phone numbers: 555-1111~555-2222.
Every HL7 message starts with MSH. Other segments appear based on the message type.
Click each card to see a real example.
HL7 uses five special characters to break up a message. They're declared in MSH-1 and MSH-2 — so they can technically change per message!
MSH-1.PID|1|123|DOEMSH-2.1.DOE^JOHN^AMSH-2.2.555-1111~555-2222MSH-2.3.\F\ = literal pipeMSH-2.4.AUTH&MRN
Each segment has numbered positions. We write them as SEG-N, e.g. PID-5.
The count starts at 1 after the segment name.
||) means the field exists but is empty.
That's different from the field being absent.
Here's an actual ADT^A01 (patient admission). Click any line to see what it means.
Click any line to see its explanation.
The MSH-9 field tells you the message type and trigger event, written as TYPE^EVENT.
Mistakes that trip up newcomers and experienced engineers alike.
Most systems use |^~\&, but the spec allows any. Always read MSH-1 and MSH-2 before parsing.
PID|1||X means field 2 is empty. PID|1|X means field 2 is X and field 3 doesn't exist. Both are legal.
Never trim spaces inside field values — some systems use them as part of the value. Only trim around the delimiters.
MSH-12 tells you the version. Field meanings change between 2.3 and 2.5.1. Always parse version-aware.
HL7 uses \r as segment terminator. Some systems send \r\n or just \n. Normalize first.
HL7 messages often carry names, MRNs, and dates of birth. Never log them in plaintext or send over non-TLS connections.
Paste a real (synthetic) HL7 message and see every field annotated live.
Open HL7 Inspector