Skip to main content

EHR Launch (SMART on FHIR)

  • OAuth 2.0 enables you to develop your application without having to build a credential management system.
  • Instead of exposing login credentials to your application, your application and an EHR's authorization server exchange a series of authorization codes and access tokens.
  • Your application can access protected patient data stored in an EHR's database after it obtains authorization from the EHR's authorization server.

Let's Start

To use OAuth 2.0 to authorize your application's access to patient information, some information needs to be shared between the authorization server and your application:

client_id: The client_id identifies your application to authentication servers within the Epic community and allows you to connect to any organization.

redirect_uri: The redirect_uri confirms your identity and is used to validate and redirect authentication requests that originate from your application. Epic's implementation allows for multiple redirect_uris.

Note:The redirect_uri is not needed for backend services using the client_credentials grant type.

Credentials: Some apps, sometimes referred to as confidential clients, can use credentials registered for a given EHR system to obtain authorization to access the system without a user or a patient implicitly or explicitly authorizing the app.

  • Examples of this are apps that use refresh tokens to allow users to launch the app outside of an Epic client without needing to log in every time they use the app.
  • Backend services that need to access resources without a specific person launching the app, for example, fetching data on a scheduled basis.
  • You can register your application for access to both the sandbox and Epic organizations here.
  • You'll provide information to us, including one or more redirect_uris, and Epic will generate a client_id for you.
  • Apps can be launched from within an existing EHR or patient portal session, which is called an EHR launch.
  • Alternatively, apps can be launched standalone from outside of an existing EHR session.
  • Apps can also be backend services where no user is launching the app.

EHR launch (SMART on FHIR)

  • The app is launched by the EHR calling a launch URL specified in the EHR's configuration.
  • The EHR launches the launch URL and appends a launch token and the FHIR server's endpoint URL (ISS parameter) in the query string.
  • The app exchanges the launch token, along with the client identification parameters to get an authorization code and eventually the access token.
  • The app you build will list both a production Client ID and a non-production Client ID. While testing in the Epic on FHIR sandbox, use the non-production Client ID.

The base URL for the Current Sandbox environment is:

https://fhir.epic.com/interconnect-fhir-oauth/

How It Works

Step 1: Your Application is Launched from the Patient Portal or EHR

  • Your app is launched by the EHR calling the launch URL which is specified in the EHR's configuration. The EHR sends a launch token and the FHIR server's endpoint URL (ISS parameter).
  • launch: This parameter is an EHR generated token that signifies that an active EHR session already exists. This token is one-time use and will be exchanged for the authorization code.
  • iss: This parameter contains the EHR's FHIR endpoint URL, which an app can use to find the EHR's authorization server.

Step 2: Your Application Retrieves the Conformance Statement or SMART Configuration

  • To determine which authorize and token endpoints to use in the EHR launch flow, you should make a GET request to the metadata endpoint which is constructed by taking the iss provided and appending /metadata.
  • Alternatively, when communicating with Epic organizations using the August 2021 version or Epic or later, you can make a GET request to the SMART configuration endpoint by taking the iss and appending /.well-known/smart-configuration.
  • If no Accept header is sent, the metadata response is XML-formatted and the smart-configuration response is JSON-formatted.
  • An Accept header can be sent with a value of application/json, application/xml, and the metadata endpoint additionally supports application/fhir+json and application/json+fhir to specify the format of the response.

Metadata Example

Here is an example of what the authorize and token endpoints would look like in the metadata response.

"extension": [
{
"url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris",
"extension": [
{
"url": "authorize",
"valueUri": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/authorize"
},
{
"url": "token",
"valueUri": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token"
}
]
}
];

Metadata Example with Dynamic Client Registration

Full metadata request

Epic Client ID, clients authorized to perform dynamic client registration can then determine which endpoint to use when performing dynamic client registration. Note that this capability is only supported for STU3 and R4 requests.

Authorize, token, and dynamic registration endpoints in the metadata response.

"extension": [
{
"url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris",
"extension": [
{
"url": "authorize",
"valueUri": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/authorize"
},
{
"url": "token",
"valueUri": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token"
},
{
"url": "register",
"valueUri": https://fhir.epic.com/interconnect-fhir-oauth/oauth2/register
}
]
}
]

Here's an example of what a smart-configuration request might look like.

Authorize and token endpoints in the smart-configuration response.

"authorization_endpoint": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/authorize",
"token_endpoint": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token",
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic",
"private_key_jwt"
]

Step 3: Your Application Requests an Authorization Code

  • Our application now has a launch token obtained from the initial EHR launch as well as the authorize endpoint obtained from the metadata query.
  • To exchange the launch token for an authorization code, your app needs to either make an HTTP GET or POST request to the authorize endpoint that contains the parameters below.
  • POST requests are supported for EHR launches in Epic version November 2020 and later, and are not currently supported for standalone launches.

The request should contain the following parameters.

response_type: This parameter must contain the value "code".

client_id: This parameter contains your web application's client ID issued by Epic.

redirect_uri: This parameter contains your application's redirect URI. After the request completes on the Epic server, this URI will be called as a callback. The value of this parameter needs to be URL encoded.

scope: This parameter describes the information for which the web application is requesting access.

launch: This parameter is required for EHR launch workflows. The value to use will be passed from the EHR.

aud: The value to use is the FHIR base URL of the resource server the application intends to access, which is typically the FHIR server returned by the iss.

state: This optional parameter is generated by your app and is opaque to the EHR. The EHR's authorization server will append it to each subsequent exchange in the workflow for you to validate session integrity.

Step 4: EHR's Authorization Server Reviews the Request

  • The EHR's authorization server reviews the request from your application.

  • If approved, the authorization server redirects the browser to the redirect URL supplied in the initial request and appends the following querystring parameter.

code: This parameter contains the authorization code generated by Epic, which will be exchanged for the access token in the next step.

state: This parameter will have the same value as the earlier state parameter.

Step 5: Your Application Exchanges the Authorization Code for an Access Token

After receiving the authorization code, your application trades the code for a JSON object containing an access token and contextual information by sending an HTTP POST to the token endpoint Access Token Request: If You Are Not Using a Client Secret

The following parameters are required in the POST body:

grant_type: For the EHR launch flow, this should contain the value "authorization_code".

code: This parameter contains the authorization code sent from Epic's authorization server to your application as a querystring parameter on the redirect URI as described above.

redirect_uri: This parameter must contain the same redirect URI that you provided in the initial access request. The value of this parameter needs to be URL encoded.

client_id: This parameter must contain the application's client ID issued by Epic that you provided in the initial request.

code_verifier: This optional parameter is used to verify against your code_challenge parameter when using PKCE.

The authorization server responds to the HTTP POST request with a JSON object that includes an access token. The response contains the following fields:

access_token: This parameter contains the access token issued by Epic to your application and is used in future requests.

token_type: In Epic's OAuth 2.0 implementation, this parameter always includes the value bearer.

expires_in: This parameter contains the number of seconds for which the access token is valid.

scope: This parameter describes the access your application is authorized for.

id_token: Returned only for applications that have requested an openid scope.

patient: This parameter identifies provides the FHIR ID for the patient, if a patient is in context at time of launch.

epic.dstu2.patient: This parameter identifies the DSTU2 FHIR ID for the patient, if a patient is in context at time of launch.

encounter: This parameter identifies the FHIR ID for the patient’s encounter, if in context at time of launch. The encounter token corresponds to the FHIR Encounter resource.

location : This parameter identifies the FHIR ID for the encounter department, if in context at time of launch. The location token corresponds to the FHIR Location resource.

appointment: This parameter identifies the FHIR ID for the patient’s appointment, if appointment context is available at time of launch. The appointment token corresponds to the FHIR Appointment resource.

loginDepartment: This parameter identifies the FHIR ID of the user's login department for launches from Hyperspace. The loginDepartment token corresponds to the FHIR Location resource.

state: This parameter will have the same value as the earlier state parameter.

Step 6: Your Application Uses FHIR APIs to Access Patient Data

Nxfve4q3H9TKs5F5vf6kRYAZqzK7j9LHvrg1Bw7fU_07_FdV9aRzLCI1GxOn20LuO2Ahl5RkRnz-p8u1MeYWqA85T8s4Ce3LcgQqIwsTkI7wezBsMduPw_xkVtLzLU2O

Step 7: Use a Refresh Token to Obtain a New Access Token

Refresh tokens are not typically needed for embedded (SMART on FHIR) launches because users are not required to log in to Epic during the SMART on FHIR launch process, and the access token obtained from the launch process is typically valid for longer than the user needs to use the app.