Build a SMART on FHIR App for Epic.
The three launch types, the OAuth 2.0 flow, the scopes, and the app registration that actually gets you live in Epic — explained by engineers who ship SMART apps, on patterns validated against Inferno g10.
The Standard Way Apps Run on Epic
SMART on FHIR is the HL7 standard that lets a third-party app authenticate to an EHR with OAuth 2.0 and read or write data through FHIR APIs. It's how virtually every modern app connects to Epic — and Epic officially recommends and supports it. Instead of proprietary hooks, you get a portable pattern that also works across Oracle Health, athenahealth, and the rest.
The single most important decision is your launch type — it determines how your app starts, who authorizes it, which scopes you request, and how Epic registers you. There are three: provider (EHR launch), patient (standalone), and backend (system-to-system). Pick the wrong one and you rebuild; pick the right one and the rest of the integration follows. Below, we break down all three the way we'd scope them with you.
Which SMART Launch Does Your App Need?
Provider, patient, or backend — each has a different flow, scope pattern, and Epic registration. Pick one.
Provider · EHR Launch
Your app opens inside Epic (in the clinician's Hyperdrive session) from a button or activity in the chart. Epic hands your app a launch token plus the current patient, encounter, and user context.
How It Starts
Epic opens your registered launch URL with launch and iss (the FHIR base URL). Your app then runs the standard OAuth /authorize → /token exchange, passing the launch parameter back.
Typical Scopes
launch, openid, fhirUser, patient/Patient.r, patient/Observation.rs, user/*.rs — scoped to the launched patient/user.
Epic Registration
Register as a Clinician-facing app with an EHR-launch redirect URI. It surfaces in the provider's workflow and runs in Hyperdrive (no COM dependencies).
Watch For
Context is the launched patient only — no patient picker. Token lifetimes are short; you refresh within the session, not across days.
Clinical decision support, documentation, ordering, and any tool that lives in the clinician's workflow at the point of care.
Patient · Standalone Launch
The patient starts your app from outside Epic (your website or mobile app) and authorizes it against MyChart. There's no launch token — the patient logs in and consents to the scopes you request.
How It Starts
Your app sends the patient to Epic's /authorize endpoint. The patient authenticates via MyChart and approves your scopes; you exchange the code for a token at /token.
Typical Scopes
openid, fhirUser, offline_access (for a refresh token), patient/*.rs — access to that patient's own record.
Epic Registration
Register as a Patient-facing app. MyChart is the authorization server; use offline_access so you can refresh without re-prompting the patient.
Watch For
You only ever get the authorizing patient's data. Handle refresh tokens securely, and expect each health system's MyChart to be a separate connection.
Personal health records, patient engagement, remote monitoring apps, and patient-mediated data products.
Backend · System-to-System
No human in the loop. Your server authenticates directly to Epic with the SMART Backend Services flow — a signed JWT using your private key (you upload the public key to Epic). Used for automated data movement and bulk export.
How It Starts
Your server creates and signs a JWT, then calls /token with grant_type=client_credentials and a client_assertion. You get a system-scoped access token — no user, no launch.
Typical Scopes
system/Observation.rs, system/*.rs — plus FHIR Bulk Data $export for population-scale pulls.
Epic Registration
Upload production and non-production public keys (or a JWK Set URL); public keys must be a base64-encoded X.509 certificate. Epic recommends backend for IPS queries and $match.
Watch For
Key management is the whole game — rotate carefully, keep prod/non-prod separate, and remember the app record is immutable once ready for production.
Data pipelines, analytics, population health, and any automated server-to-server flow with no interactive user.
From Launch to a FHIR Call, Step by Step
Provider and patient apps share the same authorization-code flow; backend swaps it for a signed-JWT client-credentials grant. Here's the request that starts it.
# 1. Provider EHR launch — redirect the browser to Epic's authorize endpointGET https://{fhir-base}/oauth2/authorize?response_type=code&client_id={your-non-prod-client-id}&redirect_uri=https://yourapp.com/callback&scope=launch openid fhirUser patient/Observation.rs&launch={launch-token-from-epic}&state={csrf}&aud={fhir-base}# 2. Epic redirects back with ?code=... → exchange it at the token endpointPOST https://{fhir-base}/oauth2/tokengrant_type=authorization_code & code=... & redirect_uri=...# 3. Response carries the token AND the launch context{ "access_token": "...", "patient": "e0w0...","encounter": "eXy...", "scope": "patient/Observation.rs" }# 4. Call FHIR with the bearer tokenGET https://{fhir-base}/api/FHIR/R4/Observation?patient=e0w0...Authorization: Bearer {access_token}
Illustrative — endpoints, parameters, and context follow the SMART App Launch v2 spec that Epic implements. Backend apps skip steps 1–2 and POST a signed JWT assertion to /token instead.
Ask for Exactly What You Need — Nothing More
SMART App Launch v2 replaced v1's blunt .read/.write with granular per-operation permissions. A scope is context / resource . operations.
The operation letters are create · read · update · delete · search. v1 → v2 maps .read → .rs, .write → .cud, .* → .cruds. Least-privilege scoping speeds up every customer's security review.
From fhir.epic.com to a Live Launch
SMART is the easy part; the Epic registration mechanics are where teams stumble. Four things to get right.
Register & Get Client IDs
Create the app on fhir.epic.com; you receive both a non-production and a production client ID.
Set Launch Type & Redirect
Declare clinician-, patient-, or backend-facing; add redirect URIs; for backend, upload your X.509 public key.
Test in the Sandbox
Use the non-prod ID against Epic's "Try It" test patients; validate scopes and launch context.
Mark Ready for Production
Required before any customer can use it — and it locks the app record. Changes need a new registration.
Because the record is immutable once live, we lock down your scopes, redirect URIs, and launch type before you mark it ready — so you're not re-registering later. See the full Epic vendor journey.
Where SMART-on-Epic Builds Go Wrong
The mistakes we're most often called in to fix.
Building a provider app when you needed patient (or vice-versa) means re-registering and re-scoping. Decide launch type first.
Requesting *.cruds when you only read slows down every customer's security review. Ask for least privilege.
Once marked ready for production the record is immutable — changing a redirect URI means a whole new app. Get it right up front.
Patient apps that skip offline_access force patients to re-authorize constantly. Backend apps must handle JWT re-signing.
SMART on FHIR for Epic, Answered
The questions we hear most when teams start a SMART build.
What's the Difference Between EHR Launch and Standalone Launch?
Do I Need SMART Backend Services, or a Regular SMART App?
system/ scopes. Many products use both.How Do SMART v2 Scopes Work?
context/Resource.operations. The context is patient/ (the launched patient), user/ (the logged-in user's access), or system/ (no user). The operations are letters — create, read, update, delete, search. So patient/Observation.rs = read + search Observations for one patient. Request the minimum you need.Does Epic Support SMART on FHIR Write-Back?
How Do I Get an Epic Sandbox to Test My SMART App?
fhir.epic.com; you're issued a non-production client ID and can test your launch and FHIR calls against Epic's example "Try It" test patients — no real customer needed. When you're ready, you mark the app ready for production to use the production client ID. See our Epic integration overview.Will My SMART App Pass Epic's / a Customer's Review?
More on Epic Integration
Epic Integration, End to End →
The full Epic ecosystem, programs, Vendor Services, Showroom, and the vendor journey.
EHR Integration Across Vendors →
Epic, Oracle Health, athenahealth, MEDITECH and more — the same SMART patterns, per vendor.
Healthcare Interoperability →
How EHRs, labs, devices, and payers connect into one FHIR data layer.
Tell Us What Your SMART App Needs to Do.
Book a scoping call — we'll pick your launch type, scope it to least-privilege, and map the path from the Epic sandbox to a live customer. Reviewed by an integration engineer, not a sales queue.
Thanks — We've Got It.
A Nirmitee integration engineer will reach out within one business day.