Lesson 4 of 51 · Message Structure in Depth

The MSH Header, Field by Field

MSH Header

Every HL7 v2 message opens with a single segment: the Message Header, or MSH. If a message is a stack of segments whose fields are separated by | and whose components are separated by ^, then MSH is the segment that bootstraps the whole arrangement. It declares the delimiters the rest of the message will use, identifies who is talking to whom, stamps the message in time, says what kind of message this is, and tells the receiver how to acknowledge it. A receiving system reads MSH first, and from it learns how to parse and route everything that follows 1.

A sample MSH line

MSH|^~\&|EPIC_ADT|HOSP_A|LAB_SYS|LAB_B|20260601083000||ADT^A01^ADT_A01|MSG00001|P|2.5.1||||AL|NE

The fields below are numbered from the literal MSH. A subtle but important quirk: MSH-1 is the field separator itself, which shifts the numbering by one relative to every other segment.

MSH-1 and MSH-2: the encoding contract

MSH-1 is the field separator. It is the very first character after MSH — in the sample, the |. Rather than being a value sitting between delimiters, it is read positionally as the delimiter, then reused to split the rest of the message. MSH-2 holds the remaining encoding characters in a fixed order: component separator (^), repetition separator (~), escape character (\), and subcomponent separator (&). Together MSH-1 and MSH-2 form a self-describing contract: the message announces its own punctuation before any of it is needed 1. Standard practice is |^~\&, and most interfaces assume it, but a conformant parser should read these characters rather than hard-code them 2.

MSH-3 to MSH-6: routing

These four fields name the endpoints of the exchange:

Field Name Sample value
MSH-3 Sending Application EPIC_ADT
MSH-4 Sending Facility HOSP_A
MSH-5 Receiving Application LAB_SYS
MSH-6 Receiving Facility LAB_B

Operationally, this is addressing information. Integration engines route on these values, deciding which downstream system receives a copy and which interface profile to apply. Sender identifiers also let a receiver apply per-source rules — different vocabularies, trust levels, or transformations — because the same trigger event can carry subtly different data depending on origin 2. Facility fields disambiguate applications that share a name across sites within a health system.

MSH-7: date/time of message

MSH-7 records when the message was created, in HL7’s timestamp format (YYYYMMDDHHMMSS, optionally with fractional seconds and a timezone offset). It supports auditing, ordering, and troubleshooting: when messages arrive out of sequence or a backlog drains, MSH-7 tells operators when each was actually generated rather than merely when it arrived 1.

MSH-9: message type

MSH-9 answers “what is this message?” and is itself composite, built from components separated by ^:

ADT^A01^ADT_A01
  • The message code (ADT) is the broad category — here, Admit/Discharge/Transfer.
  • The trigger event (A01) is the real-world event that produced the message — A01 is a patient admission.
  • The message structure (ADT_A01) names the exact segment grammar the receiver should expect, so it can validate the layout.

Receivers commonly branch their entire processing logic on MSH-9: an ADT^A01 is handled very differently from an ORU^R01 lab result 1.

MSH-10: message control id

MSH-10 is a unique identifier the sender assigns to this message (MSG00001). Its central job is acknowledgment matching: when the receiver replies, it echoes this control id back in the acknowledgment, letting the sender pair each response with the original message and detect any that went unanswered. Because reliable delivery depends on it, MSH-10 must be unique enough that two distinct messages never collide 2.

MSH-11: processing id

MSH-11 declares the environment: P for production, T for training/test, D for debugging. This single character is a critical safety control. A receiver configured for production can reject or quarantine anything marked T, preventing test admissions or fictitious lab results from polluting a live patient record. Misusing it — sending P from a test harness — is a classic cause of real-world data incidents 2.

MSH-12: version id

MSH-12 states which release of the standard the message conforms to (2.5.1). Because v2 evolved across many backward-compatible releases, a receiver uses this for version negotiation: selecting the right parsing rules and knowing which fields may legitimately be present 1.

MSH-15 and MSH-16: acknowledgment types

These two fields tell the receiver how to acknowledge. MSH-15, the accept acknowledgment type, governs the immediate “I received this” response at the transport layer. MSH-16, the application acknowledgment type, governs a later “the application processed this” response. Common values are AL (always), NE (never), SU (on success), and ER (on error); in the sample, AL then NE requests an accept acknowledgment but no separate application one. Setting these correctly is what makes a v2 interface reliable rather than fire-and-forget 1.

Why MSH is the keystone

Read top to bottom, MSH is a compact operational summary: how to parse (MSH-1/2), where it goes (MSH-3 to MSH-6), when it happened (MSH-7), what it is (MSH-9), how to track it (MSH-10), which environment it belongs to (MSH-11), which rules apply (MSH-12), and how to confirm receipt (MSH-15/16). Master these fields and the rest of any v2 message becomes far easier to read.

References

  1. HL7 Standards — Section 1d: Version 2 (V2). HL7 International. verified
  2. Tim Benson, Grahame Grieve. Principles of Health Interoperability: FHIR, HL7 and SNOMED CT. 4th ed. Springer. 2021. verified