
Epic
Epic Systems Corporation
Epic
Complete OAuth 2.0 and FHIR R4/STU3 integration adapter for Epic EHR systems. Supports patient-facing, system-to-system, and embedded EHR launch workflows with full FHIR resource operations and bulk data export.
Overview
ConnectHealth's Epic integration gives your application secure access to patient data and clinical workflows through Epic's OAuth 2.0 and FHIR R4 APIs. ConnectHealth acts as the middleware layer — handling authentication, SMART endpoint discovery, token lifecycle, and FHIR communication — so your team can focus on building features rather than managing Epic-specific OAuth flows.
You (your organization) must create and own Epic applications. ConnectHealth is middleware — it does NOT create apps, manage fhir.epic.com Developer Portal accounts, or submit applications on your behalf, so you must have an approved Epic application with a Client ID before configuring any workflow in ConnectHealth.
On This Page
Supported Authentication Flows
Click a card to jump to its configuration section.
Standalone OAuth
Standard OAuth 2.0 authorization code flow where users authorize access to their data via Epic MyChart. Best for patient portals, health tracking apps, and third-party apps needing patient consent.
Backend to Backend (B2B)
JWT Bearer assertion flow for server-to-server authentication without any user interaction. Epic requires JWT — no Basic Auth option. Best for automated data sync, population health analytics, and background processing.
Embed Launch
SMART on FHIR launch flow for applications embedded within Epic's interface. Epic supports both Patient-facing (MyChart embedded) and Provider-facing (Hyperspace embedded) SMART apps. The app is launched from within the EHR and receives context automatically. Best for clinical decision support and in-context clinical tools.
Key Features
- FHIR resource CRUD operations
- Bulk data export
- SMART endpoint auto-discovery (auth/token URLs derived from the FHIR base URL)
- JWT Bearer assertion for B2B (RSA key pair managed by ConnectHealth)
- Token refresh
- Embed Launch with automatic patient and encounter context
- Audit logging for all operations
Before You Begin
Before you can use Epic with ConnectHealth, you must set up an application in fhir.epic.com Developer Portal. This section outlines the prerequisites and gives you a step-by-step guide to get started.
Prerequisites Checklist
- fhir.epic.com developer account — Create an account at fhir.epic.com under your organization's email domain
- Approved Epic application — Created in fhir.epic.com Developer Portal with a Client ID
- Redirect URI registered — Your ConnectHealth callback URL registered in fhir.epic.com Developer Portal (for Standalone and Embed Launch)
- For B2B: JWKS URI registered — Copy the JWKS URI from ConnectHealth and paste it into your fhir.epic.com application (Epic verifies JWT assertions using this public key endpoint)
- For production — A separate production fhir.epic.com submission reviewed by Epic, plus your organization's Epic admin must activate the app on their instance
Create Your Epic Application
Follow these steps to create your Epic application in fhir.epic.com Developer Portal. Your organization owns and manages this app — fhir.epic.com Developer Portal is where you'll manage credentials and configuration.
Create an Epic Developer Account
If you don't already have one, create a developer account at fhir.epic.com.
- Sign up using your organization's email domain (e.g., someone@your-company.com)
- Your organization will own this account and all apps created under it
- Keep your login credentials secure
Create a New Application in fhir.epic.com Developer Portal
In fhir.epic.com Developer Portal, create a new application and choose the app type that matches your workflow:
- Click Create App in your fhir.epic.com dashboard
- Choose your application type:
- For Standalone (patient-facing): Select Patient-Facing App or Clinician-Facing App (3-legged OAuth)
- For Backend (B2B): Select Backend System App (client_credentials with JWT assertion — no Basic Auth option)
- For Embed Launch (in-EHR): Select EHR App (SMART on FHIR)
- Enter an app name and description (e.g., "ConnectHealth Integration - Sandbox")
- Complete the required fields and click Submit
Retrieve Your Client ID and Configure Credentials
After creating your app, copy your Client ID and configure the required credential fields:
- Open your app in fhir.epic.com Developer Portal and copy the Client ID (a UUID format string — Epic does not issue a Client Secret for B2B apps)
- For Standalone and Embed Launch: Register the Redirect URI (OAuth callback URL) from ConnectHealth:
https://your-connecthealth-domain/api/workflow/auth/{integrationId}/callback
You will get the exact {integrationId} from ConnectHealth after creating your connection - For Embed Launch: Also register the Launch URL:
https://your-connecthealth-domain/api/workflow/auth/{integrationId}/launch - For B2B (Backend): Copy the JWKS URI from your ConnectHealth connection settings and paste it into your app's JWKS URI field in fhir.epic.com Developer Portal. This is how Epic verifies your JWT assertions without sharing private keys
- Click Save
Submit for Sandbox Approval
Applications created on fhir.epic.com for sandbox testing are generally available immediately in the public sandbox. However, testing in a hospital's specific environment requires additional steps:
- Your public sandbox app is typically auto-approved for use against fhir.epic.com endpoints
- Moving the app into a specific hospital's non-production or production environment requires their Epic TS (Technical Server) administrator to explicitly approve and install your app's Client ID via their Connection Hub
- Once the Client ID is active, you can begin using it in ConnectHealth
Configure in ConnectHealth
Now you're ready to configure your Epic connection in ConnectHealth:
- In ConnectHealth, navigate to Connections and create a new connection
- Select Epic as the EHR type
- Select your workflow type:
- Standalone for patient-facing applications
- Backend for server-to-server automation
- Embed Launch for in-EHR applications
- Paste your Client ID from fhir.epic.com Developer Portal
- Fill in the FHIR Base URL (ConnectHealth auto-discovers auth and token endpoints from it)
- For B2B: ConnectHealth auto-generates an RSA key pair — copy the JWKS URI shown in your connection settings and register it in fhir.epic.com Developer Portal (if not done already in Step 3)
- Save your connection
Test with Sandbox Data
Test your integration using Epic's sandbox (see Sandbox Environment Setup below for test data and URLs).
- For Standalone: Initiate OAuth and log in using the Epic MyChart sandbox credentials (
fhircamila/epicepic1) - For Backend: Request a system token and test FHIR calls against the sandbox FHIR base URL
- Verify that data flows correctly between Epic and ConnectHealth
Production App (When Ready)
Epic production access has two distinct gates — both must be cleared:
- Submit a separate production app to the fhir.epic.com Developer Portal for review by Epic.
- Your customer's Epic admin must independently activate your app on their Epic instance — this is separate from the fhir.epic.com approval.
The production URL is not global — each Epic customer has their own instance URL (e.g., https://epicmobile.yourhospital.org/fhir/r4), which you must obtain from the Epic admin at your customer's organization. Do not attempt to go live until both gates are cleared, as using sandbox credentials or unapproved apps against production will fail.
Note: When migrating, you will first connect to your hospital's non-production environment (often called TST, POC, SUP, or PLY) before receiving final approval for PRD (Production).
When you're ready to go to production:
- Create a new production application in fhir.epic.com Developer Portal targeting the Production environment
- Configure it with the same settings as your sandbox app (Redirect URI, JWKS URI, scopes, etc.)
- Submit for Epic's production review (this may take days to weeks)
- Coordinate with your customer's Epic administrator to activate your app on their Epic instance
- Once both approvals are in place, create a new production connection in ConnectHealth using your production Client ID and the customer's Epic FHIR base URL
- See the Epic FHIR Documentation for detailed production submission guidance
Sandbox Environment Setup
Epic provides a public sandbox environment at fhir.epic.com for integration testing. You will need your own approved sandbox application from fhir.epic.com Developer Portal to obtain a Client ID. Epic also provides shared test patient data for quick functional testing — listed below.
Shared Test Data (Epic Sandbox)
Use the following shared test patient data for validating your integration. Note: You still need your own approved fhir.epic.com application's Client ID — these are test patient records, not a shared application credential.
Epic Sandbox Endpoints
| Purpose | URL |
|---|---|
| FHIR Base (R4) | https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4 |
| OAuth Authorization | https://fhir.epic.com/interconnect-fhir-oauth/oauth2/authorize |
| OAuth Token | https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token |
| SMART Configuration | https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/.well-known/smart-configuration |
ConnectHealth auto-discovers the Authorization and Token URLs from the SMART Configuration endpoint — in most cases you only need to enter the FHIR Base URL when configuring your connection.
Test Patient Data
- Camila Lopez:
erXuFYUfucBZaryVksYEcMg3 - Derrick Lin:
eq081-VQEgP8drUUqCWzHfw3 - FHIR Test Patient (generic):
eAB3mDIBBcyUKiWo - MyChart test login: Username
fhircamila/ Passwordepicepic1 - Group ID (bulk export): Create a Group in your fhir.epic.com public sandbox that includes test patients, then use that Group ID in the bulk export kick-off
For the full list of test patients, see the Epic Sandbox Test Patients documentation.
Sandbox vs Production Comparison
Understand the key differences between sandbox and production Epic environments:
| Aspect | Sandbox | Production |
|---|---|---|
| FHIR Base URL | fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4 |
Customer's own Epic instance (e.g., epicmobile.yourhospital.org/fhir/r4) |
| App Approval | fhir.epic.com public sandbox review (hours to a day) | fhir.epic.com Developer Portal review + customer's Epic admin must separately activate the app |
| Data | Synthetic test patients only | Real patient data (HIPAA-covered) |
| Credentials | Sandbox Client ID from fhir.epic.com Developer Portal | Separate production Client ID from production fhir.epic.com submission |
| Approval Timeline | Hours to 1 day | Days to weeks (Epic review + org IT activation) |
| FHIR Base URL format | Single global sandbox URL | Unique per customer — obtain from your customer's Epic admin |
Important: Unlike Athena, Epic does not have a global production URL. Every Epic customer runs their own hosted Epic instance. You must obtain the production FHIR base URL directly from the Epic administrator at your customer's organization — there is no single "Epic production URL" you can use across all customers.
Configuration Reference
Complete Steps 1–4 above (create and get your fhir.epic.com application approved) before filling in these fields. You will need your Client ID and an approved Epic application to proceed.
ConnectHealth supports multiple workflow types for this integration. Choose the one that matches your use case.
Standalone OAuth
Standard OAuth 2.0 authorization code flow where users authorize access to their data via Epic MyChart. Best for patient portals, health tracking apps, and third-party apps needing patient consent.
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Your unique application identifier from fhir.epic.com Developer Portal (UUID format). |
Client Secret |
No | No | Required only for confidential clients. Most Epic patient-facing apps are public clients and do not use a Client Secret. |
Authorization URL |
Yes | Yes | Epic's OAuth authorization endpoint. Auto-discovered from the FHIR base URL's SMART configuration if not provided. |
Token URL |
Yes | Yes | Epic's OAuth token endpoint. Auto-discovered from the FHIR base URL's SMART configuration if not provided. |
Scopes |
No | Yes | Space-separated list of OAuth scopes defining the level of access requested. |
Redirect URL |
Yes | Yes | Your ConnectHealth OAuth callback URL. Must match the redirect URI registered in fhir.epic.com Developer Portal. |
FHIR Base URL |
No | Yes | The base URL of the Epic FHIR server. ConnectHealth auto-discovers auth/token endpoints from this URL. |
Setup Steps
- Register your application in fhir.epic.com Developer Portal as a patient-facing or clinician-facing app and note the Client ID.
- Register the redirect URI (ConnectHealth callback URL) in fhir.epic.com Developer Portal.
- Determine the scopes your application needs (e.g.,
patient/*.read openid fhirUser). - Enter the FHIR base URL — ConnectHealth will auto-discover the authorization and token endpoints.
- Configure the Standalone workflow in ConnectHealth with all the fields above.
- Test the authorization flow by initiating a login — the user should be redirected to Epic MyChart to authorize.
Backend to Backend (B2B)
JWT Bearer assertion flow for server-to-server authentication without any user interaction. Epic requires JWT assertion for all B2B apps — Basic Auth (Client Secret) is not supported. ConnectHealth automatically generates and manages the RSA key pair for you. Best for automated data sync, population health analytics, and background processing.
Epic does not issue a Client Secret for backend/system applications. Authentication is done exclusively via JWT Bearer assertion. ConnectHealth generates an RSA key pair — you register the public key (JWKS URI) in fhir.epic.com Developer Portal, and ConnectHealth signs JWT assertions using the private key.
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Your unique application identifier from fhir.epic.com Developer Portal (UUID format). |
Private Key |
Yes | Yes | PEM-encoded RSA private key used to sign JWT assertions. Automatically generated and managed by ConnectHealth — copy the corresponding JWKS URI and register it in fhir.epic.com Developer Portal. |
Token URL |
Yes | Yes | Epic's OAuth token endpoint. Auto-discovered from the FHIR base URL's SMART configuration if not provided. |
FHIR Base URL |
No | Yes | The base URL of the Epic FHIR server. Used for SMART endpoint discovery and FHIR requests. |
Scopes |
No | Yes | Space-separated list of system-level OAuth scopes (e.g., system/*.read). |
Setup Steps
- Register your application in fhir.epic.com Developer Portal as a Backend System application.
- In ConnectHealth, create the Backend connection — ConnectHealth will auto-generate an RSA key pair (RS384).
- Copy the JWKS URI from your ConnectHealth connection settings and register it in your fhir.epic.com application's JWKS URI field.
- Enter your FHIR base URL — ConnectHealth auto-discovers the token endpoint.
- Test by requesting a backend token — no user interaction should be required.
SMART on FHIR - Embed Launch
SMART on FHIR launch flow for applications embedded within Epic's EHR interface. The app is launched from within Epic and receives patient and encounter context automatically. ConnectHealth auto-discovers Epic's SMART endpoints from the iss parameter on launch. Best for clinical decision support, order entry helpers, and in-context clinical tools.
| Field | Autofill | Required | Description |
|---|---|---|---|
Client ID |
No | Yes | Your unique application identifier from fhir.epic.com Developer Portal. |
Client Secret |
No | No | Required only for confidential clients. Public Epic SMART apps do not use a Client Secret. |
Setup Steps
- Register your application in fhir.epic.com Developer Portal as a SMART on FHIR EHR Launch application.
- Set the Launch URL in fhir.epic.com Developer Portal to your ConnectHealth launch endpoint:
https://your-connecthealth-domain/api/workflow/auth/{integrationId}/launch - Register the Redirect URI in fhir.epic.com Developer Portal:
https://your-connecthealth-domain/api/workflow/auth/{integrationId}/callback - Configure the Embed Launch workflow in ConnectHealth with the Client ID (and Client Secret if confidential).
- Your app needs to handle the
tokenIdreturned by ConnectHealth and call the token exchange endpoint to retrieve the access token. - Test by launching your app from within the Epic EHR sandbox environment.
How to Handle SMART Launch
Once your Embed Launch app is configured, here's the end-to-end flow — from Epic initiating the launch, to your app receiving a usable FHIR access token. Each step is tied to the exact ConnectHealth endpoint involved.
Epic Initiates the Launch
When a clinician opens your app from within Epic, Epic calls your registered Launch URL:
GET https://<your-ch-domain>/api/workflow/auth/{integrationId}/launch?iss=...&launch=...
iss— Epic's FHIR base URL for that customer's Epic instance (e.g.,https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4in sandbox)launch— an opaque token carrying patient and encounter context
ConnectHealth auto-discovers Epic's SMART endpoints (auth URL, token URL) from the iss parameter — you don't need to hardcode these. No action needed from you — this is the URL you registered in fhir.epic.com Developer Portal.
ConnectHealth Completes OAuth and Returns a tokenId
ConnectHealth exchanges the launch token with Epic server-side, stores the resulting access token securely on the backend, and redirects back to your embedded app with a short-lived tokenId (a UUID) appended to the URL. The tokenId is one-time use — it's consumed on read and cannot be replayed.
Call Token Exchange to Retrieve the Access Token
Your app must call the Token Exchange endpoint with the tokenId. This endpoint requires the x-api-key header — without it, you will get a 401:
GET https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/exchange/{tokenId}
Headers:
x-api-key: <your-connecthealth-api-key>
Accept: application/json
Response contains access_token, patient, encounter (if available), scope, expires_in, and — if offline_access was requested — a refresh_token.
Jump to Get Your ConnectHealth API Key to create one from the Settings tab before calling Token Exchange.
Call FHIR Using the Access Token
Use the access_token as a Bearer token against Epic's FHIR base URL. In sandbox, use the Epic sandbox URL; in production, use the customer's Epic instance URL:
- Sandbox:
https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4 - Production:
https://epicmobile.yourhospital.org/fhir/r4(customer-specific — obtain from their Epic admin)
GET {fhirBaseUrl}/Patient/{patient}
Headers:
Authorization: Bearer {access_token}
Accept: application/fhir+json
Refresh Before Expiry
Access tokens expire (typically in minutes). Before the token expires, call the Token Refresh endpoint to obtain a new one without re-prompting the user. Like Token Exchange, this requires x-api-key:
POST https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/refresh
Headers:
x-api-key: <your-connecthealth-api-key>
Content-Type: application/json
Body:
{
"refresh_token": "<your-refresh-token>"
}
Refresh only works if offline_access was included in your requested scopes.
General Scopes
Scopes define the level of access your application requests. Choose the appropriate scopes based on your workflow type and data needs.
User Scopes
User-level scopes grant access based on the permissions of the logged-in clinician or user.
| Scope | Description |
|---|---|
user/*.read |
Read all resource types the user has access to |
user/Patient.read |
Read patient demographics the user can access |
user/Encounter.read |
Read encounter records the user can access |
System Scopes
System-level scopes grant access for backend/server applications without a specific user context. Used with the Backend to Backend (B2B) workflow.
| Scope | Description |
|---|---|
system/*.read |
Read all resource types at the system level |
system/Patient.read |
Read all patient demographics |
system/Group.read |
Read patient groups (required for bulk data export) |
Launch Scopes
Launch scopes are used with SMART on FHIR to receive context from the EHR launch.
| Scope | Description |
|---|---|
launch |
Required for EHR launch — receives the launch context from Epic |
launch/patient |
Request patient context in a standalone or patient-facing EHR launch (MyChart) |
launch/encounter |
Request encounter context in a standalone or provider-facing EHR launch (Hyperspace) |
Identity Scopes
OpenID Connect scopes for obtaining user identity information.
| Scope | Description |
|---|---|
openid |
Required for OpenID Connect — returns an ID token |
fhirUser |
Returns the FHIR resource URL of the authenticated user |
offline_access |
Request a refresh token for long-lived access |
Use Cases
Choose the workflow type that best matches your application's needs.
Patient-Facing Applications
Scenario: A third-party app needs to access patient health data with the patient's explicit consent.
Recommended Workflow: Standalone OAuth
Best For: Patient portals, health tracking apps, care management tools
Recommended Scopes: patient/*.read openid fhirUser launch/patient offline_access
System-to-System Integration
Scenario: A server needs to access Epic data without any user interaction for automated processing.
Recommended Workflow: Backend to Backend (B2B)
Best For: Nightly data sync, population health analytics, automated reporting
Recommended Scopes: system/*.read
EHR-Embedded Applications
Scenario: An application launched from within Epic's clinical workflow that receives patient and encounter context automatically.
Recommended Workflow: Embed Launch (SMART on FHIR)
Best For: Clinical decision support, order entry helpers, documentation assistants
Recommended Scopes: launch openid fhirUser patient/*.read launch/encounter
Bulk Data Export
Scenario: Extracting large datasets from Epic for analytics, research, or population health.
Recommended Workflow: Backend to Backend (B2B)
Best For: Population health reports, research datasets, quality measure reporting
Recommended Scopes: system/*.read system/Group.read
Workflow Automation
Scenario: Low-code Node-RED workflows interacting with Epic for automated data pipelines within ConnectHealth.
Recommended Workflow: Backend to Backend (B2B)
Best For: Automated notifications, data transformation pipelines, integration workflows
Recommended Scopes: system/*.read
Get Your ConnectHealth API Key
Several ConnectHealth endpoints — Token Exchange, Backend Token, and Token Refresh — require a ConnectHealth API key passed as the x-api-key header. Without this header, these endpoints return 401 Unauthorized. Follow these steps to create your API key.
Log in to the ConnectHealth Dashboard
Open your ConnectHealth instance (the URL where your deployment is hosted) and sign in with your account credentials.
Navigate to Settings → API Keys
From the left navigation, click Settings, then open the API Keys tab. If you have never generated a key before, the list will be empty.
Create a New API Key
Click Create API Key, enter a descriptive name (e.g., epic-prod-client or embed-launch-dev), and submit. Use one key per environment or per client application so you can rotate individual keys without affecting others.
Copy Your API Key
ConnectHealth automatically saves your API key securely. You can view and copy the key value from Settings → API Keys at any time. Click your key name to reveal and copy it whenever you need it.
Use the Key in the x-api-key Header
Pass the key on every request to a protected endpoint using the header name x-api-key (lowercase, hyphenated). Example:
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/exchange/{tokenId}" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"
Endpoints requiring this header are listed in the API Endpoints section below.
API Endpoints
These are the ConnectHealth endpoints your application will interact with. All paths are prefixed with /api/workflow/auth/{integrationId}, where {integrationId} is the connection ID you created in ConnectHealth.
Token Exchange, Backend Token, and Token Refresh all require the x-api-key header. Create a key from Settings → API Keys before calling these endpoints.
Authentication Endpoints
| Method | Endpoint | Description | API Key |
|---|---|---|---|
GET |
/api/workflow/auth/{integrationId}/start |
Initiate OAuth flow for standalone launch. Typically hit from a browser; returns a redirect to Epic MyChart. | No |
GET |
/api/workflow/auth/{integrationId}/callback |
OAuth redirect URI. Called by Epic after user authorization — not by your client. Exchanges the code for tokens and stores them, returning a one-time tokenId. |
No |
GET |
/api/workflow/auth/{integrationId}/launch |
SMART on FHIR EHR Launch URL. Called by Epic with iss and launch query params — not by your client. ConnectHealth auto-discovers SMART endpoints from iss. |
No |
GET |
/api/workflow/auth/{integrationId}/token/exchange/{tokenId} |
Exchange a one-time tokenId for the actual access token and patient/encounter context. The tokenId is consumed on read. |
Yes |
GET |
/api/workflow/auth/{integrationId}/token |
Request a Backend (B2B) system token using JWT Bearer assertion. No user interaction. | Yes |
POST |
/api/workflow/auth/{integrationId}/token/refresh |
Refresh an expiring access token. Requires a previously issued refresh token (requested via offline_access scope). |
Yes |
GET |
/api/workflow/auth/{integrationId}/token/status/{tokenId} |
Check whether a tokenId is still valid and ready to exchange. Does not consume the token. |
No |
GET |
/api/workflow/auth/{integrationId}/introspect |
Optional diagnostic endpoint that inspects the currently stored token for the integration. | No |
GET |
/api/workflow/auth/{integrationId}/health |
Optional liveness check for the integration's auth pipeline. | No |
Examples
Copy-paste examples for the client-callable endpoints. Replace <your-ch-domain>, {integrationId}, {tokenId}, and YOUR_API_KEY with your actual values.
Token Exchange
Exchange a one-time tokenId for an access token + patient/encounter context after Standalone or Embed Launch flows.
curl
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/exchange/{tokenId}" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token/exchange/${tokenId}`,
{
headers: {
"x-api-key": process.env.CH_API_KEY,
"Accept": "application/json",
},
}
);
const { access_token, patient, encounter, scope, expires_in } = await res.json();
Backend Token (B2B)
Request a system-level access token for server-to-server flows using JWT Bearer assertion.
curl
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token`,
{
headers: {
"x-api-key": process.env.CH_API_KEY,
"Accept": "application/json",
},
}
);
const { access_token, expires_in, scope } = await res.json();
Token Refresh
Refresh an access token before expiry. Only works if the original token was issued with offline_access.
curl
curl -X POST "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/refresh" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token/refresh`,
{
method: "POST",
headers: {
"x-api-key": process.env.CH_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ refresh_token: "YOUR_REFRESH_TOKEN" }),
}
);
const { access_token, refresh_token, expires_in } = await res.json();
Response
{
"body": {
"access_token": "eyJhbGc...",
"refresh_token": "dGhpcyBp...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "patient/*.read",
"patient": "patient-id-if-applicable"
},
"message": "Token refreshed successfully",
"timestamp": 1718000000000
}
Token Status
Check if a one-time tokenId is still valid and ready to exchange. Non-consuming.
curl
curl -X GET "https://<your-ch-domain>/api/workflow/auth/{integrationId}/token/status/{tokenId}" \
-H "Accept: application/json"
JavaScript (fetch)
const res = await fetch(
`https://<your-ch-domain>/api/workflow/auth/${integrationId}/token/status/${tokenId}`,
{ headers: { "Accept": "application/json" } }
);
const { valid, expiresAt } = await res.json();
OAuth Start (browser-initiated)
Begin the Standalone OAuth flow. Typically opened in a browser so the user can authorize with Epic MyChart.
curl (inspect redirect only)
curl -I "https://<your-ch-domain>/api/workflow/auth/{integrationId}/start"
Example Launch URL (registered in fhir.epic.com Developer Portal):
https://demo.ehrconnect.healthconnect.systems/api/workflow/auth/[your-integration-id]/launch
Replace the domain and integration ID with your actual values.
External Resources
- fhir.epic.com Developer Portal — Create and manage your Epic applications
- Epic FHIR Documentation — Comprehensive FHIR R4 API reference
- Epic Sandbox Test Patients — Full list of sandbox test patient IDs and MyChart credentials
- SMART App Launch Guide
- FHIR R4 Specification