Lesson 3 of 51 · Foundations
How v2 Messages Are Exchanged — Acknowledgments and MLLP
From a message to a conversation
The previous lesson took apart a single message — its segments, fields, and the
encoding characters declared in MSH. But a message in isolation is only half of
an interface. In production, the sender needs to know the message arrived and
was understood. HL7 v2 answers that with an acknowledgment exchange and,
beneath it, a framing protocol that marks where each message begins and ends on
the wire.

The acknowledgment paradigm
When an application sends a message, two fields in the MSH segment declare what
kind of reply it expects: MSH-15 (accept acknowledgment type) and MSH-16
(application acknowledgment type). These let the sender ask for confirmation that
the message was received (accept) and, separately, that it was processed
(application) 1.
The reply is itself a message — type ACK — whose key content is the MSA
(message acknowledgment) segment. The most important field, MSA-1, carries an
acknowledgment code:
MSH|^~\&|LAB|HOSP|ADT1|HOSP|202406011230||ACK|MSG00001|P|2.5
MSA|AA|MSG00001
- AA — Application Accept: received and processed successfully.
- AE — Application Error: received, but a problem occurred (often with an
accompanying
ERRsegment describing it). - AR — Application Reject: rejected, typically for a structural or sequencing problem rather than a data error.
MSA-2 echoes the original message’s control id (MSH-10) so the sender can match
the acknowledgment to the message it sent 2. This pairing —
every message answered by an ACK that names it — is what turns a one-way send
into a reliable conversation.
Original vs. enhanced mode. Early v2 used a single acknowledgment. Later versions separated accept from application acknowledgment so a busy receiver can immediately confirm receipt, then send a second acknowledgment once processing finishes.
MSH-15andMSH-16select the mode per message.
MLLP: framing messages on a TCP stream
An acknowledgment paradigm assumes both sides can tell where one message stops and the next starts. TCP, however, is a continuous byte stream — it has no notion of “message.” The near-universal solution is the Minimal Lower Layer Protocol (MLLP), which wraps each message in framing characters 3:
<VT> <the entire HL7 message> <FS><CR>
where <VT> is the vertical-tab byte (0x0B) marking the start of a block, and
<FS><CR> (0x1C 0x0D) marks the end. A receiver reads bytes until it sees the
end-of-block sequence, then hands the framed content to its HL7 parser.
MLLP “has a long history of use within the HL7 community” and is the default
transport for essentially every v2 integration engine, even though it sits below
the message standard itself rather than inside it 3. Its Release 2 adds
commit acknowledgments to make the transport itself reliable, distinct from the
application-level ACK described above 3.
Why this matters before moving on
Segments tell you what a message says; the acknowledgment and MLLP layers tell
you whether it was delivered and accepted. Most real-world interface
troubleshooting — messages that “disappear,” duplicate sends, stalled queues —
lives in exactly this layer. Keep the two halves distinct: MLLP guarantees the
bytes were framed and received; the MSA acknowledgment tells you what the
application did with them.
References
- HL7 Standards — Section 1d: Version 2 (V2). HL7 International. verified
- Tim Benson, Grahame Grieve. Principles of Health Interoperability: FHIR, HL7 and SNOMED CT. 4th ed. Springer. 2021. verified
- HL7 Transport Specifications — MLLP (Minimal Lower Layer Protocol). HL7 International. verified