Epic FHIR Documentation: How To Find APIs And OAuth Guides

Epic FHIR Documentation: How To Find APIs And OAuth Guides

Getting your hands on the right Epic FHIR documentation can feel like navigating a maze. Epic's developer ecosystem is massive, and the resources you need, API references, OAuth setup guides, sandbox credentials, are scattered across multiple portals, each with its own registration requirements and access tiers. If you've spent more time searching for documentation than actually building, you're not alone.

At VectorCare, we've built our patient logistics platform to integrate directly with EHR systems like Epic, connecting transportation, home care, and DME workflows to the clinical data that drives them. That work has given us deep, hands-on experience with Epic's FHIR APIs and OAuth flows, and a clear understanding of where developers get stuck during implementation.

This guide walks you through exactly where to find Epic's FHIR resources, how to register for developer access, and what you need to know about OAuth 2.0 authorization before writing a single line of code. Whether you're building a standalone app or connecting an existing platform to Epic, you'll leave with a concrete path from documentation to working integration.

What you need before you start

Before you open a single page of Epic FHIR documentation, you need to gather a few things. Jumping straight into API specs without the right accounts, organizational context, and technical prerequisites will slow you down considerably. This section covers exactly what to have ready before you invest time reading through OAuth guides or standing up a sandbox environment.

Developer account and portal access

Epic's developer resources live primarily at open.epic.com, the company's public-facing developer portal. You need to create a free account on open.epic.com to access sandbox environments, API documentation, and the app registration workflow. Creating an account takes less than five minutes: go to open.epic.com, click "Sign Up," and complete the organization profile. Use your work email, not a personal address, because Epic ties your access tier to your stated organization type.

Registering with your work email and providing accurate organization details upfront prevents delays when you later request production access or apply for elevated API scopes.

Once your account is active, you gain access to Epic's public FHIR sandbox, which runs on a shared Epic instance and supports read and write operations against synthetic patient data. Access to certain APIs, especially those involving proprietary Epic data models or patient-facing scopes, requires a separate agreement with Epic or active sponsorship from an existing Epic customer organization.

Technical prerequisites

You need a working understanding of HL7 FHIR R4 before attempting an Epic integration. Epic's FHIR implementation follows the R4 specification (version 4.0.1) for most current APIs, with some legacy endpoints still operating on DSTU2 or STU3. If you're unfamiliar with FHIR resource types, the correct place to start is the official HL7 FHIR R4 specification at hl7.org/fhir/R4. Knowing the difference between resource types like Patient, Encounter, and Observation will save you time when reading Epic's API spec pages.

On the authorization side, you need familiarity with OAuth 2.0, specifically the SMART on FHIR authorization profile. Epic uses SMART on FHIR for both standalone and EHR-launch flows. You should understand the distinction between authorization code flow, which applies to user-facing apps, and client credentials flow, which applies to backend system-to-system integrations, before you open Epic's OAuth guides.

A few technical items to have ready before you go further:

  • A redirect URI registered under HTTPS (required for authorization code flow; Epic rejects HTTP in production)
  • A JSON Web Key Set (JWKS) endpoint or a static public key if you plan to use backend services with asymmetric JWT client authentication
  • Working knowledge of reading OpenAPI or Swagger specs, since Epic's API reference pages use this format
  • A test client application framework in your language of choice to execute FHIR requests against the sandbox

Organizational context you need to gather

Your integration path through Epic depends heavily on your relationship to Epic customers. Before you read another page of documentation, answer these questions:

  • Are you an independent software vendor (ISV) building a product for multiple health systems?
  • Are you an internal developer at an organization that already runs Epic as its EHR?
  • Are you a third-party vendor building a point solution for one specific Epic customer?

Each scenario leads to a different registration path, different API access levels, and different production readiness requirements. Internal developers at Epic customer organizations, for example, frequently work through their health system's Epic Technical Services team and may bypass parts of the open.epic.com public registration workflow entirely.

You also need the FHIR base URL of any Epic instance you plan to connect to before writing API calls. Every Epic environment publishes a metadata endpoint at [base]/api/FHIR/R4/metadata, which returns a CapabilityStatement listing exactly which resources and operations that server supports. Ask your Epic customer contact for the base URL as early as possible in your planning process.

Map your use case to the right Epic program

Epic does not operate a single developer program. It runs several distinct tracks, and the one you belong to determines which APIs you can access, how you authenticate, and what approval process you go through before connecting to a live Epic environment. Choosing the wrong track early means rework later, so get this right before you dig into the epic fhir documentation details.

Patient-facing apps vs. backend system integrations

Your first decision is whether a human user logs in during your integration or not. Patient-facing and clinician-facing apps use the SMART on FHIR authorization code flow, where a real user authenticates through Epic's identity provider and grants your app permission to act on their behalf. These apps rely on user-context scopes tied to a specific patient or provider session.

Backend integrations work differently. If your system calls Epic on a scheduled basis or in response to operational events, without any user present, you use the SMART backend services profile, also called client credentials with JWT assertion. Patient logistics platforms that pull discharge data or push transportation status updates typically fall into this category.

Choosing the wrong authorization flow at the start forces you to re-register your app and re-negotiate scopes with every Epic customer you connect to.

The App Orchard and open.epic.com tracks

Open.epic.com is where independent developers start. It gives you sandbox access, API reference pages, and a self-service app registration workflow. You can build and test here without any Epic customer involvement. This track works for vendors who plan to sell or license a product to multiple health systems.

The Epic App Orchard is a separate, curated marketplace for apps that Epic has reviewed and certified for clinical use. Getting listed there requires a formal review process, but it significantly reduces the sales cycle with health system customers because their procurement teams already trust App Orchard listings. If you're building a commercial product, targeting the App Orchard should be part of your roadmap even if you start on open.epic.com.

Internal developers at an organization that already runs Epic should contact their Epic Technical Services liaison directly. Those teams can provision dedicated sandbox environments, grant organization-specific API scopes, and accelerate testing timelines that would otherwise take months through the public portal.

Find the right FHIR API spec pages

Once you know your program track, you need to locate the specific API reference pages that cover your use case. Epic's open.epic.com portal organizes its FHIR API catalog by resource type, so you search by the clinical or operational data you want to read or write, not by feature name. Go to open.epic.com, navigate to the "API" section, and use the search bar to find resources like Patient, Appointment, or ServiceRequest. Each resource listing links to a dedicated spec page that covers supported interactions, required parameters, response examples, and scope requirements.

Browse the API catalog by resource type

The catalog groups APIs into categories: clinical data, scheduling, financial, and administrative. For patient logistics use cases, you'll spend most of your time in the scheduling and clinical data categories. ServiceRequest covers orders for transportation and home health services. Appointment covers scheduled visits. DocumentReference covers clinical notes and forms your integration may need to read or attach.

Each resource page in the Epic FHIR documentation lists the supported FHIR operations for that resource, typically read, search, and sometimes create or update. Check the "Supported Parameters" table on each page before you write a single query. Epic's implementation only returns results for parameters it explicitly supports; sending an unsupported parameter does not cause an error, it just returns an empty result set, which can waste hours of debugging time.

Always verify which search parameters a specific Epic instance supports by calling the metadata endpoint at [base]/api/FHIR/R4/metadata and checking the CapabilityStatement before assuming a parameter is active.

Read the scope requirements on each spec page

Every Epic API spec page lists the OAuth scopes required to call that endpoint. These scopes appear under a "Authorization" or "Scopes" heading on the resource page. Copy these scope strings exactly as written, because Epic's authorization server performs case-sensitive scope matching. A common mistake is requesting patient/Patient.read when the required scope is patient/Patient.Read, which causes the token request to fail silently or return a token that the resource server rejects.

Keep a running list of every scope your integration requires across all resource types. You'll need the complete, combined scope list when you register your application and when you submit a production access request to each Epic customer site.

Understand Epic's FHIR versions and profiles

Epic's FHIR implementation does not use a single uniform version across every environment. Different Epic instances run different FHIR versions depending on when the health system last upgraded, and some organizations still expose DSTU2 or STU3 endpoints alongside their R4 APIs. Before you write any integration code, confirm which FHIR version the specific Epic environment you're targeting actually supports.

R4 is current, but legacy versions still appear

Epic has standardized new development on FHIR R4 (version 4.0.1), and most resources in the current epic fhir documentation reference R4 as the baseline. However, if you're connecting to a health system that hasn't updated recently, their instance may still serve DSTU2 for some patient-facing endpoints. The easiest way to confirm what a server supports is to call the metadata endpoint directly:

GET [base]/api/FHIR/R4/metadata

The response returns a CapabilityStatement resource that lists every supported FHIR version, resource type, operation, and search parameter for that specific instance. Read this document before you build any queries. If you skip this step and assume R4 support, you may write queries against endpoints that don't exist on a given customer's server.

Pull the CapabilityStatement from every new Epic environment you connect to rather than assuming parity with the sandbox, because individual health system configurations vary.

Epic's US Core profiles and custom extensions

Epic layers US Core Implementation Guide profiles on top of base FHIR R4 resources. These profiles add required fields, constrain value sets, and define search parameter expectations that go beyond what the base FHIR spec requires. For example, the US Core Patient profile mandates specific identifier types and name fields that the base Patient resource treats as optional.

Beyond US Core, Epic defines its own custom extensions for proprietary data elements. You'll find these documented on the individual resource spec pages at open.epic.com under an "Extensions" heading. Custom extensions use Epic-specific URLs that follow the pattern http://open.epic.com/FHIR/StructureDefinition/[extension-name]. Your application needs to handle these extensions gracefully, either by reading them when they add clinical value or by ignoring them when they don't, without throwing a parsing error. Build your FHIR client to tolerate unknown extensions by default, which the FHIR specification explicitly requires for compliant implementations.

Follow Epic's OAuth 2.0 guides for your flow

Epic publishes separate OAuth 2.0 guides for each authorization flow on open.epic.com under the "Authorization" section of the developer portal. The guide you need depends entirely on whether a user is present during your integration. Read the correct guide first, because the token endpoints, request parameters, and client authentication methods differ significantly between flows, and conflating them is one of the most common reasons integrations fail during testing.

Authorization code flow for user-facing apps

Patient-facing and clinician-facing apps use the SMART on FHIR authorization code flow, where a user logs in through Epic's identity provider and grants your app access. Epic's guide for this flow walks you through the full sequence: constructing the authorization request, handling the redirect, and exchanging the authorization code for an access token.

Always include the launch scope and openid scope in your authorization request if your app launches from within Epic's EHR interface, or the launch context will not return.

Your authorization request to Epic's /oauth2/authorize endpoint must include the following parameters:

Parameter Value
response_type code
client_id Your registered app's client ID
redirect_uri Must match your registered redirect URI exactly
scope Space-separated list of all required scopes
state A random, unguessable string you generate per request
aud The FHIR base URL of the target Epic instance

Backend services flow for system integrations

System-to-system integrations that run without a user present use the SMART backend services profile, documented separately in the epic fhir documentation under "Backend OAuth 2.0." This flow uses a signed JWT as the client assertion instead of a client secret. Your application generates a JWT, signs it with your private key, and posts it directly to Epic's /oauth2/token endpoint to receive an access token.

Your JWT client assertion must include these claims:

{
  "iss": "your-client-id",
  "sub": "your-client-id",
  "aud": "https://[epic-instance]/oauth2/token",
  "jti": "unique-token-id",
  "exp": 1700000000
}

Set the exp claim no more than five minutes into the future. Epic's token server rejects assertions with longer expiration windows as a security measure, and that rejection returns a generic invalid_client error that provides no additional context.

Register your app and get client IDs

App registration is a required step before you call any Epic FHIR endpoint in production, and it determines the client ID and authentication credentials your application uses in every token request. You complete this process on open.epic.com, and the details you provide during registration directly affect which scopes Epic approves and how Epic customer sites evaluate your application during their own internal review processes.

Complete the app registration form

Log in to open.epic.com, navigate to "MyApps," and click "Create New App." Epic's registration form asks for your application name, a short description, the type of app you're building (patient-facing, clinician-facing, or backend), and the authorization flow you intend to use. Fill every field accurately, because this information appears to Epic customer administrators when they review your connection request. Vague descriptions slow down approval.

The form also asks you to specify the FHIR scopes your application requires. Paste the complete scope list you compiled while reading the epic fhir documentation API spec pages. Do not request scopes speculatively; every scope you add is a scope an Epic customer administrator must explicitly approve, and unnecessary scopes increase friction. Below is an example scope string for a backend patient logistics integration:

system/Patient.read system/Encounter.read system/ServiceRequest.read system/Appointment.read

For apps using the authorization code flow, enter your redirect URI in the designated field. Epic performs an exact-match check against this value during every authorization request, so the URI you register must match character-for-character what your application sends, including trailing slashes and query parameters.

Submit your app registration with a complete and accurate scope list from the start, because adding scopes later requires re-approval from every Epic customer you've already connected to.

Store and protect your client credentials

After Epic processes your registration, the portal displays your client ID and, depending on your flow, either a client secret or a confirmation that your JWKS endpoint is registered. Your client ID is not sensitive on its own, but your private key or client secret must never appear in client-side code, version control, or log files. Store secrets in a dedicated secrets manager such as AWS Secrets Manager or Azure Key Vault, and rotate them on a regular schedule. For backend services flows, generate a new RSA or EC key pair specifically for your Epic integration rather than reusing keys from other services. Epic's token server validates the key against your registered JWKS endpoint on every request, so any mismatch will fail your token exchange immediately.

Test in the sandbox and validate scopes

Epic's public sandbox at open.epic.com runs on a shared Epic instance loaded with synthetic patient data, giving you a realistic environment to test FHIR requests before you ever touch a real patient record. Your sandbox client ID is issued automatically after app registration, and you use it exactly the same way you'll use your production credentials, so the habits you build here carry directly into live deployments. Treat sandbox testing as a full dress rehearsal, not a quick smoke test.

Run your first sandbox requests

Your first request should always be a call to the metadata endpoint to confirm your sandbox environment is responding and to verify which resources and operations are active. Send this request without any authentication to check basic connectivity:

GET https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/metadata
Accept: application/fhir+json

Once you confirm the metadata endpoint returns a CapabilityStatement, proceed to authenticate. Use your sandbox client ID to complete the OAuth flow for your chosen authorization type, then send a simple Patient read request using one of the synthetic patient identifiers Epic provides in the open.epic.com test patient catalog. A valid first request looks like this:

GET https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/Patient/eJzlzMNsc.....
Authorization: Bearer [your-access-token]
Accept: application/fhir+json

If the response returns a Patient resource with populated fields, your authentication and base connectivity are working correctly. If you receive a 401 or 403, your token is either missing, expired, or carrying the wrong scopes for that resource.

Log the full HTTP response headers alongside the body during sandbox testing, because Epic returns diagnostic information in headers like WWW-Authenticate that the response body alone does not include.

Confirm your scope list works end to end

Work through every resource type your integration requires and test each one against your complete scope list from the epic fhir documentation spec pages. Do not assume that a token granting access to one resource automatically grants access to related resources. Each scope is evaluated independently, so a missing scope on ServiceRequest will fail silently if your other reads succeed, making it easy to miss during a casual review. Build a simple checklist that maps each API call to the scope it requires, and verify every combination passes in the sandbox before you move forward.

Resource Required Scope Sandbox Test Result
Patient system/Patient.read Pass / Fail
Encounter system/Encounter.read Pass / Fail
ServiceRequest system/ServiceRequest.read Pass / Fail
Appointment system/Appointment.read Pass / Fail

Run this verification against every resource in your integration and resolve failures before advancing to production readiness steps.

Prepare for a live Epic customer deployment

Connecting to a real Epic environment is a fundamentally different process from sandbox testing. Every live Epic instance is controlled by the health system that runs it, not by Epic directly, which means you need that organization's explicit approval before your app can authenticate against their production server. Understanding this gating process early will save you from surprises when you're ready to go live.

Get sponsored by an Epic customer

Your sandbox client ID does not transfer to production. To connect to a specific health system's Epic environment, that organization must formally sponsor your application by approving it within their Epic instance. This sponsorship is separate from any agreement you have with Epic itself. Reach out to your technical contact at the health system, typically someone in their IT or Epic Technical Services team, and ask them to initiate the vendor approval process on their end. Provide them with your open.epic.com app ID and the list of scopes your integration requires so they can evaluate the request accurately.

Confirm that your health system contact has the administrative access needed to approve third-party app connections, because not every IT staff member at an Epic organization holds that permission level.

Submit your production access request

Once your sponsor has approved your application internally, you submit a production access request through open.epic.com under your app's settings. Epic requires you to supply the FHIR base URL of the target production environment and confirm that the health system has granted approval. Epic uses this confirmation to issue a production client ID scoped to that specific environment, which is distinct from any client IDs you hold for other customer sites.

Prepare the following items before you submit the request:

  • Confirmed FHIR base URL from your health system contact (call [base]/api/FHIR/R4/metadata to verify it resolves)
  • Written confirmation from the health system that they have approved your app in their Epic instance
  • Your final scope list drawn from the epic fhir documentation spec pages, with no speculative scopes included
  • Your JWKS endpoint URL or registered public key, depending on your authorization flow

Coordinate the go-live with the health system's technical team

Schedule a joint go-live call with the health system's Epic team before you flip your integration to production traffic. Use that call to confirm the production base URL, verify your client ID is active, and run one authenticated test request against a real resource while both teams are online. This eliminates ambiguity about whether a failure is on your side or theirs and gives both teams immediate context to resolve issues before they affect patient operations.

Troubleshoot common Epic on FHIR issues

Most Epic FHIR integration failures fall into a small set of repeatable patterns. Before you spend hours tracing code, run through the most common failure categories below. Each one has a specific cause and a concrete fix that you can apply without waiting for Epic support to respond.

Fix invalid_client errors during token exchange

An invalid_client error from Epic's token endpoint almost always points to a JWT assertion problem in backend services flows. Check these three things in order: your aud claim must match the exact token endpoint URL of the target Epic instance (not a generic URL), your exp claim must be no more than five minutes from the current time, and your private key must correspond to the public key registered at your JWKS endpoint. Epic validates all three on every request.

Run this quick diagnostic against your JWT before sending it to Epic's token endpoint:

iss: matches your registered client_id exactly
sub: matches your registered client_id exactly
aud: https://[specific-epic-instance]/oauth2/token
jti: unique string, not reused across requests
exp: current Unix time + 300 seconds maximum

If you reuse the same jti value across token requests, Epic's server rejects the assertion as a replay attack even when every other claim is correct.

Resolve unexpected empty search results

Empty result sets with a 200 status code are one of the hardest failures to spot in an Epic integration. The epic fhir documentation spec pages list supported search parameters for each resource, but individual Epic instances only activate the parameters their administrators have enabled. If your search returns zero results when you expect records, your query may be using an unsupported parameter that Epic silently ignores rather than rejecting.

Pull the CapabilityStatement from the specific environment you're querying and compare its searchParam entries against the parameters you're sending. Remove any parameter not listed and rerun the search.

Handle scope mismatch on resource reads

A 403 response on a resource read usually means your access token is missing the required scope for that specific resource on that specific Epic instance. Scopes approved in the sandbox do not automatically transfer to production environments. Check the following items when you receive a 403:

  • Confirm the scope appears in the token you received by decoding it at a JWT debugger
  • Verify the health system's Epic administrator approved that scope during their internal review
  • Match your scope string character-for-character against the scope listed on the API spec page, including case

Next steps

You now have a complete path through Epic's developer ecosystem, from finding the right epic fhir documentation pages on open.epic.com to resolving the most common token and scope failures. The sequence matters: confirm your use case, locate the correct API specs, understand the FHIR version your target environment runs, choose the right OAuth flow, and test every scope against your full resource list before you request production access.

Your next move is to open open.epic.com, create your developer account, and pull the CapabilityStatement from your target Epic sandbox before writing any integration code. Every decision after that, which resources to query, which scopes to request, which authorization flow to configure, becomes easier once you know exactly what a specific Epic instance supports.

If your platform needs to connect patient logistics workflows directly to Epic data, explore how VectorCare integrates with EHR systems to streamline transportation, home care, and DME coordination.

By
SAP Ariba Invoicing: Features, Setup, And Invoice Submission

SAP Ariba Invoicing: Features, Setup, And Invoice Submission

By
What Is Logistics Analytics? Types, KPIs, And Use Cases

What Is Logistics Analytics? Types, KPIs, And Use Cases

By
Athenahealth API Documentation: How To Access Official Guides

Athenahealth API Documentation: How To Access Official Guides

By

Rhapsody Integration Engine Documentation: Official Guides

By
Rhapsody Integration Engine Documentation: Official Guides

NFPA EMS Response Time Standards: Benchmarks Explained

By
NFPA EMS Response Time Standards: Benchmarks Explained

5 Non Emergency Medical Transport Services Near Me Options

By
5 Non Emergency Medical Transport Services Near Me Options

What Is The Healthcare Ecosystem? Key Players And Connections

By
What Is The Healthcare Ecosystem? Key Players And Connections

SAM Gov Exclusion Search: Steps To Find Active Exclusions

By
SAM Gov Exclusion Search: Steps To Find Active Exclusions

9 Best Healthcare Compliance Management Software for 2026

By
9 Best Healthcare Compliance Management Software for 2026

The Future of Patient Logistics

Exploring the future of all things related to patient logistics, technology and how AI is going to re-shape the way we deliver care.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Latest
CMS Compliance Program Guidance: Requirements & 7 Elements

CMS Compliance Program Guidance: Requirements & 7 Elements

By
NCQA Standards Credentialing: 2025-2026 Rules & Timeframes

NCQA Standards Credentialing: 2025-2026 Rules & Timeframes

By
How To Automate Invoice Processing: Step-By-Step Guide

How To Automate Invoice Processing: Step-By-Step Guide

By
Ambulance Dispatch Protocols: SOPs, Triage, And Practices

Ambulance Dispatch Protocols: SOPs, Triage, And Practices

By

The Future of Patient Logistics

Exploring the future of all things related to patient logistics, technology and how AI is going to re-shape the way we deliver care.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.