ADT and ORM are the two HL7v2 message families that almost every US integration team has to handle. ADT carries admit, discharge, and transfer events; ORM carries clinical orders. They look superficially similar, and the conversion to FHIR Patient, Encounter, and ServiceRequest gets framed as one job. In practice, the two messages are not equally hard to convert, and the team that treats them the same way usually loses time on whichever one they underestimated.
This comparison walks through where each is genuinely harder. The wider US-practice context is in the Jaro-Winkler vs Soundex for patient-name matching in US practice piece, since identity resolution sits next to ADT conversion in any real pipeline. The rest of the series lives at more on healthcare interoperability in the USA.
What Each Message Actually Carries
ADT messages describe patient state changes: admit (A01), discharge (A03), transfer (A02), update (A08), merge (A40), and the long tail of trigger events. The payload is a Patient, an Encounter, often a few related resources (Practitioner, Location, Organization), and the event semantics that say which trigger fired.
ORM messages describe orders: medication, lab, imaging, referral. The payload is a Patient (again), a ServiceRequest (or a MedicationRequest, depending on the order type), one or more order-related resources, and the order control codes that say what kind of order action this is.
The two look symmetrical. They are not.
Where ADT Is Harder
ADT is harder than most teams expect because of trigger-event semantics and Patient merge logic. A01 maps cleanly to a new Encounter with status in-progress. A03 maps cleanly to an Encounter update with finished. A02 maps to a Location change inside an Encounter. So far, so straightforward.
The trouble starts at A08, the update event. A08 carries the current state of the patient and encounter, and the implementer has to figure out which fields changed since the last A08 to avoid clobbering downstream consumers. Some platforms (for example, Interbox by Health Samurai) ship with a TypeScript SDK with autocomplete for HL7v2 field indexing, which makes the per-field diff tractable; on platforms without that, the diff logic is hand-rolled and brittle.
A40 (patient merge) is the genuinely hard case. A merge says two patients that used to be separate are now the same person. Resolving that against an existing FHIR Patient pool, updating all the encounters and observations that referenced the deprecated MRN, and keeping referential integrity for downstream consumers is a non-trivial pipeline of its own.
Where ORM Is Harder
ORM is harder than ADT in a different direction: the order control codes (ORC-1) and the order-status semantics. NW (new order), CA (cancel), DC (discontinue), RP (replace), and the long tail of status codes each have specific FHIR semantics. NW maps to a new ServiceRequest with status=active. CA maps to a status change to revoked. RP is the tricky one, because it carries a reference to the order being replaced, and the FHIR side has to resolve that reference and update the previous ServiceRequest's status correctly.
Order-detail segments are the other source of ORM pain. RXE for pharmacy, OBR for lab and imaging, each with their own field structure. A converter that handles ADT well can still get ORM wrong because the order-segment coverage is shallower.
The Honest Answer on Which Is Harder
For a greenfield US integration project, ORM is harder. Order control codes, order-detail segments, and the breadth of order types (pharmacy, lab, imaging, referral) mean more code paths to implement and more edge cases to test. Most teams underestimate ORM and finish later than they planned.
For a mature deployment, ADT is harder. A08 diff logic and A40 merge handling produce production incidents long after the initial conversion is shipped. The ORM code, once it works for the common order types, tends to stay working.
How to Plan the Build
Allocate roughly 60 percent of the conversion budget to ORM if the deployment is greenfield, 40 percent to ADT. For an integration that has been live for a year and is now expanding, flip the ratio. Either way, test against real production messages from the sending EHR, not against the spec examples. The deeper library question for the identity side of ADT conversion lives in top 7 probabilistic patient-matching libraries for FHIR stacks.
Sources
- HL7 Confluence (Orders & Observations WG) - V2-FHIR Mapping for ADT^A01 message