Healthcare

Epic and Oracle Health Mobile Integration: Complete Developer Guide

March 17, 202615 min readUpdated Nov 8, 2026
Written by
Jitendra Choudhary
Jitendra Choudhary

CTO & Co-Founder

CTO & Co-Founder at Nirmitee.io. Architects healthcare integrations across FHIR, SMART on FHIR, ABDM and NHCX, writing from production experience taking hospital software from sandbox to go-live.

Epic and Oracle Health Mobile Integration: Complete Developer Guide

More than 89% of U.S. hospitals run on either Epic or Oracle Health (formerly Cerner) as their primary EHR. According to ONC data from 2025, these two platforms collectively manage clinical records for over 300 million Americans. For healthtech companies building mobile applications, integrating with these EHRs is not optional. It is the difference between a product that clinicians actually use and one that sits unused.

The challenge is real: Epic and Oracle Health each have their own certification processes, API flavors, and marketplace requirements. A mobile app that works with one does not automatically work with the other. This guide walks through every layer of the integration, from SMART on FHIR authentication to Epic production review, with code examples and hard-earned lessons from production deployments.

Understanding SMART on FHIR App Launch for Mobile

Both Epic and Oracle Health support the SMART on FHIR App Launch Framework. This is the industry-standard protocol for launching third-party applications within an EHR context. On mobile, the flow differs from browser-based launches in important ways.

The Mobile App Launch Sequence

The mobile SMART on FHIR flow uses the Authorization Code Grant with PKCE (Proof Key for Code Exchange). Unlike confidential web apps, mobile apps cannot safely store client secrets. PKCE solves this by generating a one-time code verifier and challenge for each authorization request.

Here is the step-by-step flow:

  1. Launch context received — The EHR passes a launch token and the FHIR server URL to your mobile app via a deep link or custom URL scheme.
     
  2. Discovery — Your app fetches the server's .well-known/smart-configuration endpoint to get authorization and token URLs.
     
  3. Authorization request — Your app opens a system browser (not a WebView) with the authorization URL, including the PKCE code challenge, requested scopes, and redirect URI.
     
  4. User authentication — The clinician or patient authenticates through the EHR's login page.
     
  5. Token exchange — Your app receives the authorization code at the redirect URI and exchanges it for an access token, using the PKCE code verifier.
     
  6. FHIR API access — Your app uses the access token to call FHIR R4 endpoints for patient data.

Code Example: SMART on FHIR Discovery on iOS

import Foundation

struct SMARTConfiguration: Codable {
    let authorization_endpoint: String
    let token_endpoint: String
    let capabilities: [String]
    let scopes_supported: [String]?
}

func discoverSMARTEndpoints(fhirBaseURL: String) async throws -> SMARTConfiguration {
    let url = URL(string: "\(fhirBaseURL)/.well-known/smart-configuration")!
    let (data, response) = try await URLSession.shared.data(from: url)
    
    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw SMARTError.discoveryFailed
    }
    
    return try JSONDecoder().decode(SMARTConfiguration.self, from: data)
}

// Usage
let config = try await discoverSMARTEndpoints(
    fhirBaseURL: "https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4"
)
print("Auth endpoint: \(config.authorization_endpoint)")

Code Example: PKCE Flow on Android (Kotlin)

import java.security.MessageDigest
import java.security.SecureRandom
import android.util.Base64

class PKCEHelper {
    private val codeVerifier: String
    val codeChallenge: String

    init {
        val bytes = ByteArray(32)
        SecureRandom().nextBytes(bytes)
        codeVerifier = Base64.encodeToString(bytes, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
        val digest = MessageDigest.getInstance("SHA-256").digest(codeVerifier.toByteArray())
        codeChallenge = Base64.encodeToString(digest, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
    }

    fun buildAuthURL(authEndpoint: String, clientId: String, redirectUri: String, scopes: String): String {
        return "$authEndpoint?" +
            "response_type=code&" +
            "client_id=$clientId&" +
            "redirect_uri=$redirectUri&" +
            "scope=$scopes&" +
            "code_challenge=$codeChallenge&" +
            "code_challenge_method=S256&" +
            "aud=https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4"
    }
}

Epic Integration: Showroom and MyChart

Epic's ecosystem has two distinct integration paths depending on whether you are building for patients or providers.

Patient-Facing Apps via MyChart

Patient apps integrate through MyChart, Epic's patient portal. When a patient authorizes your app through MyChart, they grant access to their clinical data using FHIR R4 APIs. The key scopes available for patient apps include:

  • patient/Patient.read — Demographics
  • patient/Observation.read — Lab results and vitals
  • patient/MedicationRequest.read — Active medications
  • patient/AllergyIntolerance.read — Allergy records
  • patient/Condition.read — Problem list
  • patient/DocumentReference.read — Clinical documents
  • patient/Immunization.read — Vaccination records

Important limitation: MyChart does not support write operations for third-party apps in most configurations. You can read data, but cannot create orders, update problems, or write notes back. Epic restricts write access to apps that go through a deeper integration review.

Provider-Facing Apps via Hyperspace

Provider apps launch within Epic Hyperspace (the clinician-facing client). These apps receive richer context, including the current patient, encounter, and the logged-in practitioner's identity. Provider scopes include:

  • launch — Required for EHR launch context
  • user/Patient.read — Read any patient the provider can access
  • user/Encounter.read — Current and historical encounters
  • user/DiagnosticReport.read — Lab and imaging reports
  • user/Procedure.read — Surgical and procedural history

Epic App Review Process

Third-party apps that connect to Epic register through Epic on FHIR, and each customer must enable them. The process involves:

  1. Registration — Create a developer account and register your application. You specify whether it is a patient or provider app, list the FHIR resources you need, and describe your use case.
     
  2. Sandbox testing — Epic provides a sandbox environment with synthetic patient data. You must demonstrate that your app works correctly against this sandbox.
     
  3. Security review — Epic reviews your app's authentication implementation, data handling, and HIPAA compliance practices.
     
  4. Clinical review — For apps that influence clinical decisions, Epic's clinical team reviews the app's safety and appropriateness.
     
  5. Production approval — After passing all reviews, your app receives a production client ID. Individual health systems can then enable your app for their users.

Typical timeline: 3-6 months from submission to production approval. Cost varies, but expect $15,000-$25,000 in annual marketplace fees plus development costs.

Oracle Health (Cerner) Integration: CODE Program

Oracle Health's developer program, CODE, provides a parallel path for third-party integrations. Since Oracle's acquisition, the platform has been transitioning toward Oracle Cloud Infrastructure, but the FHIR APIs remain stable.

Key Differences from Epic

AspectEpicOracle Health CODE
FHIR VersionR4 (full support)R4 (full support)
Auth StandardSMART on FHIR + PKCESMART on FHIR + PKCE
Patient AccessVia MyChartVia HealtheLife / Patient Portal
Write SupportLimited for third-partyMore open for certified apps
Review Timeline3-6 months2-4 months
Annual Fee$15K-$25K$10K-$20K
Sandbox QualityExtensive synthetic dataGood, but fewer edge cases
Custom ResourcesEpic-specific extensionsMillennium-specific extensions

Oracle Health FHIR Scopes

Oracle Health supports the standard SMART scopes but also offers system-level access for backend services more readily than Epic. This makes Oracle Health a stronger choice for apps that need to run automated data pipelines or population health queries.

{
  "scope": "system/Patient.read system/Observation.read system/MedicationRequest.read",
  "grant_type": "client_credentials",
  "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
  "client_assertion": "eyJhbGciOiJSUzM4NCIs..."
}

Building a Cross-EHR Mobile App Architecture

The practical challenge is building one mobile app that works with both Epic and Oracle Health. Here is the architecture pattern we use at Nirmitee for production deployments.

EHR integration architecture layers" width="1200">

Abstraction Layer Pattern

The key is an EHR abstraction layer that normalizes differences between Epic and Oracle Health APIs. Your mobile app never calls EHR APIs directly. Instead, it communicates with your backend, which handles the EHR-specific logic.

// EHR Abstraction Interface
interface EHRClient {
  getPatient(patientId: string): Promise<FHIRPatient>;
  getObservations(patientId: string, category: string): Promise<FHIRBundle>;
  getMedications(patientId: string): Promise<FHIRBundle>;
  getAllergies(patientId: string): Promise<FHIRBundle>;
  refreshToken(refreshToken: string): Promise<TokenResponse>;
}

// Epic Implementation
class EpicClient implements EHRClient {
  private baseUrl: string;
  
  async getObservations(patientId: string, category: string): Promise<FHIRBundle> {
    const url = `${this.baseUrl}/Observation?patient=${patientId}&category=${category}`;
    return this.fetchWithAuth(url);
  }
}

// Oracle Health Implementation  
class OracleHealthClient implements EHRClient {
  private baseUrl: string;
  
  async getObservations(patientId: string, category: string): Promise<FHIRBundle> {
    const dateRange = `ge${this.getDefaultStartDate()}`;
    const url = `${this.baseUrl}/Observation?patient=${patientId}&category=${category}&date=${dateRange}`;
    return this.fetchWithAuth(url);
  }
}

Handling EHR-Specific Quirks

Despite both supporting FHIR R4, there are real differences that trip up developers:

  • Date formats — Epic returns dates in YYYY-MM-DD format, while Oracle Health sometimes includes timezone offsets like 2026-03-17T10:00:00-05:00.
     
  • Search parameters — Epic supports _revinclude on more resources than Oracle Health. Oracle Health requires explicit date ranges on Observation searches.
  •  
  • Pagination — Epic uses Bundle.link with a next relation. Oracle Health uses the same mechanism but with different page sizes (default 20 vs Epic's default 10).
     
  • Extensions — Both add proprietary extensions. Epic uses http://open.epic.com/FHIR/StructureDefinition/ namespace while Oracle Health uses https://fhir-ehr.cerner.com/r4/StructureDefinition/.
     
  • Token expiry — Epic access tokens typically expire in 5 minutes. Oracle Health grants longer-lived tokens (up to 10 minutes) but refresh token behavior differs.

Patient Apps vs. Provider Apps: What to Build

Patient App Considerations

Patient-facing mobile apps have the broadest addressable market but the most constraints:

  • Read-only access in most configurations. You can display lab results, medications, and visit history, but cannot write back.
     
  • Patient must authorize each connection. Unlike provider apps that launch in-context, patient apps require the user to log into their patient portal.
     
  • Data freshness varies. Some health systems update patient-facing data in near-real time; others batch updates every 24 hours.
     
  • Limited encounter context. Patient apps do not know which encounter is current — they see the patient's entire longitudinal record.

Successful patient apps focus on areas where read-only access is sufficient: health dashboards, medication tracking, lab result visualization, and care plan monitoring.

Provider App Considerations

Provider apps have richer capabilities but a narrower deployment model:

  • Launch context gives you the current patient, encounter, and practitioner automatically.
     
  • Write access is possible through deeper integration tiers. You can create clinical documents, update problem lists, or submit orders.
     
  • Embedded in workflow. Provider apps that integrate into Hyperspace or PowerChart feel native to clinicians rather than being a separate tool.
     
  • Higher compliance bar. Apps that influence clinical decisions face additional safety reviews and may require FDA 510(k) clearance.

API Rate Limits and Performance Optimization

Both Epic and Oracle Health enforce API rate limits that mobile developers must account for. Ignoring these limits will result in HTTP 429 responses and potentially have your app suspended.

MetricEpicOracle Health
Requests per minute120 per patient session100 per patient session
Concurrent connections10 per app15 per app
Bundle page size limit100 resources50 resources
Bulk data exportSupported (SMART Backend)Supported (limited)

Performance Strategies

  1. Cache aggressively — Patient demographics and allergy lists change infrequently. Cache for the session duration and invalidate on user refresh.
     
  2. Use _include and _revinclude — Fetch related resources in a single request instead of making separate calls for each.
     
  3. Implement pagination correctly — Always follow the Bundle.link[next] URL rather than constructing offset-based queries.
     
  4. Background sync — For patient apps, sync data when the app is backgrounded using iOS Background App Refresh or Android WorkManager.

Timeline and Cost: What to Expect

Development Phases

  1. Phase 1: FHIR Integration (8-12 weeks) — Build the abstraction layer, implement SMART on FHIR auth, and connect to sandbox environments. Cost: $60K-$120K.
     
  2. Phase 2: Testing and Compliance (4-6 weeks) — Run Inferno test suites, conduct HIPAA security assessment, prepare documentation. Cost: $25K-$50K.
     
  3. Phase 3: Certification (8-16 weeks) — Submit to Epic and/or CODE, respond to review feedback, iterate on requirements. Cost: $15K-$30K in fees plus developer time.
     
  4. Phase 4: Site Deployment (4-8 weeks per site) — Each health system must enable your app individually. Their IT team configures your app, tests it, and rolls it out to users. Cost: $5K-$15K per site in support effort.

Total Cost Ranges

  • Single EHR (Epic or Oracle Health): $150K-$250K for initial development and certification
  • Both EHRs: $250K-$400K (shared abstraction layer reduces incremental cost)
  • Ongoing annual costs: $50K-$100K for marketplace fees, API monitoring, certification renewals, and maintenance

Security and HIPAA Compliance for Mobile

Mobile EHR integrations carry specific security requirements beyond standard web applications.

Required Security Measures

  • Certificate pinning — Pin your FHIR server's TLS certificate to prevent man-in-the-middle attacks. Both Epic and Oracle Health require this for production apps.
     
  • Secure token storage — Use iOS Keychain or Android Keystore for access and refresh tokens. Never store tokens in SharedPreferences, UserDefaults, or local databases.
     
  • Jailbreak/root detection — Detect compromised devices and restrict functionality. Both marketplaces check for this during review.
     
  • Data at rest encryption — Any cached FHIR data must be encrypted on the device. Use iOS Data Protection API or Android's EncryptedFile.
     
  • Audit logging — Log every FHIR API call with timestamp, resource type, and patient context. This is required for HIPAA compliance and EHR audit support.
     
  • Session timeout — Implement automatic session expiry. The recommended maximum is 15 minutes of inactivity for patient apps and 8 hours for provider apps.

Common Pitfalls and How to Avoid Them

After building multiple Epic and Oracle Health mobile integrations at Nirmitee, here are the issues that catch development teams off guard:

  1. Using WebView for authentication — Both Epic and Oracle Health reject apps that use embedded WebViews for OAuth. You must use the system browser (ASWebAuthenticationSession on iOS, Chrome Custom Tabs on Android). This is a SMART on FHIR requirement.
     
  2. Assuming consistent data quality — FHIR resources from different health systems vary wildly. One system might populate Patient.telecom with three phone numbers; another might leave it empty. 
     
  3. Ignoring offline scenarios — Mobile apps lose connectivity. Cache critical data locally and queue write operations for retry when connectivity returns.
     
  4. Skipping the SMART on FHIR test suite — Run the ONC Inferno tests against your implementation before submitting for review. Both marketplaces will run similar tests.
     
  5. Hard-coding FHIR server URLs — Each health system has a unique FHIR base URL. Your app must discover endpoints dynamically through the SMART configuration endpoint.

Ready to scale?

Talk to our healthcare engineering team about building, integrating, and shipping faster.

Frequently Asked Questions

How do mobile apps integrate with Epic and Oracle Health EHRs?

Mobile apps integrate with Epic and Oracle Health through the SMART on FHIR App Launch Framework, the industry-standard protocol for launching third-party apps within an EHR context, using FHIR R4 APIs for clinical data access. The stakes are high: more than 89% of US hospitals run Epic or Oracle Health, and per 2025 ONC data the two platforms manage clinical records for over 300 million Americans. Each platform has its own certification process, API flavor, and marketplace requirements.

What is SMART on FHIR with PKCE and why do mobile apps need it?

Mobile SMART on FHIR uses the Authorization Code Grant with PKCE (Proof Key for Code Exchange) because mobile apps cannot safely store client secrets like confidential web apps can. PKCE generates a one-time code verifier and challenge per authorization request. The flow runs: receive the launch context via deep link, discover endpoints from .well-known/smart-configuration, open a system browser (not a WebView) for authorization, authenticate the user, exchange the code for an access token, then call FHIR R4 endpoints.

Can third-party apps write data back to Epic through MyChart?

No, in most configurations MyChart does not support write operations for third-party patient apps: you can read data but cannot create orders, update problems, or write notes back. Epic restricts write access to apps that pass a deeper integration review. Patient apps can read demographics, lab results and vitals, active medications, allergies, the problem list, clinical documents, and immunization records through patient-scoped FHIR R4 APIs.

What is the Epic app review process?

Apps register through Epic on FHIR, and each customer must enable them. The usual path has five stages: registration with your use case and required FHIR resources, sandbox testing against synthetic patient data, a security review of your authentication, data handling, and HIPAA compliance, a clinical review for apps that influence clinical decisions, and finally production approval with a production client ID.

What is the difference between patient-facing and provider-facing Epic apps?

Patient-facing apps integrate through MyChart with patient-scoped read access to the individual's own record, while provider-facing apps launch inside Epic Hyperspace and receive richer context: the current patient, encounter, and logged-in practitioner identity, with user-level scopes covering any patient the provider can access. Building for both paths requires separate scopes and reviews; healthcare engineering teams like Nirmitee.io handle these dual Epic and Oracle Health integrations in production mobile apps.

How does Nirmitee.io approach healthcare software development?

Nirmitee.io follows a healthcare-first engineering approach — every solution is built with HIPAA compliance, HL7/FHIR interoperability standards, and clinical workflow requirements at the core. We combine domain expertise with modern engineering practices to deliver production-ready systems.
Share