In this article
- What HL7 FHIR integration is
- What HL7 is
- HL7 message structure
- What FHIR is
- HL7 vs FHIR
- How HL7 and FHIR work together
- HL7 to FHIR mapping
- FHIR resources explained
- Reference architecture
- EHR integration workflow
- The integration engine
- Security and SMART on FHIR
- 13 common challenges
- 14 best practices
- Interoperability and AI
- HL7, FHIR, or both?
- How Bonami helps
- FAQ
Key takeaways
- HL7 v2 and FHIR are two generations of standards from the same organization, HL7 International. They are not rivals: v2 runs the event traffic inside the hospital, and FHIR is the API the outside world uses.
- Almost every real HL7 FHIR integration follows one pattern: an integration engine receives HL7 v2 messages, translates them into FHIR resources, validates them, and serves them through a FHIR API.
- Mapping is where most effort and most defects live. Start from HL7’s V2-to-FHIR implementation guide, keep concept maps for codes, and treat mapping as versioned code with tests.
- Neither standard is a security standard. Authorization (SMART on FHIR), encryption, audit and identity resolution are design work you own.
- The integration layer is the foundation for analytics and AI. Clean, coded, longitudinal FHIR data is what models are built on.
What is HL7 FHIR integration?
HL7 FHIR integration connects healthcare systems so that data sent as HL7 v2 messages and data served as FHIR resources can be exchanged and used reliably. In practice an integration engine receives HL7 v2 events from the EHR, lab and pharmacy systems, translates them into FHIR resources, and exposes them through a secure FHIR API that modern apps call.
A patient’s story is never held in one system. Registration happens in the hospital EHR, a blood test is resulted in the laboratory system, the prescription is filled in a pharmacy system, the claim is adjudicated by a payer, and the follow-up reminder comes from a patient app. Each was built by a different vendor, at a different time, with its own idea of what a patient, a visit or a result looks like. HL7 and FHIR integration is the discipline of making them agree, reliably, at volume, and without anyone re-keying data.
Health Level Seven International has defined how healthcare systems exchange information since 1987. Its version 2 messaging standard is the most widely deployed interface format in hospitals. Its newest standard, FHIR, does the same job with the architecture of the modern web: resources instead of messages, REST instead of point-to-point sockets, JSON instead of pipe-delimited text. A working healthcare organization in 2026 almost always runs both, so the practical skill is not choosing between HL7 and FHIR but making them work together.
HL7 International founded. The “7” is the seventh, application, layer of the OSI model
HL7 Internationalresource types defined in FHIR R4. A typical integration uses about a dozen of them
HL7 FHIR R4 specificationdeclare the whole HL7 v2 syntax: | ^ ~ \ &
Exchanging data versus using it
Interoperability is the ability of two systems to exchange information and to use what was exchanged. Moving a file from a lab to a hospital is easy. Making sure the hospital’s software knows that the third value is a serum glucose in mg/dL, belongs to this patient and not her mother, and replaces yesterday’s preliminary result is the hard part.
Technical
Systems can connect and move bytes: a network path, a transport protocol, an agreed encoding. Necessary, and nearly useless on its own.
Syntactic
The receiver can parse what arrives: where each field starts and ends and what type it holds. A message or resource format provides this.
Semantic
The receiver understands the meaning: LOINC 2345-7 is a glucose test, and “F” in one field is a sex and in another a final result.
Healthcare exchange is harder than most enterprise integration for three reasons. Identity is uncertain, because there is no universal patient identifier. Meaning is coded in different vocabularies on each side. And the consequences are clinical: a mis-mapped unit is a patient-safety event, not a reporting error. For the policy side of the topic (HIE, TEFCA, USCDI and the Cures Act) see our healthcare interoperability guide.
What is HL7? The organization, HL7 v2 and its relatives
“HL7” means three different things, and integration conversations go wrong when they get mixed up. It is an organization, Health Level Seven International. It is a family of standards that organization publishes. And in everyday hospital use it is shorthand for one of them: HL7 version 2, the event-driven messaging standard that connects most clinical systems in the world. HL7 is not a programming language. It is a set of data formats and rules that software written in any language can read and write.
HL7 v2.x
The messaging standard, first published in the late 1980s and revised through v2.9. Pipe-delimited text messages triggered by events: a patient is admitted, an order is placed, a result is ready. Backward compatible by design, so a hospital may run v2.3, v2.5.1 and v2.8 interfaces side by side.
Ubiquitous in hospitalsHL7 v3
A ground-up redesign from the 2000s, built on a formal Reference Information Model and expressed in XML. Rigorous but complex; used in some national programs and otherwise rarely for messaging. Its lasting legacy is CDA.
Rarely used for messagingCDA and C-CDA
The Clinical Document Architecture: XML documents such as discharge summaries and referrals that are human-readable and machine-parseable at once. Consolidated CDA is the profile exchanged between certified US EHRs. See CDA integration.
Document exchangeFHIR
The newest standard: web resources exchanged over REST APIs in JSON or XML. Designed to be implemented quickly and to coexist with everything above rather than replace it overnight.
APIs, apps, payersEvent-driven messaging, in plain termsInstead of being asked for data, the source system announces changes as they happen, like a notification rather than a lookup. When a patient is admitted, the EHR sends an ADT^A01 message, and the lab, radiology, pharmacy and bed-management systems all receive it within seconds. Each one knows the patient exists, and which bed she is in, before anyone orders anything.
HL7 message structure: an ADT^A01 example, segment by segment
An HL7 v2 message is plain text. It is made of segments, one per line, each starting with a three-character ID. Segments hold fields separated by |, and fields can be split into components (^), repetitions (~) and sub-components (&), with \ as the escape character. The delimiters are declared in the first segment, so a parser never has to guess. Fields are identified by position: PID-5 is the fifth field of the PID segment, and the standard defines what each position means.
Here is a complete admit message for a fictitious patient. Pick a segment to see what it carries, or hover any value to see its field number.
MSH|^~\&|HIS|CITYHOSP|LIS|CITYLAB|20260916083000||ADT^A01^ADT_A01|MSG00001|P|2.5.1EVN|A01|20260916082500PID|1||MRN-0045821^^^CITYHOSP^MR||ROY^AMARA^K||19840312|F|||14 HARBOUR ST^^SEATTLE^WA^98101||^PRN^PH^^^206^5550142PV1|1|I|4W^412^A^CITYHOSP||||1122^PATEL^NEERAJ^^^DR|||MED|||||||||V2026-77812|||||||||||||||||||||||||20260916082500MSH Message header
Declares the delimiters, who sent the message and who should receive it, when it was created, what kind of message it is, a control ID the receiver echoes in its acknowledgement, and the v2 version it conforms to.
MSH-1|the field separator itselfMSH-2^~\&component, repetition, escape, sub-componentMSH-3/4Sending application and facility: HIS at CITYHOSPMSH-5/6Receiving application and facility: LIS at CITYLABMSH-9Message type ADT, trigger event A01, structure ADT_A01MSH-10Control ID MSG00001, echoed back in the ACKMSH-11Processing ID P, productionMSH-12Version 2.5.1
EVN Event type
Says which trigger fired and when it was recorded. The moment the event actually happened (EVN-6) can differ from when the message was sent, which matters when messages arrive late or out of order.
EVN-1Event type code A01, kept for backward compatibilityEVN-2Recorded date/time of the eventEVN-6Event occurred, when populatedMSH-9.2The authoritative trigger event in v2.5+
PID Patient identification
Who the patient is: identifiers with their assigning authority and type, the name as family^given, date of birth, administrative sex, address and phone. This is the segment a FHIR Patient resource is built from.
PID-3MRN-0045821, assigned by CITYHOSP, type MRPID-5ROY^AMARA^K: family^given^middlePID-719840312, date of birth as YYYYMMDDPID-8F, from HL7 table 0001PID-11Street^other^city^state^postal codePID-13Home phone: use PRN, equipment PH, 206 555 0142
PV1 Patient visit
The visit: patient class, assigned location as ward^room^bed, attending physician, hospital service, visit number and admission time. Long runs of empty fields are normal in v2, because meaning is positional. This is the segment a FHIR Encounter is built from.
PV1-2I, inpatientPV1-34W^412^A^CITYHOSP: unit, room, bed, facilityPV1-7Attending doctor 1122, Dr Neeraj PatelPV1-10Hospital service MEDPV1-19Visit number V2026-77812PV1-44Admit date/time
HL7 message types you will meet on day one
| Message type | Common trigger events | What it carries |
|---|---|---|
| ADTAdmit, discharge, transfer | A01 admit · A02 transfer · A03 discharge · A04 register outpatient · A08 update patient · A40 merge patient | The backbone of patient identity and encounter flow. PID and PV1 do most of the work. |
| ORM · OMGOrders | O01 · O19 | A request for a lab panel, imaging study or medication. ORC carries order control (new, cancel, hold); OBR carries what was ordered and by whom. |
| ORUObservation result | R01 unsolicited result | OBR identifies the order and report; one OBX per value with analyte, value, units, reference range, abnormal flag and status. |
| SIUScheduling | S12 new · S13 rescheduled · S15 cancelled | The appointment slot, the resources booked and the patient. |
| MDM · DFTDocuments, charges | T02 · P03 | MDM moves clinical documents and their status; DFT posts charges to billing. |
| ACKAcknowledgement | AA accept · AE error · AR reject | The reply every receiver returns, which is how a sender knows a message arrived. |
MLLP, acknowledgements and Z-segments
Two facts about v2 rarely appear in an introduction and always appear in a project. First, the standard says little about transport. In practice messages travel over MLLP, the Minimal Lower Layer Protocol: each message is wrapped in a start byte (0x0B) and end bytes (0x1C 0x0D) on a TCP socket, and every message expects an ACK back. An interface is a persistent connection with a heartbeat, not a stateless call.
MSH|^~\&|LIS|CITYLAB|HIS|CITYHOSP|20260916083001||ACK^A01^ACK|ACK00001|P|2.5.1
MSA|AA|MSG00001Second, the standard allows locally defined Z-segments for data it does not cover. Nearly every hospital has them, no two hospitals’ match, and they are the biggest single reason that “standard HL7” interfaces still need to be specified system by system. Our HL7 integration team starts every project with a Z-segment inventory for exactly this reason.
What is FHIR? Resources, the FHIR API and FHIR R4
FHIR, Fast Healthcare Interoperability Resources (pronounced “fire”), is HL7’s standard for exchanging healthcare data using the architecture of the web. The first draft appeared in 2014. Release 4 (R4), published in December 2018, became the version most regulations and platforms build on; R4B followed in 2022 and R5 in March 2023, and R6 is in development as the first release intended to be largely normative. FHIR was designed by people who had implemented v2 and v3 for years and wanted something a web developer could pick up in an afternoon, without losing clinical depth.
The unit of FHIR is the resource: a small, well-defined object for one concept, such as a Patient, Encounter, Observation or MedicationRequest. A resource has typed elements with defined cardinality, a human-readable narrative, and an identity: a URL where it can be read, updated or deleted. Resources point to each other by reference, so an Observation names the Patient it was measured on, just as a web page links to another. Here is the same fictitious patient from the ADT message, as a FHIR R4 Patient resource:
{
"resourceType": "Patient",
"id": "pat-0045821",
"identifier": [{
"type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "MR" }] },
"system": "https://cityhospital.example.org/identifiers/mrn",
"value": "MRN-0045821"
}],
"name": [{ "use": "official", "family": "Roy", "given": ["Amara", "K"] }],
"gender": "female",
"birthDate": "1984-03-12",
"address": [{ "line": ["14 Harbour St"], "city": "Seattle", "state": "WA", "postalCode": "98101" }],
"telecom": [{ "system": "phone", "value": "206-555-0142", "use": "home" }]
}Type and address
Every resource names its type and carries a logical id. With the server’s base URL it forms an address: [base]/Patient/pat-0045821.
Business identifiers
Each with a system (who assigned it) and a value. The type code MR comes from an HL7 v2 table, which is how FHIR reuses the vocabularies it grew up with.
Typed and constrained
Gender comes from a fixed value set (male, female, other, unknown); birthDate is an ISO date. In v2 the same facts were positional: F and 19840312.
Lists, not separators
A patient can have several identifiers, names and addresses. FHIR models each as a list of typed objects rather than a repetition separator, so any JSON parser handles it.
The FHIR API: four operations do most of the work
FHIR resources are exchanged through a RESTful FHIR API over HTTPS: GET to read or search, POST to create, PUT to update, DELETE to remove, with standard status codes and JSON or XML bodies. This is the change that matters most for a development team: an integration becomes an API client, testable with the same tools as any other web service.
// read one resource by its id
GET [base]/Patient/pat-0045821
// search: find the patient by MRN, then her glucose results, newest first
GET [base]/Patient?identifier=https://cityhospital.example.org/identifiers/mrn|MRN-0045821
GET [base]/Observation?patient=pat-0045821&code=http://loinc.org|2345-7&_sort=-date&_count=20
// create and update: the body is the resource; the response carries id and version
POST [base]/Observation Content-Type: application/fhir+json
PUT [base]/Patient/pat-0045821 If-Match: W/"3"A search returns a Bundle, a resource that contains other resources, with paging links. Bundles also come as transaction (all or nothing), batch, document and message. The If-Match header carries the resource version, so two systems cannot silently overwrite each other.
Profiles, extensions and implementation guides
Profile
A constraint on a base resource: which elements are required, which value sets apply, what cardinality. Base Patient permits almost anything; US Core Patient makes name, gender and an identifier mandatory. A server lists its profiles in its
CapabilityStatement.Extension
A defined way to carry data the base resource has no element for. It is the FHIR answer to the Z-segment, but with a published definition at a URL, a data type and a place in the model.
Implementation guide
A package of profiles, extensions, value sets and search rules for a use case: US Core for certified EHR APIs, the International Patient Summary, Da Vinci for payers, SMART App Launch, Bulk Data. Conformance is stated against an IG, not against “FHIR”.
Terminology resources
CodeSystem,ValueSetandConceptMapare resources too, so vocabularies and the maps between them can be fetched and validated over the same API. That is what makes semantic interoperability machine-checkable.
HL7 vs FHIR: the key differences
Every architecture review eventually draws this table. It is worth drawing carefully, because the right conclusion is not “replace v2 with FHIR”. The two standards solve the same problem with the tools of their eras, and the differences that matter are about who consumes the data and how.
| Dimension | HL7 v2 | FHIR |
|---|---|---|
| Paradigm | Messages. One message describes an event and carries everything about it. | Resources. Discrete objects with identity, linked by reference, read and written individually. |
| Interaction | Event-driven push. The source announces changes; consumers listen on a persistent connection. | REST request/response. Consumers query when they need to; events via Subscriptions and messaging. |
| Structure | Positional fields. PID-5 is the name because the standard says so. | Named, typed elements. Patient.name.family describes itself. |
| Encoding | Delimited text. Compact and fast, but needs a custom parser. | JSON or XML. Parsed by any standard library, validated against profiles. |
| Transport | MLLP over TCP with application-level ACKs; long-lived sockets. | HTTPS. Status codes, caching, load balancing and gateways apply unchanged. |
| Conformance | Local agreement. Optionality and Z-segments mean each interface is specified individually. | Profiles and IGs. Published, machine-readable, validatable constraints. |
| Skills | Interface analysts who know the hospital’s conventions. | Any developer who can call a REST API; clinical modeling is the learning curve. |
| Where found | Ubiquitous inside hospitals, decades of installed interfaces. | Growing at the edges: patient apps, payers, analytics, regulated APIs, new platforms. |
The conclusion the comparison should lead toFHIR does not replace HL7 v2 in systems that already speak it, and few hospitals plan to re-interface a lab analyzer that works. What FHIR replaces is the lack of a good answer for everything outside those walls: the patient’s phone, the payer’s portal, the analytics platform, the AI service. So a modern environment runs both, and the engineering problem is the translation between them. For a deeper side-by-side, read HL7 vs FHIR explained.
How HL7 and FHIR integration works in practice
This is how most real HL7 and FHIR integration is done today. The EHR and departmental systems keep emitting the v2 messages they always have. An integration layer receives them, translates each into FHIR resources, and exposes those through a FHIR API. Modern apps never see a pipe-delimited message, and legacy systems never see JSON. Each side keeps its own language, and translation happens once, in one place, under control.
-
SystemHospital EHR
Registers the patient and emits events as they happen.
-
ProcessIntegration engine: receive, acknowledge, parse
The listener persists the message, returns an ACK and splits it into segments and fields.
-
ProcessTransformation and mapping
PID → Patient, PV1 → Encounter; codes translated; identifiers resolved against the master patient index.
-
ProcessValidation
Resources checked against the target profile. Failures go to an error queue, never dropped.
-
DataFHIR resources
Patient and Encounter created or updated on the FHIR server, versioned.
-
APIFHIR API
GET, POST, search and Subscriptions, authorized with OAuth 2.0 and SMART on FHIR.
-
SystemModern healthcare application
Patient app, care-coordination tool, analytics or AI service.
- System
- HL7 message
- Process
- Data · resource
- FHIR API
Seven responsibilities of the translation layer
Each one is a place an integration can fail, and each has a standard remedy.
Parsing
Split the message on the delimiters declared in MSH-1 and MSH-2 into segments, fields, repetitions and components; decode escapes. A robust parser tolerates missing trailing fields and unknown Z-segments.
Transformation
Flat and positional becomes nested and typed. One ADT yields a Patient and an Encounter; one ORU yields a DiagnosticReport and several Observations, each referencing the Patient.
Mapping
Field to element (PID-7 to birthDate) and vocabulary translation (table 0001 sex codes to AdministrativeGender, local lab codes to LOINC).
Identity resolution
The MRN must resolve to the right Patient. Across facilities a master patient index matches on identifiers and demographics, and ADT^A40 merges must be honored.
Validation
Check the produced resource against the profile with $validate. A failure goes to a reviewable queue with the original message, never written half-formed.
Routing
Content-based decisions by facility, message type or patient class, including fan-out: write to the FHIR server and still forward the v2 message to a system that needs it.
API exposure and error handling
Serve resources through REST with authorization, search and paging. Log every stage with the message control ID (MSH-10) so a result can be traced from analyzer to app, and retry with back-off, because in an event-driven system there is no second chance to ask for the event.
The direction runs both ways. An app that creates a FHIR ServiceRequest, such as a booking or a referral, often has to reach a lab or scheduling system that only accepts a v2 ORM or SIU message. The same layer composes that message and waits for the ACK. A well-designed platform treats v2 and FHIR as two interfaces onto one canonical model, so adding a third format later is another adapter, not another architecture.
HL7 to FHIR mapping: PID to Patient, field by field
Mapping is where integration projects spend most of their effort and where most defects start. Below is the core of the most common map, the PID segment to the FHIR Patient resource, following HL7’s published V2-to-FHIR implementation guide. Hover or tap a row and the matching value lights up in both the HL7 message and the FHIR JSON.
PID|1||MRN-0045821^^^CITYHOSP^MR||ROY^AMARA^K||19840312|F|||14 HARBOUR ST^^SEATTLE^WA^98101||^PRN^PH^^^206^5550142repeat to array
split
reformat
concept map
split
default
{
"resourceType": "Patient",
"id": "pat-0045821",
"identifier": [{
"type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "MR" }] },
"system": "https://cityhospital.example.org/identifiers/mrn",
"value": "MRN-0045821"
}],
"name": [{ "use": "official", "family": "Roy", "given": ["Amara", "K"] }],
"gender": "female",
"birthDate": "1984-03-12",
"address": [{ "line": ["14 Harbour St"], "city": "Seattle", "state": "WA", "postalCode": "98101" }],
"telecom": [{ "system": "phone", "value": "206-555-0142", "use": "home" }]
}Tip: tap a highlighted value to pin it while you scroll.
The other core segment maps
The same discipline extends to every segment an integration touches. These are the starting points the V2-to-FHIR guide defines.
| HL7 v2 segment | FHIR resource | Key element maps |
|---|---|---|
| PV1 · PV2Patient visit | Encounter | patient class → class · location → location · attending → participant · visit number → identifier · admit time → period.start |
| ORC · OBROrder | ServiceRequest · DiagnosticReport | OBR is the request and the header of the report that points back to it |
| OBXObservation | Observation | OBX-3 → code · OBX-5 → value[x] typed by OBX-2 · OBX-6 → unit · OBX-7 → referenceRange · OBX-8 → interpretation · OBX-11 → status (F final, P preliminary, C corrected) |
| AL1 · IAMAllergy | AllergyIntolerance | substance → code · severity → criticality · reaction → reaction |
| DG1 · PRBDiagnosis, problem | Condition | diagnosis code → code (ICD-10 · SNOMED CT) · onset → onset[x] |
| IN1Insurance | Coverage | plan, payer organization, subscriber and member identifiers |
| NK1Next of kin | RelatedPerson | relationship, name, contact details |
| MRGMerge (A40) | Patient.link | the surviving and replaced identities, so duplicates do not accumulate |
Why mapping is harder than the diagram suggests
One becomes many
An ORU with twelve OBX segments becomes one DiagnosticReport, twelve Observations and the references between them, even when the message carries several OBR groups.
Different codes, same fact
The lab sends its local test code; the profile requires LOINC. Table 0001 has six sex values; FHIR gender has four. Every pair needs a maintained ConceptMap and a defined fallback.
Missing is not empty
A v2 field can be absent, empty, or the explicit null "", each meaning something different, while the profile may make the target mandatory. That is a business decision.
Real messages are messy
Dates arrive as 1984 or 198403, names in capitals with credentials appended, units spelled three ways. Normalize defensively and flag what could not be fixed.
Z-segments need homes
Data a hospital put in a Z-segment needs a FHIR extension with a published definition, a data type and agreement from every consumer.
References must resolve
A result for MRN-0045821 must find the existing Patient, not create a second one, and attach to the encounter registered by a different message an hour earlier.
FHIR resources explained: the dozen that carry most integration traffic
Of the roughly 145 resources in FHIR R4, about twelve carry the overwhelming majority of integration work. Each card names what the resource represents, the elements an integration touches most, and the HL7 v2 segment it is usually built from. Filter by where they sit in a clinical workflow.
Patient
IdentityDemographics and identifiers for a person receiving care. The hub almost every other clinical resource references; one person may have several Patient records across organizations, joined with link.
Encounter
ContextAn interaction between a patient and a provider: an admission, a clinic visit, an ED attendance. Anchors observations, procedures and diagnoses to a time and place.
Practitioner
WhoA person directly involved in care: physician, nurse, pharmacist. Roles, specialties and affiliations live in the companion PractitionerRole.
Organization
WhoA formally recognized group: hospital, department, laboratory, payer, practice. The responsible party for encounters, coverage and reports.
Observation
Clinical factOne measurement or assertion: a lab value, a vital sign, a social-history item. The workhorse of clinical data; a hospital produces millions a year.
DiagnosticReport
Clinical factThe findings of a diagnostic service, such as a lab panel, imaging study or pathology report, grouping its Observations and carrying the conclusion.
Condition
Clinical decisionA diagnosis, problem or health concern, with clinical status (active, resolved), verification status and onset. The problem list and encounter diagnoses.
AllergyIntolerance
Clinical decisionA risk of adverse reaction to a substance: the substance, reaction manifestations, criticality, and whether it is an allergy or an intolerance.
MedicationRequest
Clinical decisionAn order or prescription for a medication: what, for whom, how much, how often and by whom. Separate from the drug itself and from dispensing.
Medication
ReferenceThe drug product: code, form, ingredients and strength. Referenced by requests, dispenses and administrations rather than repeated in each.
ServiceRequest
What was askedA request for a diagnostic or therapeutic service: the lab order, the imaging order, the referral. The FHIR side of an ORM message, and the parent a DiagnosticReport points back to.
Procedure
What was doneAn action performed on or for a patient, whether surgical, diagnostic or therapeutic, with when, by whom, where and the outcome.
A useful rule for modeling debatesIf a fact has a value and a time, it is probably an Observation. If it is a judgment that persists, it is a Condition. If someone asked for something, it is a ServiceRequest; if they did it, a Procedure. Most arguments resolve on those four distinctions.
Also common: Coverage and Claim for payer exchange, Immunization for registries, DocumentReference to index C-CDA and PDF documents, Appointment, Schedule and Slot for booking, Location and Device. Infrastructure resources do the plumbing: Bundle wraps sets of resources, OperationOutcome carries errors, CapabilityStatement declares what a server supports, and AuditEvent and Provenance record who did what and where data came from. For profiling and Bulk Data in production, see FHIR R4 in practice.
A reference architecture for HL7 and FHIR integration
This is a conceptual reference architecture: how the parts of HL7 and FHIR integration are commonly arranged, not one vendor’s design. Real deployments merge, split or skip tiers depending on scale and what already exists. Data flows top to bottom, from a clinical system to an application. Select a tier to see what lives there.
- Transaction log · monitoring · audit across every tier
Source systems
The systems of record, each on its own release cycle and each with its own idea of a patient.
- What lives here
- EHR / EMR (ADT, orders, documents) · laboratory (results) · radiology RIS and PACS · pharmacy · practice management · devices and monitors
- Why it matters
- They will not change for you. Their interface capabilities are fixed at whatever v2 version and conventions they shipped with.
Interfaces
The formats and transports that cross into the integration layer.
- What lives here
- HL7 v2 over MLLP (ADT, ORM, ORU, SIU, MDM) · C-CDA documents · native FHIR REST on newer systems · files and proprietary APIs, wrapped by the engine
- Why it matters
- Inventory every interface, its version and its Z-segments before design. Surprises here become schedule slips later.
Integration engine
Tier 3 is the translation. Everything above it speaks its native format; everything below it speaks FHIR.
- What lives here
- Listeners and connectors (MLLP, HTTPS, SFTP, queues) · parsing · v2 → FHIR, FHIR → v2 and CDA → FHIR transformation · terminology mapping to LOINC, SNOMED CT and RxNorm · validation · routing and fan-out · queues, retry and error handling · transaction log
- Why it matters
- The transaction log is a data store in its own right: the record that lets a result be traced from analyzer to app.
Data platform
Tier 4 holds the truth. A FHIR server is a database with a standard API.
- What lives here
- FHIR server or clinical data repository (versioned resources) · master patient index · terminology service (CodeSystem, ValueSet, ConceptMap) · canonical resources
- Why it matters
- The MPI and terminology service beside the FHIR server are what keep identity and meaning consistent across every source.
Access layer
Tier 5 is where security lives: authorization, scopes and audit are enforced at the API, not inside each consumer.
- What lives here
- FHIR REST API (read, search, write) · SMART on FHIR authorization (OAuth 2.0, scopes, launch context) · Bulk Data export (NDJSON) · Subscriptions and events
- Why it matters
- Bulk export and Subscriptions serve the consumers a request/response API cannot: analytics and event-driven applications.
Consumers
Everyone downstream, each an ordinary web client.
- What lives here
- Clinical applications · patient apps and portals · analytics and population health · AI and decision support · payers, HIEs and registries
- Why it matters
- None of these has to parse a pipe. That is the point of the whole architecture.
Expect variations. A hospital whose EHR already exposes a certified FHIR API may need an engine only for departmental v2 traffic. A payer may have no v2 at all. A cloud data platform may swap the FHIR server for a lakehouse fed by Bulk Data. The tiers are responsibilities; which products fill them is a design choice, and “which vendor” is the wrong first question. When several EHRs must be reached through one API, the pattern is our universal EHR integration layer.
Who sends what: integration across the ecosystem
| System | Sends | Needs | Speaks today |
|---|---|---|---|
| EHR / EMR | ADT events, orders, documents | Results, dispensing, external documents | HL7 v2 to departments, C-CDA for documents, certified FHIR R4 API for apps. See Epic and Oracle Health integration |
| Laboratory (LIS) | ORU results, specimen status | ADT, ORM orders | HL7 v2 almost universally; LOINC is the mapping target. See lab integration |
| Radiology (RIS · PACS) | ORU reports, study references | ADT, imaging orders | HL7 v2 for orders and reports; DICOM for images, referenced from FHIR ImagingStudy. See PACS integration |
| Pharmacy | Dispense and administration events | Orders, allergies, weight, renal function | HL7 v2 RDE/RDS/RAS; FHIR MedicationRequest where modernized. See pharmacy integration |
| Devices · wearables | Vital signs, glucose readings | Patient association | Gateways emit HL7 v2 ORU or FHIR Observation. See device integration |
| Payers | Eligibility, prior authorization, remittance | Claims, clinical evidence | X12 EDI for claims; FHIR for patient access and payer-to-payer under the Da Vinci guides |
| Patient apps · portals | Appointments, questionnaires, consent | Records and results, on demand | FHIR with SMART on FHIR. The use case FHIR was built for and v2 has no answer to |
| Analytics · AI | Scores, alerts, insight | Clean, coded, longitudinal data | FHIR Bulk Data (NDJSON) in; results back as Observations, Flags or Tasks; CDS Hooks in workflow |
Read down the last column and the architecture explains itself. Inside the hospital, between long-running systems, HL7 v2 dominates and will for years. At every boundary where a person, a partner or a modern application needs the data, FHIR is the answer. The integration layer sits exactly on that boundary, which makes it the highest-leverage component an organization owns.
EHR integration workflow: one registration, end to end
The most common integration in any hospital is the flow of patient identity from the EHR to everything else. Following one registration from the front desk to a downstream app shows where each part of the architecture earns its place, and where each failure mode would first show up.
- 01 · EHRPatient registered
A clerk registers Amara Roy, or she pre-registers in a portal. The EHR assigns or finds her MRN and opens an encounter. Nothing has left the EHR yet, but every downstream system inherits the data quality captured here.
- 02 · ADTEHR raises an ADT event
Saving fires the trigger: A04 for an outpatient registration, A01 for an inpatient admission. MSH-10 gets a unique control ID; PID and PV1 are filled from the registration.
- 03 · MLLPHL7 v2 message sent
The message is framed in MLLP and written to the engine’s socket. If the socket is down, the EHR’s outbound queue holds it, and queue depth is the first metric an operations team watches.
- 04 · ACKEngine receives and acknowledges
The listener persists the raw message to its transaction log, then returns
AA. Persist, then acknowledge: an acknowledged message must never be lost. A malformed frame getsARorAEwith an error segment. - 05 · CheckMessage validation
Structural checks (segments, data types, version) and business checks (known facility, valid patient class, well-formed MRN). Failures go to a reviewable queue with the raw text, and do not block the messages behind them.
- 06 · MapTransformation and mapping
PID becomes a Patient, PV1 an Encounter. The MRN is looked up in the master patient index: an existing Patient is updated, a new one created, and a possible duplicate goes to a human data steward, not an automatic merge.
- 07 · FHIRFHIR resources created or updated
A conditional update on Patient by identifier, then a create or update on Encounter that references it, validated against the deployment’s profiles. The engine records the resource IDs against the control ID, closing the trace.
- 08 · APIThe FHIR API makes it available
GET [base]/Encounter?patient=…&status=in-progressnow works for any authorized client, and a Subscription can notify interested apps. A client sees only what its scopes and the patient’s consent allow. - 09 · AppsDownstream applications consume it
A care-coordination tool fetches the Encounter, the patient app shows the visit, the bed board updates, and the analytics pipeline picks it up on the next Bulk Data export. None of them parsed a pipe.
- 10 · CareClinical and business use
The ward knows the patient is coming, eligibility is checked against her coverage, and her first lab result will attach to this encounter automatically. Every step is logged, so “did the registration reach the lab, and when” is one query.
What “real time” should meanIn a well-run environment those ten stages finish in seconds, but speed is not the achievement. The achievement is that every stage is observable and recoverable. If the FHIR server is down at stage 7, the message waits and is retried; if mapping fails at stage 6, it is in the error queue with a reason. Interfaces that are fast but opaque are the ones that generate incident calls. For EHR-specific build work, see our EHR and EMR development services.
The HL7 interface engine: what it does, and why it is not just middleware
An integration engine, also called an HL7 interface engine, receives messages from source systems, transforms them and delivers them to destinations, with the queuing, error handling and logging that make the flow reliable. Hospitals commonly run Mirth Connect, Rhapsody, Cloverleaf or InterSystems HealthShare, and Epic sites use Epic Bridges. Cloud platforms offer managed building blocks too: Azure Health Data Services (a FHIR service with templates that convert HL7 v2), Google Cloud Healthcare API (HL7v2 and FHIR stores) and AWS HealthLake (a managed FHIR data store). The responsibilities are the same whichever product you pick.
The unit of work is the channel: one configured pathway from a source, through processing steps, to one or more destinations. Think of it as a single interface written down as configuration. An engine runs many at once.
source MLLP listener :6661 # persist, then ACK (AA)
parse ORU^R01, HL7 v2.5.1
transform OBR -> DiagnosticReport, each OBX -> Observation
map local test code -> LOINC, OBX-6 units -> UCUM
validate laboratory Observation profile # $validate
deliver POST transaction Bundle -> FHIR server
on failure retry with back-off, then error queue + alertDecoupling
Source and destination never connect directly. When the lab replaces its system, one channel changes and the twelve systems that consume lab results notice nothing.
Reliability
Messages are persisted on receipt and retried with exponential back-off. A destination outage becomes a growing queue and an alert, not lost clinical data.
Observability
Every message logged with its control ID, every transformation with its outcome, every delivery with its response. “Where is the result?” becomes a query, not an investigation.
Governed change
Mappings and routes live in versioned configuration with test harnesses. A change to the sex-code map is reviewed, tested against recorded messages and deployed, never edited in production.
Engine or FHIR server: which is the platform?They are complementary and often confused. The engine moves and translates; the FHIR server stores and serves. With only an engine you get fast interfaces and no queryable record; with only a FHIR server you get a clean API and no way to feed it from v2 systems. Most architectures need both, each with one job: the engine owns transport, transformation and delivery guarantees, and the FHIR server owns persistence, versioning, search and authorization.
Security, HIPAA and SMART on FHIR
Neither HL7 v2 nor FHIR is a security standard, and neither makes a system compliant on its own. HL7 v2 says almost nothing about security: an MLLP interface is a plaintext TCP socket unless it is wrapped in TLS or a VPN. FHIR defines how security applies to its API but relies on established web standards: TLS for transport, OAuth 2.0 and OpenID Connect through the SMART App Launch framework for authorization and identity, and AuditEvent and Provenance for accountability.
How SMART on FHIR authorizes an app to read a record
The app requests access
Either a standalone launch, or launched from inside the EHR with patient context already set.
Discovery
The app reads the server’s SMART configuration to find the authorization and token endpoints.
The user authorizes scopes
OAuth 2.0 authorization code flow: the user signs in and approves the requested scopes.
Access token issued
A short-lived bearer token carrying the granted scopes and patient context, plus a refresh token if offline access was granted.
FHIR API call with the token
The server enforces the scopes, the patient compartment and any consent rules on every request.
AuditEvent recorded
Who accessed what, when, from where and on whose behalf, kept for review.
Security controls, one by one
| Control | What it protects, and where it belongs |
|---|---|
| Transport encryptionTLS | Every FHIR call over HTTPS; every MLLP interface over TLS or confined to a private network. Certificates and cipher policy are operational disciplines, not one-time settings. |
| Authentication | Who is calling. OAuth 2.0 client credentials or SMART backend services (signed JWT) for systems; OpenID Connect through the organization’s identity provider for users. |
| Authorization and scopes | What the caller may do. SMART scopes name the resource type, the operations and whether access is for one patient, the user’s patients or the whole system. They are minimum necessary, expressed technically. |
| Record-level access control | Scopes say which type; the server must also enforce which records: patient compartment, care relationship, consent and break-the-glass. This is where most FHIR security review effort belongs. |
| Audit logging | Every access and change, attributable and reviewable. AuditEvent for the record, Provenance for lineage, and the engine’s transaction log for the v2 side. |
| Protection at rest | Encrypt the FHIR store, the engine’s queues and logs, and every backup. Message archives are often the least-protected copy of the most sensitive data. |
| De-identification | Analytics and AI pipelines rarely need identifiers. Filter Bulk exports and de-identify before the warehouse. See PHI de-identification. |
| Governance | Who approves a new interface, who owns each mapping, how data-sharing agreements are recorded and partner access is reviewed. This is what an auditor asks for. |
Is FHIR HIPAA compliant?No standard is compliant by itself. HIPAA’s Privacy and Security Rules govern protected health information, and a FHIR API can sit inside a compliant system or a non-compliant one. The difference is access control, encryption, audit, business associate agreements, risk analysis and staff process. HL7 and FHIR make good security practical by giving authorization and audit standard shapes; the organization stays responsible for achieving it. Our HIPAA risk assessment team reviews integration layers against those requirements.
13 common HL7 and FHIR integration challenges, and how to handle each
Every one of these shows up in most projects. Each is listed with why it happens, because the remedy follows from the cause.
Legacy systems that cannot change
Departmental systems are stable, certified for their purpose and expensive to replace. Their interface options are fixed at whatever v2 version and conventions they shipped with.
Do not ask them to change. Terminate their interfaces at the engine, translate there, and modernize behind the FHIR API. The legacy constraints become one channel’s configuration.
Inconsistent data formats
Each source encodes dates, names, identifiers and units its own way, even two interfaces from the same vendor at different sites.
Normalize at ingestion into one canonical model with per-source adapters. Test each against a corpus of real, de-identified messages and keep it as a regression suite.
Data mapping complexity
Flat segments become nested resources, one message becomes many resources, and the same fact is coded differently on each side.
Start from HL7’s V2-to-FHIR implementation guide. Document every mapping decision with its reason, and treat mappings as versioned code with review and tests.
Custom HL7 messages and Z-segments
v2 permits local segments, and hospitals have used them for decades. Two sites’ Z-segments never match.
Inventory every Z-segment and non-standard field before design. Map each to a FHIR extension with a published StructureDefinition, or decide explicitly that it is not needed.
Different FHIR versions
R4 is the regulatory baseline; some systems still expose STU3 or DSTU2; R5 exists and R6 is coming. Resources changed shape between versions.
Standardize internally on one version, R4 in most cases, and convert at the edge. Track each partner’s version from its CapabilityStatement and version your own API.
Terminology differences
The lab uses local test codes; the profile wants LOINC. Diagnoses arrive as ICD-10, problems as SNOMED CT, drugs as national codes.
Run a terminology service with maintained ConceptMaps. Send unmapped codes to a review queue with the original code kept in the resource, so nothing is lost.
Missing or incomplete data
Optional fields are optional, and a required element in the target profile may have no source at all.
Decide per element: derive, default with a data-absent-reason extension, reject, or relax the profile. Record the decision. Never invent a plausible value to pass validation.
Duplicate patient records
No universal patient identifier, registrations in many systems, names and dates that vary, and A40 merges that are missed or arrive out of order.
Use a master patient index with deterministic and probabilistic matching, honor merge events, and send ambiguous matches to a steward. Use Patient.link when identities are related but not merged.
API limitations
A partner’s FHIR server may support only some resources, search parameters or operations, with rate limits and page sizes on top.
Read the CapabilityStatement before designing against a server. Use Bulk Data for populations, Subscriptions for change notification, and cache where the source cannot keep up.
Authentication and security integration
Each partner has its own identity provider, token lifetimes and scope conventions; certificates expire; a v2 socket has no security at all.
Centralize authorization at the API gateway or FHIR server with SMART on FHIR, automate certificate rotation, wrap every MLLP interface in TLS or a private network, and audit every access.
Error handling
Messages fail through bad data, unavailable destinations or mapping gaps. Without a design for failure they are dropped silently or block the queue.
Every failure goes to a reviewable, replayable error queue with the raw message and reason. Separate transient errors (retry) from permanent ones (alert a person), and measure time to resolution.
Monitoring
An interface that ran for a year stops at 2 a.m. and nobody notices until the morning round. Interfaces fail quietly.
Instrument queue depth, latency, error rate and heartbeat per channel. Alert on missing expected traffic, not only on errors, and publish a status view clinical operations can read.
Scalability
A regional network produces millions of messages a day with sharp peaks, Bulk exports compete with live traffic, and one engine instance becomes the bottleneck.
Design for horizontal scale from the start: stateless processing, durable queues, partitioning by facility or message type, and separate read paths for analytics. Load-test with production-shaped traffic.
14 HL7 and FHIR integration best practices
These are practical rather than aspirational. Each is something a team can do on the next project, and each answers one or more of the failure modes above.
- Define the data requirements firstWhich resources, elements and codes, for which consumers, at what latency. “Get everything into FHIR” never finishes; a named use case does.
- Establish a canonical data modelTranslate every source into one internal model, in practice profiled FHIR resources. A new source then touches one adapter, not every pair.
- Map from the published guideStart from HL7’s V2-to-FHIR guide; where your data forces a different choice, record what and why.
- Validate at the boundaryStructural validation on receipt, profile validation before write. It turns “the data looks wrong” into fixable work items.
- Version the APIState the FHIR and profile versions consumers can rely on. Change additively, deprecate with notice, never break a consumer.
- Keep reviewable error queuesA failed message is a work item with an owner, a reason and a replay button, never just a log line.
- Log every transaction end to endControl ID in, resource IDs out, every hop timestamped. “Did the result reach the ward?” is one query.
- Use standard terminologiesLOINC, SNOMED CT, ICD-10, RxNorm and UCUM, with a terminology service and maintained maps from local codes.
- Secure the API, not each appEnforce SMART on FHIR, scopes and audit at the server or gateway, so every consumer inherits the same controls.
- Retry with back-off and idempotencyTransient failures should heal themselves. Conditional creates and updates stop a retried message creating a duplicate.
- Test with real message shapesA de-identified corpus of production messages, malformed ones included, is a project’s most valuable test asset.
- Monitor integration as a servicePer-channel volume, latency, error rate and heartbeat; alerts on silence; a status page operations can read.
- Plan identity from day oneDecide matching, merge propagation and who resolves ambiguity before the first message flows. Retrofitting an MPI is far harder.
- Document mappings as living artifactsA mapping spec that lives beside the code and is readable by a clinical informaticist lets the next team change it safely.
Planning an HL7 or FHIR integration?Bring the systems you have, the applications you want to connect and the rules you have to meet. Our FHIR integration team starts with the architecture, not a sales deck.
Why healthcare AI depends on HL7 and FHIR integration
Every useful clinical AI system, whether a deterioration score, a readmission model, an ambient documentation assistant or a population-health stratifier, sits downstream of the same thing: a reliable, coded, longitudinal, well-governed supply of clinical data. Interoperability is not next to the AI roadmap. It is the first item on it.
FHIR is a good substrate for machine learning because it does feature engineering that used to eat most of a data scientist’s time. An Observation has a LOINC code, a UCUM unit, a timestamp and a patient reference whichever lab produced it. Bulk Data export delivers a whole population in that shape as NDJSON, so a model built on it travels across sites in a way a model built on one hospital’s schema never did. At inference time, a model that reads live FHIR resources and writes back a risk score as an Observation, a suggested action as a Task or an alert as a Flag appears inside the clinician’s existing workflow, and CDS Hooks can call it when a chart opens or an order is signed. The AI does not need its own screen; it needs the interface.
Clinical decision support
Sepsis and deterioration scores, drug-interaction and dosing checks, guideline reminders, all consuming Observations, Conditions and MedicationRequests in workflow.
Risk and population health
Readmission, no-show and progression models trained on Bulk Data; cohorts stratified by coded conditions; care gaps found against guideline logic.
Automation and engagement
Documentation drafts from encounter data, prior-authorization evidence assembly, outreach triggered by results, each reading and writing FHIR instead of scraping screens.
Data quality and governance remain the constraintInteroperability makes data available; it does not make it right. A model trained on inconsistently mapped units, or on Conditions recorded for billing rather than clinical truth, learns those defects. Provenance, which is itself a FHIR resource, tells a data scientist which values to trust, and consent, de-identification and scopes decide which may be used at all. The organizations getting value from healthcare AI are the ones that treated their integration layer as the foundation, not plumbing to finish later. More on that in the healthcare AI infrastructure gap.
When to use HL7, FHIR, or both
The choice is rarely open. It is dictated by what already exists, who the consumer is, and what the rules in your market require. Answer two questions for a quick steer, then check the situations below.
Two questions
Who needs the data?
Think about the system or person on the receiving end of this interface.
Does the other system already speak HL7 v2, or offer no FHIR API?
Lab, radiology, pharmacy and bed-management systems usually do.
Where does the data come from?
New products can choose their interface; established hospitals usually cannot.
Use HL7 v2, through an engine
Keep v2 for high-volume, low-latency events between established clinical systems. Route it through an integration engine so you can add FHIR later without touching the source. Re-platforming a v2 interface that works is cost without benefit.
Use FHIR
Build FHIR-native: profiled R4 resources, SMART on FHIR authorization and a versioned API. Expect to meet HL7 v2 the moment you connect to a hospital, and plan an adapter or a partner who owns one, not a rewrite.
Use both, with one translation layer
This is where most hospitals and health systems sit. Keep v2 between clinical systems, add an integration engine and FHIR server, expose FHIR at the edge, and move consumers across one at a time. The boundary moves inward over time.
| Your situation | Recommended approach |
|---|---|
| Existing hospital | Keep v2 between clinical systems. Add an integration engine and a FHIR server, expose FHIR at the edge, and migrate consumers one at a time. Do not re-interface anything that works. |
| New digital health product | Build FHIR-native. Plan an HL7 v2 adapter, or a partner who owns one, for the first hospital you integrate with. Our healthcare software development team builds both sides. |
| Payer or administrator | FHIR for member-facing and partner exchange, driven by regulation and the Da Vinci guides; existing X12 EDI for claims. Identity resolution across sources is the foundational problem. |
| Public health or registry | Accept everything: FHIR from capable submitters, v2 from the installed base, files and a portal for the rest, and resolve identity centrally. Completeness depends on a low barrier to submit. |
| Analytics or AI program | FHIR as the canonical model and Bulk Data as the export path, fed by whatever the sources speak. Invest in terminology and provenance before models. |
How Bonami can help with HL7 and FHIR integration
Everything in this guide is work our healthcare technology practice does for hospitals, health systems, payers, public health agencies and digital health companies. The guide is meant to be useful whether or not you work with us; this section says plainly what we do, so a team planning an integration knows what to ask.
HL7 v2 integration
Interface specification, channel development, Z-segment inventory and mapping, MLLP and ACK handling, and the monitoring that keeps interfaces quiet.
FHIR integration and API development
FHIR R4 servers and APIs, US Core profiling, SMART on FHIR, Bulk Data, Subscriptions and CDS Hooks.
EHR and EMR integration
Connecting Epic, Oracle Health, athenahealth and practice systems to labs, pharmacies, radiology, billing and patient apps, in both directions.
Data transformation and terminology
V2-to-FHIR and CDA-to-FHIR mapping from the published guides, terminology services with maintained ConceptMaps, and profile validation.
Integration architecture
Reference architecture, engine and FHIR server selection, canonical model design, identity resolution and master patient index strategy.
Interoperability modernization
Incremental migration from point-to-point v2 to a governed FHIR platform, including the regulated APIs a certified system or payer must meet.
From our published case studies
This is work we have delivered, not a service list. We also built APPNEA, a sleep and dental care platform with seven HL7 interfaces covering registration, demographics, claims and results.
Frequently asked questions about HL7 and FHIR integration
What is HL7 FHIR integration?
HL7 FHIR integration connects healthcare systems so that data exchanged as HL7 v2 messages and data served as FHIR resources can move between them and be used reliably. Typically an integration engine receives HL7 v2 events such as admissions and lab results, translates them into FHIR resources like Patient, Encounter and Observation, and exposes them through a secure FHIR API for apps, payers and analytics.
What is the difference between HL7 and FHIR?
HL7 v2 is an event-driven messaging standard that sends pipe-delimited segments over persistent connections, usually MLLP. FHIR is a resource-based standard that exchanges JSON or XML resources through a RESTful API and is constrained by published profiles. Both are published by HL7 International; FHIR is the newer generation and is built for apps, patients and cross-organization access.
What does HL7 FHIR stand for?
HL7 stands for Health Level Seven, the standards organization founded in 1987, whose name refers to the seventh, application, layer of the OSI networking model. FHIR stands for Fast Healthcare Interoperability Resources and is pronounced "fire". HL7 FHIR is the FHIR standard published by HL7 International.
Is FHIR replacing HL7 v2?
Not in the systems that already speak HL7 v2, and not soon. Laboratory, pharmacy, radiology and bed-management interfaces that work are rarely re-built. FHIR replaces the lack of a good answer for app, patient, payer and cross-organization access. Most healthcare environments run both and translate between them in an integration layer.
Is HL7 a coding language?
No. HL7 is not a programming language; it is a family of data exchange standards. HL7 v2 messages are plain text made of segments and delimited fields, and FHIR resources are JSON or XML documents. Developers read and write them in ordinary languages such as Java, C#, Python or JavaScript, usually with a parsing library or an integration engine.
Can you give an example of HL7 data?
A typical example is an ADT^A01 admit message. Its PID segment looks like PID|1||MRN-0045821^^^CITYHOSP^MR||ROY^AMARA^K||19840312|F, where PID-3 is the medical record number, PID-5 the name as family^given, PID-7 the date of birth and PID-8 the administrative sex. This guide shows the full message and the FHIR Patient resource it becomes.
What type of API does FHIR use?
FHIR defines a RESTful API over HTTPS. Clients use GET to read and search, POST to create, PUT to update and DELETE to remove resources, exchanged as JSON (application/fhir+json) or XML. FHIR also supports documents, messaging, Bulk Data export and Subscriptions, but the REST API is its primary mode.
What are FHIR resources?
FHIR resources are the building blocks of FHIR: defined objects for clinical and administrative concepts such as Patient, Encounter, Observation, Condition, MedicationRequest and DiagnosticReport. FHIR R4 defines about 145 resource types. Each has typed elements, a logical id that makes it addressable by URL, and references to related resources.
How does HL7 to FHIR mapping work?
HL7 v2 segments and fields are mapped to FHIR resources and elements: PID to Patient, PV1 to Encounter, OBR to ServiceRequest and DiagnosticReport, OBX to Observation. Dates are reformatted, repetitions become arrays and codes are translated through concept maps. HL7 publishes a V2-to-FHIR implementation guide that projects should start from.
What is an HL7 integration engine?
An HL7 integration engine, also called an interface engine, is software that receives messages from source systems, parses and transforms them, maps fields and codes, validates, routes to destinations, retries on failure and logs every transaction. Mirth Connect, Rhapsody and Cloverleaf are common examples. It decouples systems so each can change independently.
How does HL7 integrate with EHR systems?
The EHR emits HL7 v2 messages when events occur, such as ADT for patient movement, ORM for orders and MDM for documents, and receives results, dispensing and scheduling messages back. An integration engine sits between the EHR and each departmental system, translating and routing. Modern EHRs also expose a FHIR API for apps.
Is FHIR HIPAA compliant?
No standard is compliant by itself. FHIR specifies how to apply web security standards, including TLS, OAuth 2.0 through SMART on FHIR and audit through AuditEvent, but HIPAA compliance depends on the whole system: access controls, encryption, audit, business associate agreements, risk analysis and organizational process.
Which FHIR version should I use?
FHIR R4 in most cases. It is the version US certification rules, the US Core profiles and the CMS payer APIs are built on. R4B and R5 exist and R6 is in development. Standardize internally on one version and convert at the edge when a partner exposes another.
How long does HL7 or FHIR integration take?
A single well-specified HL7 v2 interface between known systems can be built and tested in weeks. A FHIR API over an existing data set, with authorization and profiling, typically takes a few months. An enterprise integration platform with an engine, FHIR server, identity resolution and many channels is measured in quarters and delivered incrementally.
The takeaway: the interface is the infrastructure
HL7 v2 and FHIR are not rival answers to the same question. One is the nervous system of the hospital as it exists: event-driven, fast and tuned to decades of clinical workflow. The other is how that hospital meets everyone outside its walls: the patient with a phone, the payer with a rule, the analyst with a model. The organizations that succeed at HL7 and FHIR integration stop asking which to choose and start designing the layer where the two meet.
That layer has a definite shape. It receives every source in its native format and translates once, from published maps, into profiled FHIR resources coded to standard terminologies. It resolves identity deliberately. It validates at the boundary and treats every failure as a work item. It exposes one API with authorization and audit enforced at the server. And it is observable end to end, so “did the result reach the ward” is answered by a query, not a phone call.
Planning an HL7 or FHIR integration?
Whether you are connecting a lab to an EHR, exposing a certified FHIR API, building a payer data platform or preparing clinical data for AI, we start with your systems, your consumers and your obligations, then design the layer where they meet.
Sources
- HL7 International: HL7 Version 2 product suite
- HL7 FHIR Release 4 specification
- FHIR R4 resource list
- HL7 V2-to-FHIR implementation guide
- HL7 US Core implementation guide
- SMART App Launch implementation guide
- FHIR Bulk Data Access implementation guide
- CDS Hooks specification
All patient, clinician and facility details in the examples are fictitious. The architecture and engine diagrams are conceptual, not the design of a specific product. This article is general technical guidance, not legal or compliance advice.