Working with FHIR Sandboxes
This guide covers setting up access to public FHIR sandboxes for testing and development. These sandboxes provide free access to test data and realistic FHIR APIs without requiring production EHR credentials.
Epic on FHIR Sandbox
Epic provides a public testing sandbox with sample patients and resource specifications available for developing against their FHIR Server.
Prerequisites
- Free Epic on FHIR developer account: https://fhir.epic.com/
- No existing Epic customer account required (it only takes a minute)
Step 1: Create an App
- Log in to https://fhir.epic.com/

- Navigate to "Build Apps" → "Create"

- Fill out the application form:
- Application Name: Choose any descriptive name
- Application Type: Check "Backend Systems"
- FHIR APIs: Select the APIs you need (note the versions)

Step 2: Configure OAuth2 with JWT Authentication
Epic uses OAuth2 with JWT assertion for authentication.
Generate Key Pair
Follow Epic's instructions to create a Public Private key pair for JWT signature:
# Generate private key - make sure the key length is at least 2048 bits.
openssl genrsa -out privatekey.pem 2048
# Export public key as base64 encoded X.509 certificate
openssl req -new -x509 -key privatekey.pem -out publickey509.pem -subj '/CN=myapp'
Where /CN=myapp is the subject name (e.g., your app name). The subject name doesn't have functional impact but is required for creating an X.509 certificate.
Register Public Key via JWKS URL
Epic now requires registering your public key via a JWKS (JSON Web Key Set) URL instead of direct file upload. For quick and dirty development/testing purposes, you can use ngrok to expose your JWKS server publicly.
-
Set up a JWKS server:
-
Get a free static domain from ngrok:
- Sign up at ngrok.com
- Claim your free static domain from the dashboard
- Example:
your-app.ngrok-free.app
-
Expose your JWKS server:
-
Register in Epic App Orchard:
- In your Epic app configuration, locate the Non-Production JWK Set URL field
- Enter:
https://your-app.ngrok-free.app/.well-known/jwks.json - Click Save
- Note down your Non-Production Client ID
The JWKS must be:
- Publicly accessible without authentication
- Served over HTTPS
- Stable (URL should not change)

Step 3: Complete App Setup
- Fill out remaining required fields (description, etc.)
- Check to confirm terms of use
- Click Save & Ready for Sandbox

Step 4: Configure Environment Variables
Create a .env file with your credentials:
# .env file
EPIC_BASE_URL=https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4
EPIC_CLIENT_ID=your_non_production_client_id
EPIC_CLIENT_SECRET_PATH=path/to/privatekey.pem
EPIC_TOKEN_URL=https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token
EPIC_USE_JWT_ASSERTION=true
EPIC_KEY_ID=healthchain-demo-key # Must match the kid in your JWKS
Important: The EPIC_KEY_ID must match the Key ID (kid) you used when creating your JWKS. This allows Epic to identify which key to use for JWT verification.
Using Epic Sandbox in Code
from healthchain.gateway.clients import FHIRAuthConfig
# Load configuration from environment variables
config = FHIRAuthConfig.from_env("EPIC")
EPIC_URL = config.to_connection_string()
# Add to FHIR gateway
from healthchain.gateway import FHIRGateway
gateway = FHIRGateway()
gateway.add_source("epic", EPIC_URL)
Testing Your Connection
After configuration:
This script will:
1. Load your Epic configuration
2. Create a JWT assertion with the kid header
3. Request an access token from Epic
4. Test a FHIR endpoint query
Available Test Patients
Epic provides sample test patients including:
- Derrick Lin - Patient ID:
eq081-VQEgP8drUUqCWzHfw3 - Linda Ross - Patient ID:
eIXesllypH3M9tAA5WdJftQ3 - Many others with various clinical scenarios
Troubleshooting (click to expand)
Token request fails after JWKS registration:
- Wait 15-30 minutes for Epic to propagate changes
- Verify your JWKS URL is publicly accessible (test in browser)
- Check that EPIC_KEY_ID matches the kid in your JWKS
- Ensure the ngrok tunnel is still running
JWKS format errors:
- Verify the JWKS structure at your URL matches Epic's requirements
- Check that n and e are properly base64url encoded (no padding)
- Algorithm should be RS384, RS256, or RS512
Cerner Sandbox
Cerner (now Oracle Health) provides both open and secure public sandboxes for the FHIR R4 APIs for Oracle Health Millennium Platform.
The Open Sandbox is read-only. It does not require authentication and is handy for quick proof of concepts:
You can get an idea of patients available in the open sandbox by querying some common last names:curl -i -H "Accept: application/json+fhir" "https://fhir-open.cerner.com/r4/ec2458f2-1e24-41c8-b71b-0e701af7583d/Patient?family=smith"
Documentation on Secure Sandbox coming soon.
Medplum
Medplum is an open-source healthcare platform that provides a compliant FHIR server. It's useful for testing with controlled data where you can upload your own test patients. Medplum uses standard OAuth2/OpenID authentication.
Prerequisites
- Medplum account: Register here
- Free tier available
Step 1: Create a Client Application
- Log in to your Medplum account
- Navigate to Client Application:
- Option 1: Use this direct link: ClientApplication
- Option 2: Click the Medplum logo (top-left) and search for "Client Application" in the resources search bar
- Create a new Client
- Configure Access Policy if needed:
- Required for: Production deployments, multi-user environments, restricted data access
- Optional for: Sandbox testing with personal test data
- For production setup, see Medplum's access control documentation
Step 2: Get Credentials
After creating the client:
- Note your Client ID
- Copy your Client Secret

Step 3: Configure Environment Variables
Create a .env file with your credentials:
# .env file
MEDPLUM_BASE_URL=https://api.medplum.com/fhir/R4
MEDPLUM_CLIENT_ID=your_client_id
MEDPLUM_CLIENT_SECRET=your_client_secret
MEDPLUM_TOKEN_URL=https://api.medplum.com/oauth2/token
MEDPLUM_SCOPE=openid
Using Medplum in Code
from healthchain.gateway import FHIRGateway
from healthchain.gateway.clients import FHIRAuthConfig
from dotenv import load_dotenv
load_dotenv()
# Load configuration from environment variables
config = FHIRAuthConfig.from_env("MEDPLUM")
MEDPLUM_URL = config.to_connection_string()
# Add to FHIR gateway
gateway = FHIRGateway()
gateway.add_source("medplum", MEDPLUM_URL)
Benefits of Medplum
- Full control: Upload your own test data
- FHIR R4 compliant: Complete FHIR API implementation
- Multi-source testing: Create multiple projects for different data sources
- Web interface: Browse and manage resources via UI
Tips for Multi-Source Testing
Different Test Data
Public sandboxes (Epic, Cerner) contain different test patients. When testing multi-source aggregation:
- Expected behavior: Queries for patients not in a source should fail gracefully
- Production use: Map patient identifiers across systems or use sources sharing patient cohorts
- Controlled testing: Use Medplum where you can upload the same test patients to multiple instances
Error Handling
Your code should handle:
- Network issues or downtime
- Patient not found in specific sources
- Rate limiting
- Authorization failures
Authentication
| Sandbox | Auth Mechanism |
|---|---|
| Epic | OAuth2 with JWT assertion (backend) |
| Medplum | OAuth2 client credentials (Client Credentials Flow) |
HealthChain's FHIRGateway handles these automatically via connection strings.
Next Steps
- Return to your tutorial to continue with the specific use case
- See FHIR Gateway documentation for advanced configuration
- Check FHIR Resources documentation for working with different resource types