HL7v2 to FHIR - references and deduplication

Deliver each HL7v2 message as one consistent resource graph - fullUrl and urn:uuid references, deduplication and bundle_type effects.

A single HL7v2 message usually describes several connected entities - a patient, their visit, the attending doctor, lab results. The conversion turns each of them into a separate resource and wires the connections between them, so the bundle arrives at the FHIR server as one consistent graph.

Every entry has a fullUrl

Each bundle entry includes a fullUrl in the urn:uuid: form and other entries reference it through that URL:

{
  "fullUrl": "urn:uuid:237f706c-3f37-5ee3-98bf-fe8c006c2aa5",
  "resource": {
    "resourceType": "Encounter",
    "subject": {
      "reference": "urn:uuid:98e4f8aa-a5ad-5791-add1-66fd3afb4f83"
    }
  }
}

Here the Encounter's subject points at the Patient entry from the same bundle. When a FHIR server processes the transaction, it assigns real IDs to the created resources and rewrites all the urn:uuid: references to point at them - the graph stays intact on the server side.

The UUIDs are deterministic - they derive from the resource's content, so converting the same message twice yields the same URLs, which makes bundles reproducible and easy to compare in tests.

The wired-up references include:

  • Encounter.subject, Observation.subject, Condition.subject and every other clinical resource pointing at the Patient
  • MessageHeader.focus pointing at the Patient, with sender and the destination's receiver pointing at the facility Organizations from MSH-4 and MSH-6
  • Encounter.participant and Encounter.location pointing at Practitioners and Locations
  • DiagnosticReport.basedOn pointing at the ServiceRequest, DiagnosticReport.result at Observations, DiagnosticReport.specimen at Specimens
  • Coverage.payor pointing at the insurer Organization

Deduplication

The same entity often appears multiple times in one message - the same doctor in PV1-7 and ORC-12, the same organization in several IN1 segments. Resources with identical content are created once, and every later occurrence becomes a reference to the first one:

from zato.hl7v2 import parse_hl7

raw = (
    'MSH|^~\\&|SENDER|FACILITY|RECEIVER|FAC|20260315101112||ADT^A01^ADT_A01|CTL001|P|2.9\r'
    'PID|||12345^^^HOSP^MR||SMITH^JOHN^A||19800115|M\r'

    # The same doctor is both the attending and the referring physician ..
    'PV1|1|I|WARD^101^BED1||||1234^JONES^MARIA|1234^JONES^MARIA\r'
)

msg = parse_hl7(raw, validate=False)
bundle = msg.to_fhir()

# .. yet the bundle contains a single Practitioner.
for entry in bundle.entry:
    print(entry.resource.resource_type)
Organization
Organization
MessageHeader
Patient
Location
Practitioner
Encounter

Both Encounter.participant entries point at the one Practitioner. Deduplication is content-based, so it applies to any resource type, most often to Practitioners, Locations and Organizations.

What bundle_type changes

By default the bundle is a transaction - the server applies all entries atomically and each entry has a request with POST and the resource type as the URL. The configuration file can change this:

[bundle]
type=batch
  • transaction - all or nothing, the server rolls everything back if any entry fails
  • batch - the same entries, but each is processed independently and failures do not affect the other entries
  • collection - no request elements at all, the bundle is a plain container of resources, useful for storing or forwarding the conversion result without a FHIR server interaction

In all three cases the fullUrl values and the urn:uuid: references stay the same.

See also

PageWhat it covers
What you get per messageThe resources the references connect, per message family
Sending bundles to FHIR serversHow servers rewrite the urn:uuid references into real IDs
ConfigurationThe bundle type setting and everything else the .ini file holds

Learn more


Schedule a meaningful demo

Book a demo with an expert who will help you build meaningful systems that match your ambitions

"We evaluated 12 integration platforms and Zato was the only one to score 100%."

Philip Zuñiga, Assistant Professor, University of the Philippines