Skip to main content
EHR
FHIR
SMART on FHIR
HL7
EHR Integration
Interoperability
Epic
HIPAA
Healthcare Apps

FHIR Integration for Healthcare Apps: A Builder’s Guide (2026)

By Garvita Amin, Co-Founder & CTO, VertiComply

September 18, 2026

15 min read

Share this article

FHIR integration for healthcare apps: FHIR R4 resources, SMART on FHIR authorization and EHR connection steps for Epic and Oracle Health

“Integrate with the EHR” is one line on a roadmap and, very often, the item that takes longest to ship. The standard itself is not the hard part. FHIR is well designed and reasonably pleasant to work with. What takes the time is everything around it: authorization, the approval process for each health system, terminology, and the question of whose data this is once it leaves the chart. This guide covers what a team building a healthcare app needs to know about FHIR integration in 2026, using code from our own templates as examples, and it says plainly which parts are still integration work that no generator does for you.

1. What FHIR Is, and FHIR vs HL7 v2

FHIR (Fast Healthcare Interoperability Resources) is an HL7 standard for exchanging health data over a REST API as JSON or XML. Each clinical concept, whether a patient, a lab value, a prescription or a visit, is a resource with a defined structure, and you read and write resources with ordinary HTTP: GET /Patient/123, POST /Observation, GET /Observation?patient=123&category=laboratory.

The version that matters in the US is FHIR R4 (4.0.1). It is the version US regulation points at, through the US Core Implementation Guide, and it is what certified EHRs expose. R5 exists and R6 is in development, but if you are integrating with American health systems in 2026, you are writing R4.

HL7 v2 is the older standard. It is still everywhere, and it is not going away.

HL7 v2FHIR R4
ShapePipe-delimited text messages (PID|1||12345^^^MRN||DOE^JANE)JSON or XML resources over REST
ModelEvent messages pushed between systems: an admission (ADT), a lab result (ORU), an order (ORM)Resources you query, create and update on demand
TransportUsually MLLP over a VPN, through an interface engineHTTPS with OAuth 2.0
Where you meet itInside a hospital: labs, radiology, registration feedsApps outside the hospital: patient apps, SaaS tools, anything third-party
OnboardingA custom interface per site, specified by that site’s integration teamA standard API, still gated by per-site app approval

A useful rule: if you are an app that a clinician or patient launches, you will use FHIR. If you are a system that has to receive every lab result a hospital produces as it happens, you will probably still get HL7 v2 messages, even in 2026. Plenty of production products do both.

Where C-CDA fits You will also meet C-CDA, an XML clinical document standard (a discharge summary, a continuity-of-care document). It predates FHIR and still carries a lot of record exchange between organisations. Treat it as a file you may have to parse, not an API you call.

2. The Resources Most Apps Actually Need

FHIR R4 defines around 145 resource types. A typical app touches fewer than ten. These cover most patient-facing and clinical-workflow products:

ResourceWhat it holdsTypical use
PatientDemographics, identifiers (MRN), contact detailsEvery integration starts here
EncounterA visit, admission or telehealth sessionScheduling, visit history, billing context
ObservationVitals, lab results, survey scores, anything measuredRemote monitoring, lab portals, outcomes tracking
ConditionDiagnoses and problemsProblem lists, risk scoring
MedicationRequestPrescriptions and medication ordersMedication lists, adherence apps
AllergyIntoleranceAllergies and adverse reactionsAnything that suggests or prescribes
DocumentReferenceA clinical document or note, with its contentFiling an AI scribe note, uploading a PDF
QuestionnaireResponseAnswers to a structured formPatient intake, screening instruments
AppointmentA booked slotScheduling and reminders

Two supporting ideas matter as much as the resources themselves.

US Core profiles. A profile narrows a base resource: which fields are required, which code systems are allowed. US Core is the set of profiles certified EHRs support, and it maps to USCDI (the United States Core Data for Interoperability), the federal list of data elements that must be exchangeable. If your data fits US Core, the EHRs you talk to will understand it.

Terminology. The JSON shape is the easy part. The codes inside it are what receiving systems check: LOINC for labs and vitals, SNOMED CT for conditions, RxNorm for medications, ICD-10-CM for billing diagnoses, CVX for vaccines. An Observation with a well-formed body and a free-text code is, to most EHRs, an Observation they cannot file anywhere useful.

{
  "resourceType": "Observation",
  "status": "final",
  "category": [{ "coding": [{
    "system": "http://terminology.hl7.org/CodeSystem/observation-category",
    "code": "vital-signs" }] }],
  "code": { "coding": [{
    "system": "http://loinc.org", "code": "8867-4", "display": "Heart rate" }] },
  "subject": { "reference": "Patient/123" },
  "effectiveDateTime": "2026-09-18T14:05:00Z",
  "valueQuantity": { "value": 72, "unit": "/min",
    "system": "http://unitsofmeasure.org", "code": "/min" }
}

3. SMART on FHIR: How an App Gets In

FHIR describes the data. SMART on FHIR describes how a third-party app is allowed to reach it. It is a profile of OAuth 2.0 and OpenID Connect, and it is what the major EHRs implement for outside apps. The current version is SMART App Launch 2.x, which requires PKCE and uses a finer-grained scope syntax than v1.

The flow has four steps.

  1. Discovery. The app fetches /.well-known/smart-configuration from the FHIR server. It lists the authorization and token endpoints and the capabilities the server supports.
  2. Launch. Either an EHR launch, where a clinician opens your app from inside the EHR and the EHR passes a launch parameter with the current patient and encounter, or a standalone launch, where a patient opens your app directly and picks which record to connect.
  3. Authorize. The user signs in at the EHR, not in your app, and approves the scopes you asked for. You get back an authorization code.
  4. Token. You exchange the code for an access token, and usually a refresh token, plus launch context such as the patient ID. Every FHIR call then carries the token.

Scopes decide what the token can reach. Ask for the least you need.

launch/patient openid fhirUser offline_access
patient/Patient.r
patient/Observation.rs?category=laboratory
patient/DocumentReference.c

In SMART v2 syntax, r is read, s is search, c is create, u is update and d is delete. The patient/ prefix limits the token to one patient’s data, user/ gives the signed-in user’s access, and system/ is for backend services. The minimum-necessary standard in HIPAA and the scope list in your SMART request are the same idea, and a health system’s reviewer will read the scope list with that in mind.

Backend services are a different flow If nobody is present to sign in (a nightly sync, a population-health job), you use SMART Backend Services: the client-credentials grant with a JWT signed by your private key, and system/ scopes. Pair it with the Bulk Data $export operation when you need many patients at once. Health systems approve these more cautiously than user-facing apps, because no person is in the loop.

4. Getting Into Epic, Oracle Health and athenahealth

This is the part of FHIR integration that roadmaps under-estimate. Writing the code against a sandbox takes days. Being allowed to run it against a real health system’s production data takes much longer, and the steps are organisational rather than technical.

  1. Register as a developer with the vendor’s program: Epic’s at fhir.epic.com, Oracle Health’s (formerly Cerner) developer program, athenahealth’s developer portal. You get sandbox credentials and test patients.
  2. Build against the sandbox. Every vendor’s implementation has quirks: which search parameters they support, how they page results, which US Core profiles they emit, what they do with write requests. Test against each vendor you plan to support, not just one.
  3. Register the production app. You declare your redirect URIs, scopes, and whether the app is patient-facing, clinician-facing or a backend service.
  4. Get each health system to turn it on. For patient-facing apps that use the certified patient-access API, the process is usually lighter, because the regulation behind that API limits what a health system can demand. Clinician-facing and backend apps are different: each organisation decides for itself, usually after a security questionnaire, often after a BAA, and sometimes after a contract.

For a clinician-facing app, allow weeks to months per health system, not per vendor. The first go-live is the slowest, because you are also writing the security documentation, the data-flow diagram and the support process that every later site will ask for. Vendor program names and marketplace rules change often, so check the current terms before you plan around any of them.

Why the patient-access API is easier The 21st Century Cures Act and the ONC certification rules require certified EHRs to offer a standardised FHIR R4 API with SMART launch, and the information-blocking rules restrict how a health system can refuse or slow down a patient’s own request for their data. A patient connecting your app to their own record is the path those rules were written for. Writing data into the chart is not covered by any of it.

5. FHIR and HIPAA: A Format, Not a Safeguard

FHIR makes no compliance claims and has no compliance features. A FHIR resource containing a diagnosis is PHI exactly as a database row containing that diagnosis is. Everything in the Security Rule still applies to it:

  • Encryption. TLS 1.2 or later for every FHIR call, and encryption at rest for anything you cache. Tokens count as secrets too. See our PHI encryption guide.
  • Audit logging. Log every FHIR read and write with actor, patient, resource type and outcome. A bulk export is one request that touches thousands of records, so log what it returned, not just that it ran. See our audit logging guide.
  • Access control. The SMART token decides what the EHR will give you. Your own app still has to decide which of its users can see what it received.
  • Business associate agreements. If you pull PHI on behalf of a covered entity, you are a business associate and need a BAA, and so does every vendor in your stack that stores or processes that data.

There is one case where the answer changes. When a patient directs their provider to send their record to an app the patient chose, and that app is not acting for the provider, HHS has said the provider is not responsible for what the app does with the data afterwards, and the app is generally not a business associate. That does not make the app unregulated. The FTC’s Health Breach Notification Rule covers many consumer health apps outside HIPAA, as do state health-privacy laws such as Washington’s My Health My Data Act. Work out which side of that line your product is on before you design the data flow, because the two sides have different obligations.

6. Export, Read, Write-Back: Three Different Projects

“FHIR integration” covers three jobs with very different effort. Scope them separately.

DirectionWhat it meansEffort
ExportYour app produces FHIR from its own data, such as a patient downloading their record as a BundleLow. You control both ends of the mapping and no EHR approval is involved
ReadYour app pulls data from an EHR over SMART on FHIRMedium. The code is standard; the per-site approval is the long part
Write-backYour app creates or updates data inside the EHRHigh. Many EHRs accept only a few resource types for writing, and every site will review it closely

Export deserves more attention than it gets. Under HIPAA’s right of access (45 CFR 164.524), an individual can ask for their record in the electronic form they want if the practice can readily produce it. An app that can hand a patient a clean FHIR R4 Bundle meets that request with a single endpoint, and it is also the easiest way to prove your data model maps to FHIR at all.

Write-back is where plans go wrong. An AI scribe filing a signed note as a DocumentReference, or an intake chatbot writing a QuestionnaireResponse, are both reasonable designs. Neither works until the target EHR accepts that resource type for writing, the health system approves the write scope, and someone at that site agrees where in the chart the data should appear. Build write-back behind a flag, and make copy-to-clipboard or PDF the fallback until a site is live.

7. Six Mistakes That Get FHIR Resources Rejected

These come up repeatedly, and several came up in our own template code.

  1. Timestamps without an offset. FHIR requires a timezone whenever a dateTime includes a time. 2026-09-18T14:05:00 is invalid; 2026-09-18T14:05:00Z is valid. If your database stores naive timestamps, decide once, in one place, what timezone they are in.
  2. Your own status words. Encounter.status, Observation.status and MedicationRequest.status each have a fixed value set. Sending your app’s own "confirmed" or "expired" where FHIR expects "planned" or "completed" can make a receiving system reject the whole resource. Map every internal status explicitly, and map anything unknown to the spec’s own unknown value rather than passing it through.
  3. References that don’t resolve. A Bundle where an Observation points at Patient/42 but no Patient/42 is in the Bundle or on the server is broken, and validators will say so.
  4. Identifiers with no system. An MRN of "12345" means nothing on its own. Identifier.system should be a URI that names your organisation’s MRN namespace, so a receiving system can tell your 12345 from everyone else’s.
  5. Ignoring paging. Search results come back one page at a time, with a next link in Bundle.link. Code that reads only the first page works in a sandbox with five test patients and silently drops data in production.
  6. Treating structural checks as validation. Tests that check required fields and reference integrity are necessary, but they are not what the official HL7 FHIR validator does. The validator also checks codes against their value sets, which needs a terminology server. Run it before any partner does.

Here is how the first two look in the chart-export module of our general-practice template, where every internal status is mapped to the value set FHIR allows:

# Our vocabulary -> the value sets FHIR actually allows. Anything unrecognised
# becomes the spec's own "unknown" rather than being passed through: an invalid
# status code makes the whole resource unparseable to the receiving system.
_ENCOUNTER_STATUS = {
    "pending": "planned",
    "confirmed": "planned",
    "completed": "finished",
    "cancelled": "cancelled",
}

8. What a Generated App Gets, and What It Doesn’t

Our position is that you should know exactly where the generated code stops. Here is what VertiComply’s templates include today:

  • Chart export as a FHIR R4 Bundle. The general-practice clinic template lets a signed-in patient download their whole record as a collection Bundle containing Patient, Encounter, Observation, MedicationRequest, CarePlan, Composition and DocumentReference resources, served as application/fhir+json. It is rate-limited, and every export is written to the audit log. Tests cover structural R4 conformance: required elements, allowed status codes, and every reference resolving inside the Bundle. It has not been through the official validator with a terminology server.
  • A FHIR R4 API surface in the EHR template. The modular EHR template publishes a CapabilityStatement (fhirVersion 4.0.1), serves Patient read and create and a LOINC-coded Observation search for vitals, parses inbound HL7 v2 messages (MSH, PID and OBX segments), and audit-logs each call.

And here is what is still integration work, whatever tool you use:

  • SMART on FHIR. The EHR template’s FHIR endpoints are protected by the app’s own clinician sign-in, not by SMART tokens. The OAuth authorize and token flow that an outside SMART app would need is not implemented, and the template deliberately does not publish a SMART discovery document until it is.
  • A live connection to any real EHR. No template connects to Epic, Oracle Health or athenahealth, and the interoperability screens in demos show illustrative data. Connecting means the developer registration and per-site approval in section 4, and no code generator can do those for you.
  • Write-back. The AI scribe and clinical-documentation templates hand the signed note to the clinician to paste into the chart, and they say so. Filing it through the EHR’s API is production work, done per health system.

If you need that last part built, a live Epic or Oracle Health connection is the kind of project our custom build team scopes. For the wider question of what a no-code EHR can and can’t do, start with our EHR app builder guide. If payments are involved, our Stripe and EHR guide covers mapping charges to FHIR Claim resources without leaking PHI into the processor.

9. Frequently Asked Questions

What is FHIR integration?

FHIR integration means connecting a healthcare application to other systems, usually an EHR, through the HL7 FHIR standard: a REST API that exchanges clinical data as structured resources such as Patient, Observation and MedicationRequest. In practice it has three parts: mapping your data to FHIR resources and codes, authorizing access (usually with SMART on FHIR), and getting each health system to approve your app.

What is the difference between HL7 and FHIR?

FHIR is one of the standards HL7 publishes. When people say “HL7” they usually mean HL7 v2, an older pipe-delimited messaging standard that systems inside a hospital use to push events such as admissions and lab results to each other. FHIR is a newer REST API with JSON resources, designed for apps to query and update data on demand. Most hospitals run both: HL7 v2 for internal feeds and FHIR for third-party apps.

What is SMART on FHIR?

SMART on FHIR is the authorization layer for FHIR apps, built on OAuth 2.0 and OpenID Connect. It defines how an app discovers an EHR’s authorization endpoints, how it launches either from inside the EHR or on its own, which scopes it can request (such as patient/Observation.rs), and how it receives the current patient and encounter context. Major EHRs, including Epic and Oracle Health, use it for third-party app access.

How long does it take to integrate with Epic using FHIR?

Building against Epic’s sandbox typically takes days to a few weeks, depending on how many resources you use. Going live takes longer, because each health system approves your app separately, usually with a security review and often a BAA and contract. Patient-facing apps using the certified patient-access API tend to move faster. Clinician-facing and backend apps commonly take weeks to months per health system.

Is FHIR HIPAA compliant?

FHIR is a data format and API standard, so it is neither compliant nor non-compliant. Compliance depends on how you handle the data: TLS for every call, encryption at rest, audit logs of each read and write, least-privilege scopes and user permissions, and BAAs with vendors that touch PHI. An app a patient chooses to receive their own record may fall outside HIPAA, but it can still be covered by the FTC Health Breach Notification Rule and state health-privacy laws.

Which FHIR version should I use?

Use FHIR R4 (4.0.1) with the US Core profiles if you are integrating with US health systems. It is the version referenced by US certification rules and the one certified EHRs expose. R5 is published and R6 is in development, but production EHR APIs in the US are R4.

Does the 21st Century Cures Act require my app to support FHIR?

The Cures Act rules apply mainly to certified EHR developers, health information networks and healthcare providers. Certified EHRs must offer a standard FHIR R4 API, and the information-blocking rules restrict interference with access to health data. A third-party app is usually not directly required to support FHIR, but FHIR is the practical way to get data out of those certified APIs, and a FHIR export is the simplest way to meet a patient’s HIPAA right-of-access request.

Can I write data back into an EHR with FHIR?

Sometimes. Write support varies by EHR and by resource type, and it needs write scopes that each health system must approve. Documents, questionnaire responses and some observations are the most commonly accepted. Plan write-back as a separate project from reading, keep a manual fallback such as copy-to-chart or PDF, and log every write with who initiated it and what was filed.

Last reviewed 18 September 2026. Timelines are typical ranges, and vendor developer-program names and approval rules change often, so check current terms before planning around them. Nothing here is legal advice on whether HIPAA or another privacy law applies to a specific product.


Share this article:

Build Compliant Healthcare Apps in Minutes

VertiComply generates production-ready code with HIPAA, GDPR, and SOC 2 compliance built in.

Related Articles

Continue reading about healthcare compliance and development

Healthcare Technology
14 min read
EHR App Builder No Code: Build Your Own EHR System in 2026

What no-code EHR builders can actually do, integration with FHIR/HL7, and the 3 stages where most builds break. 2026 buyer’s guide.

Read article

Compliance
12 min read
How to Build a HIPAA-Compliant Healthcare App Without Code in 2026

Which no-code platforms sign BAAs, ship audit logs, and pass HIPAA out-of-the-box. Real comparison of 7 builders, with PHI-handling gotchas flagged.

Read article

AI & Compliance
13 min read
HIPAA Compliant AI: How to Build It Right in 2026

Which AI vendors sign HIPAA BAAs (OpenAI, Anthropic, Google), where PHI leaks in production LLM apps, and the architecture that keeps healthcare AI safe.

Read article

© 2026 VertiComply. All rights reserved.