If you are building a digital health product in 2026, the question is rarely whether you will integrate with Epic. It is how long the integration takes, which data you can actually read or write, and what the security review will demand before a hospital turns your app on. Epic powers the medical records of most large US health systems, so "Epic on FHIR" is usually the first real engineering decision a healthtech CTO has to get right.
This guide walks through Epic FHIR integration the way we approach it on real builds: what the FHIR R4 API gives you, how OAuth2 and SMART on FHIR control access, the difference between the three launch models, and the path from a sandbox test call to live patient data. It is written for founders, CTOs, and product engineers who need a working mental model before they scope the work. For the wider picture across every Epic module and interface, start with our Epic integration services.
What "Epic on FHIR" actually means
FHIR (Fast Healthcare Interoperability Resources) is the HL7 standard for exchanging healthcare data over a REST API. Epic exposes its data through FHIR R4, the version US health systems run today. When people say "Epic on FHIR," they mean the public developer program at fhir.epic.com plus the per-customer FHIR endpoints that every Epic site exposes.
The data you can reach is shaped by US regulation. Epic's FHIR API is built around US Core profiles and the USCDI data set, which the federal interoperability rules require. In plain terms: you get reliable read access to a defined set of clinical data, and a narrower, more controlled set of write operations.
The resources you will touch most often are Patient, Observation (labs and vitals), Condition (problems), MedicationRequest, AllergyIntolerance, DocumentReference, and Appointment. Read access to these is broad and stable. Write access exists for specific workflows, but it is gated, varies by Epic version, and often needs Epic's involvement to enable. A useful rule when scoping: assume read is available, and confirm every write before you promise it to a customer.
How apps authenticate: OAuth2 and SMART on FHIR
You never hit an Epic FHIR endpoint with a raw API key. Every call carries an OAuth2 access token, and the framework that issues it is SMART on FHIR. SMART adds a healthcare-specific layer on top of OAuth2: scopes that describe exactly what a token can do (for example patient/Observation.read or system/Patient.read), plus launch context so the token knows which patient and which user it belongs to.
The interactive flow is the OAuth2 authorization code grant. Your app sends the user to Epic's authorize endpoint, the user logs in and consents to the requested scopes, Epic returns an authorization code, and your backend exchanges that code (with your client credentials) for an access token. From there, every FHIR request carries the token in the Authorization: Bearer header. Tokens are short-lived, so for patient-facing apps you also handle refresh tokens to keep a session alive.
For server-to-server work where no human is present, you use SMART Backend Services instead. Your app authenticates with a signed JWT (asymmetric keys you register with Epic), receives a token with system/* scopes, and reads data without a user in the loop. This is the path for analytics pipelines, registries, and Bulk Data exports.
A quick token-request example
POST /oauth2/token HTTP/1.1
Host: fhir.epic.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE_FROM_EPIC
&redirect_uri=https://yourapp.example.com/callback
&client_id=YOUR_CLIENT_ID
The response gives you an access_token, an expires_in value, the granted scope, and (for patient launches) the patient context ID. Read those fields carefully. The scope Epic grants is not always the scope you asked for, and you should code defensively against that gap.
The three ways apps connect to Epic FHIR
One reason Epic FHIR projects stall is that teams pick the wrong launch model and rebuild halfway through. There are three, and the right one depends on where your app runs.
EHR launch is for apps that open inside Epic. A clinician clicks your tool from a patient's chart in Hyperdrive, and Epic passes the patient and user context to your app automatically. This is how a SMART app feels native to the clinician. You request launch plus the clinical scopes you need, and the context arrives with the token.
Standalone launch is for patient-facing apps. A patient logs in through MyChart credentials, your app requests patient/*.read scopes, and you get access to that single patient's record. There is no Epic session involved, which makes this the model for consumer mobile and web apps.
Backend Services is the no-user model described above. Use it when you are syncing data on a schedule or pulling population-level data with system/* scopes and the Bulk Data $export operation.
From sandbox to production: the path that surprises people
The technical work of calling a FHIR endpoint is the easy part. What stretches timelines is everything between your first sandbox call and reading a real patient's chart at a customer site.
You start at fhir.epic.com, where you register your app on the Connection Hub and receive a Client ID. You build and test against the public sandbox, which uses synthetic patients, not real data. Changes you make to your app registration can take up to an hour to sync to the sandbox, so build that lag into your testing rhythm.
To move beyond synthetic data you sign up for Epic Vendor Services, which gives you expanded documentation, support, and a larger testing surface. Then comes the part many teams underestimate: a real Epic customer has to enable your app in their environment, each site has its own FHIR base URL, and your app only sees that organization's data once their Epic team configures it. Production go-live means live PHI, monitored, under a signed agreement.
What does this mean for your plan? A read-only MVP against the sandbox can come together in weeks. We took one healthtech client from zero FHIR capability to a working Epic integration in five weeks. A write-back integration that needs Vendor Services and multiple customer sites is a 6 to 14 month effort. Scope honestly, and stage the work so you have something testable early.
The gotchas that quietly break Epic FHIR projects
A handful of issues account for most of the lost time we see when teams come to us mid-project:
- Per-customer base URLs. There is no single Epic endpoint. Every health system has its own FHIR base URL, and your app has to manage a directory of them.
- Scope availability varies. A scope that works in the sandbox may not be turned on at a given customer site, or in their Epic version. Confirm, do not assume.
- Write access is the hard part. Reading USCDI data is well supported. Writing back (orders, notes, flowsheet data) is narrower, version-dependent, and frequently needs Epic to enable it.
- Token lifetimes and refresh. Access tokens expire quickly. Patient apps need a clean refresh-token flow or sessions break mid-use.
- FHIR is not real-time messaging. If you need to receive a lab result the moment it is resulted, FHIR polling is the wrong tool. That is an HL7 v2 job, which we cover in our guide to Epic Bridges integration.
FHIR or HL7 v2? Use the right tool
FHIR and HL7 v2 are not competitors. They solve different problems. FHIR is for application data access: a clean REST API for reading and (selectively) writing structured records, ideal for apps, portals, and analytics. HL7 v2, running through Epic Bridges, is for real-time clinical messaging: lab orders and results, ADT, charges, scheduling events flowing the instant they happen.
Most production integrations we build use both. The app reads patient context and history over FHIR, and the operational data moves over HL7 v2. If you are weighing the two, our breakdown of how third-party apps connect to Epic maps each method to its use case.
How we approach Epic FHIR builds
Healthcare is the only industry we work in, and we have built EHR integrations for 30+ healthtech startups. On the FHIR side specifically, we open-sourced a Headless EHR covering 28 clinical domains and more than 70 FHIR R4 resources, which means we are not learning the resource model on your timeline. We have shipped multi-EHR data platforms that read from Epic, Cerner, Allscripts, and athenahealth behind one interface.
The engagements are HIPAA-compliant by default, and we hold SOC 2 and ISO 27001, which matters when your customer's security review lands. Our architecture is FHIR R4 native, so interoperability is designed in from the first sprint rather than bolted on before a launch. If a hospital security review has stalled a generalist dev shop's work, that is usually the moment teams call us.
Where to start
If you are scoping an Epic FHIR integration, the highest-value first step is deciding which launch model fits your product and listing the exact resources and scopes you need to read or write. Get that list right and the rest of the project plans itself.
If you want a second set of eyes on that scope, or you are facing a security review with a deadline, we can help. See our full Epic integration services for the complete picture across FHIR, HL7, and every Epic module, or reach out to talk through your specific build.



