Epic FHIR R4 REST API
Epic's FHIR R4 API enables access to electronic health record (EHR) data including patients, encounters, observations, conditions, medications, and more. Epic supports SMART on FHIR and OAuth 2.0 for authorization. The open sandbox at fhir.epic.com allows testing with synthetic data. Production access requires registration with Epic's App Orchard and approval from individual health systems.
Warnings
- breaking Epic FHIR endpoints require a valid OAuth 2.0 Bearer token for every request. There is no API key fallback. Unauthenticated requests return 401.
- breaking The open sandbox base URL (fhir.epic.com) is for testing only. Production endpoints vary per health system and require App Orchard registration and approval.
- gotcha Epic's FHIR server requires the Accept header to be 'application/fhir+json'. Omitting it or using 'application/json' may return XML or errors depending on the Epic version.
- gotcha Access tokens are short-lived (typically 5 minutes). Caching tokens without refresh logic causes sudden 401 errors.
- gotcha Search results are paginated via FHIR Bundle 'link' entries. Epic defaults to small page sizes (often 10-20 resources). Not following pagination misses most results.
- gotcha Epic scopes are strictly enforced. Requesting a resource outside your granted SMART scopes returns 403 Forbidden, not an empty result set.
Install
-
pip install requests
Imports
- requests
import requests
Quickstart
import os
import requests
BASE_URL = "https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4"
access_token = os.environ.get("EPIC_FHIR_ACCESS_TOKEN", "")
headers = {
"Authorization": f"Bearer {access_token}",
"Accept": "application/fhir+json"
}
# Read a test patient from the Epic open sandbox
resp = requests.get(
f"{BASE_URL}/Patient/erXuFYUfucBZaryVksYEcMg3",
headers=headers
)
resp.raise_for_status()
patient = resp.json()
print(f"Patient: {patient['name'][0]['given'][0]} {patient['name'][0]['family']}")