NEWFree ROI Calculators — quantify what prior auth and siloed data are costing your organization.Prior Auth ROI Siloed Data ROI
HL7 v2Data Type8 min read

HL7 MSG Data Type: Message Type

The MSG (Message Type) data type was introduced as a composite in HL7 v2.4. Before v2.4, MSH-9 carried three separate fields (Message Code, Trigger Event, Message Structure) glued together by position and convention; v2.4 promoted them to a single typed composite, MSG, with three explicit components. From v2.4 onwards, MSG appears in exactly one place — MSH-9 — but that one place is the most important field in the entire message: it is what tells the receiver "this is an ADT, trigger A01, parse it as the ADT_A01 structure."

Purpose

MSG exists to give a receiver three pieces of information at once: what kind of message is this (Message Code), what real-world event triggered it (Trigger Event), and which exact structural template should the parser use (Message Structure). The third component is the one that engineers most often omit and most often need: many trigger events share a single structure (ADT_A01 covers A01 admit, A04 register-outpatient, A08 update-patient-information, and A13 cancel-discharge — all four trigger events are parsed using the same segment graph), and several pairs of trigger events that look related have different structures (ADT_A39 patient merge has a different structure from ADT_A01).

Without MSG.3, the receiver must maintain its own trigger-event-to-structure lookup table — and that table changes across HL7 versions. With MSG.3, the sender tells the receiver exactly which template to use, every time.

Component reference

Source: HAPI HL7v2 v2.8.1 javadocs — MSG. MSG has three components separated by ^. Length is not published in the javadocs ().

SeqNameData TypeLengthReqTableDescription
MSG.1Message CodeidR[HL70076]Three-letter message code — ADT, ORU, ORM, SIU, MDM, DFT, MFN, BAR, RDE, RGV, RAS, OMG, etc. Identifies the category of message.
MSG.2Trigger EventidR[HL70003]Trigger-event code paired with the message code — A01, A04, A08, R01, O01, S12, T02, etc. Names the real-world event.
MSG.3Message StructureidR[HL70354]Structure ID — ADT_A01, ORU_R01, ORM_O01, SIU_S12, MDM_T02. Names the segment-grammar template the parser should apply. Required from v2.4 onwards.

The composite is read together: MSG.1 + ^ + MSG.2 yields the conventional ADT^A01 display form; MSG.3 disambiguates structures when several trigger events share one.

Most-used components

  • MSG.1 Message Code — the category. Routing engines first triage on this single value (ADT to the registration pipeline, ORU to results, ORM to orders, SIU to scheduling).
  • MSG.2 Trigger Event — the event that produced the message. Within ADT, A01 admit and A03 discharge fan out to different downstream consumers even though both share MSG.1=ADT.
  • MSG.3 Message Structure — the parser key. Tells the receiver which structure definition to use. Several trigger events share a structure (ADT_A01 covers A01, A04, A08, A13), so MSG.3 is not redundant with MSG.2 — it is strictly more specific in one direction and strictly less specific in the other.

Where it's used

MSG appears in exactly one field across all of HL7 v2:

  • MSH-9 Message Type — the only field typed as MSG. Every conforming v2.4+ message carries one MSG in MSH-9, and that MSG is what gets logged, routed, acknowledged (via the matching MSA-2 control ID and MSA-1 acknowledgment code), and parsed.

That single placement is deceptive about its importance. MSH-9 is the second most-read field in any HL7 message after MSH-10 Message Control ID — every routing engine, audit log, replay tool, and conformance test reads MSH-9 to decide what the message is before reading anything else.

Version differences

  • v2.1 / v2.2 / v2.3 / v2.3.1 — MSH-9 was a string field carrying MessageCode^TriggerEvent (two components, no composite type). Some senders emitted a third component for structure; receivers parsed it positionally.
  • v2.4 — MSG composite introduced. MSH-9 retyped as MSG. Message Structure (MSG.3) became formally part of the type, although many senders continued to omit it during the v2.3→v2.4 transition.
  • v2.5 / v2.5.1 — MSG.3 conformance tightened; HL7 table 0354 (Message Structure) curated as the canonical structure-ID list.
  • v2.6 / v2.7 / v2.7.1 — No structural changes to MSG. New trigger events added to HL70003; new structure IDs added to HL70354.
  • v2.8 / v2.8.1 / v2.8.2 — Structurally stable. HAPI v2.8.1 javadoc reflects the three-component layout unchanged.

Common mistakes

  • Omitting MSG.3 Message Structure. ADT^A01 parses on lenient engines but is ambiguous on strict ones — and replay tools that hash on structure cannot index the message. Always emit the third component (ADT^A01^ADT_A01).
  • Mismatching MSG.2 and MSG.3. Sending ADT^A08^ADT_A04 is technically permissible (both A04 and A08 share the ADT_A01 structure in modern profiles), but most senders intend ADT^A08^ADT_A01. The _A04 form is almost always a copy-paste bug from a v2.3 template.
  • Inventing structure IDs. ADT^A08^ADT_A08_v2 or ORU^R01^ORU_R01_LAB are not in HL70354. Custom structures must be declared in a conformance profile, not invented in MSG.3.
  • Treating MSG.1 as case-insensitive. HL7 v2 IDs are case-sensitive in conformance contexts. adt^a01^adt_a01 will be rejected by strict parsers and silently miscategorized by lenient ones.
  • Underscore vs caret confusion. MSG.3 uses an underscore (ADT_A01), not a caret (ADT^A01). The caret is the component delimiter inside MSG itself; using it inside MSG.3 produces a four-component MSG that does not parse.
  • Sending ACK in MSG.2 instead of MSG.1. ACK is the message code for an acknowledgment; its trigger event is the trigger of the original message (e.g. ACK^A01^ACK). Putting ACK in MSG.2 produces a nonsense composite.

Examples

Minimal value (legal on v2.3-and-earlier emitters but discouraged):

ADT^A01

Conformant v2.4+ value with all three components:

ADT^A01^ADT_A01

Trigger events that share a structure:

ADT^A04^ADT_A01      ; register outpatient — same structure as A01
ADT^A08^ADT_A01      ; update patient info — same structure as A01
ADT^A13^ADT_A01      ; cancel discharge — same structure as A01
ADT^A39^ADT_A39      ; patient merge — distinct structure

Other common message types:

ORU^R01^ORU_R01      ; unsolicited observation result
ORM^O01^ORM_O01      ; order message (legacy)
OMG^O19^OMG_O19      ; general order (v2.5+)
SIU^S12^SIU_S12      ; new appointment
MDM^T02^MDM_T02      ; document notification with content
ACK^A01^ACK          ; acknowledgment of an ADT^A01

In context — full MSH segment carrying an ADT^A08 update:

MSH|^~&|EMR|MERCY^2.16.840.1.113883.19.5^ISO|EHR|MERCY|20260624101530-0500||ADT^A08^ADT_A01|MSG-ADT-77321|P|2.8.1
EVN|A08|20260624101530-0500
PID|1||MR884412^^^MERCY&2.16.840.1.113883.19.5&ISO^MR||TESTPATIENT^ALEX^Q||19720508|F
PV1|1|I|3W^301^A^MERCY||||9988^Reyes^Marta^L^^^MD

In context — an unsolicited lab result:

MSH|^~&|LIS|MERCY^2.16.840.1.113883.19.5^ISO|EMR|MERCY|20260624110000-0500||ORU^R01^ORU_R01|MSG-LAB-44210|P|2.8.1

Common pitfall — MSG.3 omitted:

MSH|^~&|EMR|MERCY|EHR|MERCY|20260624101530-0500||ADT^A08|MSG-ADT-77321|P|2.8.1

ADT^A08 alone is parseable but ambiguous: the receiver must consult its own trigger-event-to-structure table to know that A08 uses ADT_A01. Strict v2.8.1 conformance profiles flag this.

Common pitfall — wrong structure paired with trigger:

MSH|^~&|EMR|MERCY|EHR|MERCY|20260624101530-0500||ADT^A39^ADT_A01|MSG-MRG-1|P|2.8.1

A39 (patient merge) does not use the ADT_A01 structure; it uses ADT_A39. The parser will read MRG and find segments out of expected order, then either reject the message or misroute the merge.

FHIR mapping

The HL7 v2-to-FHIR Implementation Guide publishes three ConceptMaps for MSG:

  • datatype-msg-to-coding — MSG.1 + MSG.2 combined into a single Coding (system http://terminology.hl7.org/CodeSystem/v2-0003, code ADT_A01-style).
  • datatype-msg-to-messageheader — drives the surrounding MessageHeader resource; MessageHeader.eventCoding is populated from the MSG composite.
  • datatype-msg-to-code — for profiles that need only the bare event code as a string.

Component-level mapping:

HL7 v2FHIR target
MSG.1 Message Codeembedded in MessageHeader.eventCoding.code (concatenated with MSG.2)
MSG.2 Trigger Eventembedded in MessageHeader.eventCoding.code
MSG.3 Message Structureno direct equivalent — FHIR's resource graph is its own structure

FHIR MessageHeader does not advertise message structure separately because the FHIR Bundle layout is the structure. Round-tripping HL7 → FHIR → HL7 requires the converter to re-derive MSG.3 from MSG.2 using a curated trigger-event-to-structure table, which is why most production converters carry one.

Engine considerations

  • Routing key. Most engines route on MSG.1 alone, then fan out on MSG.2. Treating MSG.1+MSG.2 as a single tuple is more robust: ADT^A01 and ADT^A03 go to different destinations even though they share MSG.1.
  • Structure validation. Strict profiles validate MSG.3 against HL70354 and against the actual segment graph parsed from the message. A claim of ADT_A01 followed by an MRG segment is internally inconsistent.
  • Replay and idempotency. Replay tools should index messages by (MSH-10 Message Control ID, MSG.1, MSG.2, MSG.3); using only MSH-10 is insufficient when senders reuse control IDs across message types.
  • Acknowledgment construction. ACK messages echo the original MSG with ACK in MSG.1 and the original MSG.2 as the trigger — for example, ACK^A01^ACK. Some senders emit ACK^^ACK, dropping MSG.2; modern profiles consider this non-conformant.
  • HAPI typing. ca.uhn.hl7v2.model.v281.datatype.MSG exposes typed accessors getMessageCode(), getTriggerEvent(), getMessageStructure(). Each returns an ID instance. Code that imports a different version's MSG class (e.g. v2.3 had no MSG type at all) will not compile against v2.8.1 structures.
  • Version mismatch with MSH-12. A v2.8.1 message that carries MSG.3=ADT_A04 (a structure ID that v2.7+ no longer publishes as canonical for A04) will load but should trigger a profile-version warning.

How Vorro parses and produces MSG

Vorro treats MSG as the primary routing key. On inbound, every message is parsed into (messageCode, triggerEvent, messageStructure) and the tuple drives the dispatch table — ADT^A01^ADT_A01 lands on the registration pipeline, ORU^R01^ORU_R01 on the results pipeline, SIU^S12^SIU_S12 on scheduling. When MSG.3 is missing, Vorro derives it from a curated trigger-event-to-structure table keyed off MSH-12 (the version identifier) and tags the message with provenance so the receiver can distinguish "structure asserted by sender" from "structure inferred at ingress."

When MSG.2 and MSG.3 disagree (e.g. A39 paired with ADT_A01), Vorro rejects the message at the edge rather than risk silent misrouting. On outbound, all three components are always emitted; Vorro never produces a two-component MSG even when the destination claims to be v2.3.

Sources

← Back to HL7 v2 Guide

Ready to Integrate This Into Your Workflow?

Talk to a Vorro expert about implementing HL7 v2 in your specific environment.

Browse HL7 v2 Guides
HL7 MSG Data Type: Message Type | Vorro Academy | Vorro