Healthcare Integration-12 min read

HL7 ADT to FHIR: mapping Patient and Encounter from A01, A04, A08 and A03

A playbook for projecting HL7 v2 ADT A01, A04, A08 and A03 onto FHIR Patient and Encounter — PID-3 versus identifier.system, PV1-19 visit numbers, and de-identified test fixtures.

Ala Ben Aicha

HL7 ADT to FHIR: mapping Patient and Encounter from A01, A04, A08 and A03

Direct answer

ADT A01, A04 and A08 project PID to Patient and PV1 to Encounter. A03 ends the visit. PID-3 is Patient.identifier; PV1-19 is the visit number. Pin assigning authorities before you upsert.

Message and resource mapping

Pin the published HL7 Version 2 to FHIR IG 1.0.0 (STU 1) (generated 7 October 2025, package hl7.fhir.uv.v2mappings#1.0.0 on FHIR R4). The STU 1 message maps include ADT_A01 → Bundle. A04, A08 and A03 are still Chapter 3 Patient Administration trigger events; they reuse the same PID → Patient and PV1 → Encounter segment maps even when a dedicated message ConceptMap is not in that STU.

Trigger (MSH-9) v2 event FHIR effect Status / class notes
ADT^A01 Admit / visit notification Upsert Patient from PID; upsert Encounter from PV1; Encounter.subject → that Patient Encounter.class from PV1-2 (table 0004 → ActCode: I→IMP, O→AMB, E→EMER). Status in-progress when PV1-45 is empty
ADT^A04 Register a patient Same Patient + Encounter pair Typically outpatient (PV1-2 = O → AMB). Not a bed assignment
ADT^A08 Update patient information Patch Patient; update Encounter only when PV1 is present and the visit is already known Not a new visit. Do not mint a second Encounter.identifier
ADT^A03 Discharge / end visit Encounter.status → finished; Encounter.period.end from PV1-45 Do not delete Patient. Do not reuse the visit number on the next A01

Segment-level pins from the IG:

v2 field FHIR path Type map
PID-3 Patient Identifier List Patient.identifier CX → Identifier
PID-5 Patient Name Patient.name XPN → HumanName
PID-7 Date/Time of Birth Patient.birthDate TS → date
PV1-2 Patient Class Encounter.class CWE → Coding (ActCode)
PV1-19 Visit Number Encounter.identifier CX → Identifier, type VN (http://terminology.hl7.org/CodeSystem/v2-0203)
PV1-44 Admit Date/Time Encounter.period.start
PV1-45 Discharge Date/Time Encounter.period.end

MSH still becomes MessageHeader / Provenance. EVN-2 is event time, not a second birth date. NK1 is RelatedPerson or Patient.contact, not another Patient. This page does not map A40 merges — that is an MPI problem, covered in the master patient index article.

The hybrid engine pattern (keep v2 as the hospital nervous system, project FHIR for new consumers) is the v2-to-FHIR migration playbook. This page is the ADT mapping contract inside that engine.

Identifier traps

PID-3 is a repeating CX. Each repeat is ID^^^AssigningAuthority^IdentifierType. FHIR needs identifier.system (the assigning authority as a URI you actually own) and identifier.value. A bare MRN string with no system will collide the first time two hospitals share a FHIR server.

Do not put PV1-19 on Patient.identifier. The IG types the visit number as VN. PID-18 (Patient Account Number) is not the visit number; the PID map even warns that some senders stuff a visit id into PID-18 — if yours does, treat it as a documented exception, not as the default.

National identifiers (AHV, NHS number, KVNR, IHI) belong in PID-3 with their published system URIs. Local MRNs stay local. The MPI article is where matching rules live; the ADT mapper's job is to preserve the CX, not to invent a golden record.

Trap Symptom Fix
PID-3 without assigning authority Duplicate Patient resources on the first A08 Require CX.4 (or CX.4.2 namespace ID) before upsert; reject or quarantine
PV1-19 copied onto Patient Two patients share a visit number after transfer Visit → Encounter.identifier only
A08 creating Encounter Census doubles on demographic fixes Match Encounter by PV1-19 + Patient; insert only on A01/A04
A03 deleting Patient Downstream Observation orphans Patient stays; Encounter.status = finished
MSH-3 / MSH-4 as identifier.system Systems collide when a vendor reuses a facility name Pin a URI per sending application × assigning authority

Test fixtures

De-identified examples only. These values are specification fixtures, not a person.

MSH|^~\&|HIS|HOSP-A|FHIR-BRIDGE|HOSP-A|20260917103000||ADT^A01^ADT_A01|MSG0001|P|2.5
EVN|A01|20260917103000
PID|1||HOSP-MRN-0001^^^HOSP-A^MR||EXAMPLE^JANE^Q||19770412|F|||1 TEST STREET^^TESTVILLE^TN^10000
PV1|1|I|WARD-A^101^A||||ATTEND^SMITH^A|||SUR||||A0|||||VN-2026-00042^^^HOSP-A^VN|||||||||||||||||||||||||20260917103000

Projected Patient (truncated):

{
  "resourceType": "Patient",
  "identifier": [
    {
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "MR"
          }
        ]
      },
      "system": "https://hosp-a.example.org/mrn",
      "value": "HOSP-MRN-0001"
    }
  ],
  "name": [{ "family": "EXAMPLE", "given": ["JANE", "Q"] }],
  "birthDate": "1977-04-12",
  "gender": "female"
}

Projected Encounter (truncated):

{
  "resourceType": "Encounter",
  "status": "in-progress",
  "class": {
    "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
    "code": "IMP"
  },
  "identifier": [
    {
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "VN"
          }
        ]
      },
      "system": "https://hosp-a.example.org/visit",
      "value": "VN-2026-00042"
    }
  ],
  "subject": { "reference": "Patient?identifier=https://hosp-a.example.org/mrn|HOSP-MRN-0001" },
  "period": { "start": "2026-09-17T10:30:00+01:00" }
}

Minimum fixture set before cutover:

  1. A01 then A08 (name correction) — one Patient, one Encounter, name updated.
  2. A01 then A03 — Encounter.period.end set, status finished, Patient still searchable.
  3. A04 outpatient register — class AMB, no bed in Encounter.location unless PV1-3 is valued.
  4. Two A01 with the same PID-3 and different PV1-19 — two Encounters, one Patient.
  5. A08 with missing PV1-19 — Patient updates; no new Encounter.

Never copy a live PID into a ticket, a git repo, or this site.

Failure modes and rollback

Failure Detection Rollback
Duplicate Patient Two resources share PID-3 value with different systems, or the same system after a mapper bug Stop the writer; merge only with an agreed MPI rule; replay A08 from the v2 store
Duplicate Encounter Two in-progress Encounters for one PV1-19 Treat PV1-19 + assigning authority as the natural key; close the extra as entered-in-error
Late A03 Census still shows in-progress after discharge Idempotent A03: set status and period.end; do not require the original A01 in the same process
A08 applied as A01 Extra visits on demographic noise Filter MSH-9.2 before insert; A08 is PATCH
Loop with a FHIR subscription that re-emits ADT Message volume cliff One authoritative write path; provenance on the projected resources; suppress echo by MSH-3

Keep v2 as the source of truth until the FHIR Patient/Encounter pair has a named owner, an ACK policy, and a replay from the engine's message store. The migration playbook covers shadow, dual-write and cutover as architecture. This mapper must still be able to disable the FHIR writer without touching the HIS ADT feed.

Related service

If you need the mapping implemented on an engine (NextGen Connect / Mirth, or a FHIR facade in front of a v2 feed), that is HL7 FHIR integration. For a scoped ADT→Patient/Encounter spike, use contact with project intent.

This page is not a conformance certificate against the v2-to-FHIR IG, not an MPI product, and not clinical advice about admission or discharge.

HL7 v2ADTFHIRPatientEncounterPID-3PV1-19Mirth ConnectInteroperability

Related reading and services

Let's Continue the Conversation

Have questions about this topic? I'd love to hear from you.

Get in Touch

🍪 Do you like cookies?

Allow analytics cookies to help understand site visits and enquiries? Optional analytics stays off until you accept.

Learn More