Home Services FHIR Platform About Blog Get in Touch
EHR Integration

Smart on FHIR App Launch: From Sandbox to Epic Production

Akhester Engineering April 2025 6 min read

What is SMART App Launch?

SMART on FHIR defines a standard way for applications to launch from inside an EHR, obtain an OAuth 2.0 access token scoped to the current patient and encounter, and then call the EHR's FHIR API on the patient's behalf.

The core flow: EHR calls your /launch endpoint with a launch token → your app discovers the EHR's auth server → PKCE authorization code exchange → access token with patient/encounter context.

Implementing the Launch Endpoint

Your GET /launch controller receives two query parameters from the EHR: iss (the FHIR server base URL) and launch (an opaque context token).

@GetMapping("/launch")
public RedirectView launch(@RequestParam String iss,
                           @RequestParam String launch) {
    SmartConfig cfg = discoveryService.discover(iss);
    String verifier = pkce.generateVerifier();   // 96 bytes, base64url
    String challenge = pkce.challenge(verifier); // SHA-256
    String state = stateStore.save(verifier, iss);

    return new RedirectView(cfg.authorizationEndpoint()
        + "?response_type=code"
        + "&client_id=" + clientId
        + "&redirect_uri=" + redirectUri
        + "&scope=launch+openid+fhirUser+patient/*.read"
        + "&launch=" + launch
        + "&aud=" + iss
        + "&state=" + state
        + "&code_challenge=" + challenge
        + "&code_challenge_method=S256");
}

Discovery

Before redirecting, your app must fetch the EHR's SMART configuration from {iss}/.well-known/smart-configuration. This returns the authorization and token endpoints, supported scopes, and PKCE requirements.

Token Exchange

After the user authorises, the EHR redirects back to your /callback with a code. Exchange it for tokens:

POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code={code}
&redirect_uri={redirect_uri}
&client_id={client_id}
&code_verifier={verifier}

The token response includes access_token, patient, encounter, and need_patient_banner at the top level.

Epic-Specific Requirements

Going to Production

Epic's App Orchard review checks that your app handles token expiry, uses HTTPS everywhere, stores tokens securely (not in localStorage), and implements a proper logout. Budget 4–8 weeks for the review cycle and test thoroughly on the Epic sandbox first.


Have questions about implementing this in your healthcare platform? Get in touch with the Akhester team.