Healthcare software rarely fails because the UI looks wrong. It fails because the data does not line up. A diagnosis shows up under the wrong patient, a medication dose appears in the wrong units, a lab result arrives without the time zone that downstream reporting expects, or the system quietly drops fields that were supposed to matter. When I worked on integrations between clinical systems, the most expensive bugs were never the ones you could see in a screenshot. They were the ones you only noticed after you compared payloads side by side and realized one party had interpreted a concept differently than the other.
This is where HL7 and FHIR come in. They are not glamorous technologies, and they do not replace good product decisions, security reviews, or clinical workflow design. But they give teams a shared language. In practice, that shared language is what turns a brittle integration project into something you can evolve over years.
HL7 in plain terms: a long-running effort to standardize healthcare communication
HL7 is a family of standards, most famously for clinical and administrative data exchange. The “HL7” you hear in healthcare engineering is not a single document that everyone reads once and then moves on. It’s a set of specifications that evolved because healthcare data has always been messy: different vendors build differently, regulations require different reporting semantics, clinicians document Learn more in human terms, and payers demand structured details.
Earlier HL7 versions, especially the message-based approach (think of “segments” and “fields” carried over an interface), were designed for reliable transmission between systems. Those older formats are still in the wild, and there are plenty of environments where “HL7” means those older message standards. They work, but they can be slow to adapt when the integration scope grows. Adding a new use case often means more interface contracts, more mapping rules, and more operational burden.
FHIR arrived with a different posture. Instead of focusing primarily on message structures, it emphasizes resources, identifiers, and APIs that fit how modern software is built. That does not make it automatically simpler, but it changes the default architecture from “custom interface per integration” toward “common model exposed over web technologies.”
FHIR: the model behind the APIs
FHIR stands for Fast Healthcare Interoperability Resources. The name is a bit marketing-y, but the core idea is concrete: represent healthcare concepts as a set of standardized “resources” with consistent JSON and XML structures. If HL7 messaging is often like exchanging forms between departments, FHIR is more like sharing objects in an application.
A few practical details are worth keeping in mind:
- Resources are designed to be composable. A patient is represented one way, observations another way, and clinical encounters yet another. When you need to connect them, you do that with references. Identifiers and references are first-class concepts. You do not just shove patient names into a payload and hope the receiving system can match them. You represent stable identifiers where possible. FHIR supports multiple interaction styles. Some teams use RESTful API calls, others rely on messaging patterns, and there are also batch and subscription capabilities that can fit different operational realities.
In day-to-day integration work, this difference matters. You can build a service that handles an Encounter resource, then reuse large parts of it when the next requirement involves Observations tied to that encounter. You are less likely to rewrite the world for every small change.
How standards change engineering work, not just data formats
When you implement an interface without a shared standard model, you end up with mapping logic that is effectively a bespoke translation layer for every pair of systems. Even if you have a careful engineer on the team, you still fight ambiguity.
I remember a project where a lab result came over correctly, but the “effective time” behaved differently depending on the source system. One system treated the timestamp as a measurement time, another treated it as the time the result became available. The number of hours spent not on the code, but on the debugging conversation, was a reminder that semantic meaning is part of the data.
Standards reduce ambiguity by constraining what fields mean and how they are used. FHIR does not eliminate ambiguity completely, but it makes it easier to document decisions, validate payload shapes, and reason about mapping trade-offs. When something is off, you can compare interpretations against the spec and the profiles you choose.
Resources, profiles, and the reality of “FHIR everywhere”
A common misconception is that adopting FHIR means you will get consistent payloads across vendors and use cases automatically. In reality, FHIR is an extensible framework. The base resources describe general structure. Most production deployments end up using “profiles” and implementation guides to narrow what is required, what is allowed, and how to interpret fields for a given domain.
This is where engineering judgment comes in. Profiles can help you reduce variation. They can also introduce complexity. If your team builds a parser that accepts everything in the base specification, it might process too much loosely and mask issues. If you validate strictly against a profile, you may block payloads that are “valid” in a broader sense but not conformant to your narrower expectations.
A realistic integration often lands in the middle:
- Accept a range of payloads but normalize to an internal representation. Validate what you can, record what you cannot, and build monitoring to catch systematic differences. Use profile-based validation where it helps prevent real downstream harm, such as missing required identifiers or incorrect references.
If you have ever dealt with identity matching, you already know what I mean. Most integrations fail not because the JSON is malformed, but because the receiving system cannot reliably connect an incoming record to the correct internal patient or encounter.
Observations and the trickiness of clinical meaning
Observations are a great example of why standards are necessary and not sufficient. An Observation resource can represent a wide range of clinical measurements and assessments: vital signs, lab results, symptom scores, imaging findings, and more.
At the code level, it can look straightforward: a code, a value, a unit, and a timestamp. In real healthcare workflows, those fields carry semantic weight:
- What does the code mean in this context? Is it a standard LOINC code, a local code, or a code mapped through a terminology service? Does the unit correspond exactly to the measurement type, or did someone convert values upstream? Is the timestamp the specimen collection time, result availability time, or reporting time? Are reference ranges included, and if so, do they match the patient’s demographic context?
FHIR gives you a consistent scaffold. But your implementation still needs strong decisions on terminology mapping, time interpretation, and how you handle missing elements. In production, it is common to see partial data: units may be absent, components may be split across messages, or the same measurement may arrive multiple times with different timestamps.
When teams get serious about interoperability, they build data hygiene into the pipeline: validate codes, normalize units, preserve original text when normalization is uncertain, and store provenance so you can trace a value back to its source.
Identifiers, references, and the patient matching problem
Focusing on resources is necessary, but it is not the whole story. References between resources rely on identifiers. FHIR can represent patient identifiers, provider identifiers, and encounter identifiers. But systems differ in what identifiers they consider authoritative.
In one integration I supported, the clinical system sent a patient reference using a local MRN, while the downstream analytics platform expected a different identifier. Even though both were “patient IDs,” neither system could safely assume the other’s ID was globally stable. The interface worked technically, but it created a quiet failure mode: duplicates. Clinical review caught it eventually, but the operational impact was immediate, since reporting and clinical decision support were affected.
FHIR can represent multiple identifiers and can link resources by reference. That helps, but it does not replace governance. You need rules for:
- which identifier to treat as primary in each context how to handle identifier reconciliation what to do when a reference cannot be resolved
The best outcomes I have seen come from pairing standard payloads with explicit identity management processes, sometimes involving a master patient index, sometimes involving deterministic rules plus fallbacks, and always involving monitoring.
Searching, subscriptions, and the shift from “push everything” to “serve on demand”
A lot of legacy integrations were built as “push” pipelines. A source system publishes messages to a destination, and the destination consumes them. That model works, but it can get expensive when requirements multiply. Every new use case adds another destination, another filter, another contract.
FHIR’s API-oriented design encourages a more flexible approach:
- clients can query only what they need systems can validate and transform data at the edge services can expose consistent endpoints across domains
FHIR also supports subscriptions, which can enable near real-time updates without inventing a custom webhook scheme per vendor. That matters for operational scenarios like result notifications, care team updates, and scheduling events.
In practice, you still need to design for reliability. Subscriptions are not a magic shield against retry storms, deduplication problems, or clock drift. Teams that succeed treat event ingestion like a system engineering problem: idempotent writes, careful sequencing, backfill workflows, and audit logs.
Mapping data between standards: where integrations earn their keep
Standards do not eliminate mapping. They standardize the shape of the mapping.
Consider that a source system may already store data in a legacy HL7 messaging model, but the receiving system expects FHIR resources. Mapping becomes a translation problem between two semantic models, not just two serialization formats.
medical softwareThe hard parts are usually consistent across projects:
- choosing the correct code system for a concept (especially for problems, medications, and observations) deciding where free-text documentation lives when a structured field is missing representing relationships such as “this observation is part of that panel” handling versioning when an upstream value changes, and the downstream record should reflect an update rather than a new entry
A useful pattern is to store the original representation alongside your normalized version. It costs storage and some implementation effort, but it turns debugging from a philosophical debate into a concrete comparison. When a clinician asks, “Why does this record show the value in kilograms instead of pounds?” you can answer with provenance.
Terminology and coding systems: the bridge you cannot ignore
Every interoperability story eventually runs into terminology. HL7 helps with data structure. FHIR helps with resource modeling. Neither automatically solves the “meaning of a code” problem.
In healthcare, you will see multiple coding systems used for the same clinical concepts. For example:
- medications may be represented by different drug code systems diagnoses may be documented with local codes or mapped from standardized terminologies lab tests often align with LOINC-style codes clinical problems may rely on ICD-style coding
FHIR includes standardized fields for codes and systems, and it supports extensions when you cannot represent a concept cleanly in the base model. But you still need a terminology strategy. That might include a terminology service, a curated mapping table, or a process for human review when mapping confidence is low.
I have seen teams underestimate this and treat terminology mapping as a “later step.” “Later” turns into months when you realize downstream reporting and clinical decision support rely on accurate codes. Once you tie code accuracy to patient safety, you cannot just “make it work.”
Validation, test tooling, and the discipline of conformance
FHIR implementations often succeed or fail based on how consistently teams test conformance and how they manage changes over time.
There are two layers of confidence you want:
Structural validation, meaning the payload matches the expected schema and required fields Semantic validation, meaning key fields are present and refer to meaningful concepts within your domainStructural validation catches typos, missing required elements, and incorrect datatypes. Semantic validation catches “the code is present but wrong,” “the unit is present but inconsistent with the observation type,” and “the reference points to a resource that does not exist in your system.”
In mature programs, teams build regression tests around example payloads from each partner. They keep a library of “known good” and “known tricky” cases, including missing fields and alternative representations. That sounds tedious until you experience a production outage caused by a small schema change upstream.
Trade-offs: where teams get surprised
Even with standards, integration projects can run into predictable surprises.
Strictness vs throughput
If you validate too strictly, you might reject payloads that are “good enough” for non-critical workflows. If you validate too loosely, you risk propagating errors.
A pragmatic approach is to route different quality levels differently. For example, you can accept payloads into a staging area when references are missing but values and codes are valid, then trigger a reconciliation workflow. Only promote records to your clinical systems when the data reaches a defined threshold.
Versioning and backward compatibility
FHIR versions evolve. Profiles evolve. Implementation guides evolve. Partners update their payload generation. Even if the “standard” remains the same, the reality is that your integration becomes a living contract.
That contract should include:
- explicit version support windows compatibility tests for partner updates clear deprecation plans for fields and behaviors
Extensions and interoperability drift
Extensions are how you represent what the base model does not cover. Used carefully, they enable innovation. Used casually, they fragment interoperability.
If you rely heavily on custom extensions, you may find that each partner effectively becomes its own dialect. The remedy is not to ban extensions, but to govern them: prefer standardized fields when possible, document extensions clearly, and consider whether your extension belongs in a broader profile or shared guide.
How HL7 and FHIR show up across the software lifecycle
Standards influence more than integration endpoints. They can affect how you design your domain model, your database schema, your event pipeline, and your API gateway.
One of the most valuable shifts I have seen is that teams start treating interoperability as a product capability rather than a side quest. Instead of a one-off mapping script, they build internal abstractions aligned with the resource model. They also implement observability so they can answer operational questions quickly.
If your system is ingesting resources, you want metrics like:
- payload acceptance rate by partner validation failures by profile and field deduplication rates time-to-reconcile when references cannot be resolved immediately distribution of codes and units for key observation types
That level of visibility turns “interoperability” from a vague goal into an engineering discipline.
Real-world architecture patterns that work
Different organizations choose different architectures based on their constraints, but a few patterns show up frequently.
A common pattern is an ingestion layer that accepts FHIR payloads, validates and normalizes them into an internal model, then exposes domain APIs to application services. This reduces coupling between clinical apps and partner quirks. It also gives you a single place to implement security, logging, and data governance.
Another pattern is “query-first” integration for read-heavy workflows. If your use case is to display the latest labs or medications, it may be more efficient to use FHIR search and read endpoints rather than building a heavy push pipeline. You still need caching and careful performance tuning, but you reduce data duplication.
For write-heavy or operationally sensitive workflows, systems often use controlled update patterns with idempotency keys, versioning checks, and explicit audit trails. In healthcare, “update” is not just a database operation. It can change clinical context, and you want to be able to explain what changed and when.
Where standards matter most: safety, auditability, and trust
Healthcare software is not just data plumbing. It is trust plumbing.
FHIR and HL7 help you build systems that are:
- auditable, because payloads map to well-defined resources and fields resilient, because standardized structures enable consistent validation and normalization evolvable, because resource-based APIs support expansion without rewriting every interface from scratch
But trust depends on implementation details. If you ignore identifiers, skip validation, or treat terminology as optional, you can still create systems that look interoperable on paper but fail in practice.
The best interoperability programs I have seen treat standards as a foundation and then invest in the hard surrounding work: data quality, governance, monitoring, reconciliation workflows, and partnership management.
Practical next steps for teams evaluating FHIR and HL7
If your organization is considering adopting FHIR for new integrations, the most useful starting point is not a deep dive into documentation pages. It is a review of your current failure modes. Where do you lose data today? Where do mappings break? How often do you spend days debugging semantic mismatches instead of shipping product improvements?
From there, define a small set of high-value workflows to pilot. Choose areas where structured data is most critical, such as patient identity references, observations, and care encounters. Then build an ingestion and normalization path that you can reuse.
A short, honest checklist helps keep the pilot grounded, for example:
- confirm you can map and validate codes with an agreed terminology approach agree on identifier rules and reconciliation behavior for unresolved references implement idempotent ingestion, with deduplication and audit logs design for partial payloads, missing fields, and timestamp inconsistencies define how you handle profile conformance and extensions across partners
When the pilot is successful, you can scale it into broader domains. When it fails, the logs and payload comparisons will tell you exactly why, and you will learn something actionable rather than repeating the same integration mistake in a bigger project.
FHIR and HL7 are standards, yes, but they are also working tools. They encode years of hard-earned lessons about what breaks in healthcare software. If you build with them thoughtfully, you can reduce the “integration tax” that slows teams down. And if you pair them with good engineering discipline, you end up with systems that do more than exchange data. They exchange meaning, reliably enough to support clinical and operational decisions.