Quick Start
Two paths depending on whether you have an Epic developer account:
| SMART Health IT sandbox | Epic non-production sandbox | |
|---|---|---|
| Account needed | None | Free โ fhir.epic.com |
| Real Epic data | No โ synthetic Synthea patients | Yes โ Epic's own sandbox patients |
| Time to first launch | ~5 minutes | ~75 minutes (includes 1-hour sync) |
| Maven profile | -Psmart | -Pepic |
Start with the SMART Health IT sandbox โ it requires nothing and proves the full flow works.
Option A โ SMART Health IT sandbox (recommended first step)โ
1. Clone the repositoryโ
git clone https://github.com/your-org/smart-fhir-client.git
cd smart-fhir-client
2. Start the appโ
mvn spring-boot:run -Dspring-boot.run.profiles=smart
You should see:
INFO SmartFhirApplication - Started SmartFhirApplication in 4.2 seconds
INFO FhirClientFactory - FhirClientFactory ready โ socketTimeout=30000ms, connectTimeout=10000ms
3. Verify the health endpointโ
curl http://localhost:8080/health
{"status":"UP","app":"smart-fhir-client","epicClientId":"growth_ch..."}
4. Launch from SMART Health ITโ
- Open launch.smarthealthit.org in your browser
- Set App Launch URL to
http://localhost:8080/launch - Set FHIR Version to
R4 - Choose Launch Type โ
Provider EHR Launch - Select any patient from the list
- Click Launch
Your browser redirects through the SMART handshake and lands on the dashboard at
http://localhost:8080/.
- Blue patient banner with the selected patient's name
- Dashboard with stat cards showing condition and medication counts
- Navigation links to Patient, Conditions, Medications pages
- Clinician profile card (if
openidscope was granted)
Option B โ Epic non-production sandboxโ
1. Register with Epic and get a client IDโ
Follow the Epic Registration guide โ. This takes about 15 minutes plus a 1-hour sync wait.
2. Export your client IDโ
export EPIC_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
3. Start the app with the Epic profileโ
mvn spring-boot:run -Dspring-boot.run.profiles=epic
4. Launch from Epic LaunchPadโ
- Open open.epic.com/launchpad
- Select SMART on FHIR App Launch
- Set Launch URL to
http://localhost:8080/launch - Pick a test patient (e.g.
Camila Lopez) - Click Launch
What happens during a launchโ
Here is what the logs show for a successful EHR launch:
INFO SmartLaunchController - EHR launch received โ iss=https://launch.smarthealthit.org/v/r4/fhir
INFO SmartDiscoveryService - Fetching SMART configuration from ISS: https://...
INFO SmartDiscoveryService - SMART configuration cached โ authEndpoint=..., tokenEndpoint=...
DEBUG SmartAuthRequestBuilder - PKCE generated and stored in session โ challenge method: S256
INFO SmartLaunchController - Redirecting to authorize endpoint โ mode=ehr, state=abc123...
INFO SmartCallbackController - SMART EHR launch complete โ patient=eXXXX, encounter=eYYYY, scope=...
INFO IdTokenValidator - id_token validated โ subject=eProvider123
INFO UiController - Fetching Patient/eXXXX
Each log line maps to a class and package in the codebase:
| Log line | Class | Package |
|---|---|---|
EHR launch received | SmartLaunchController | launch/ |
Fetching SMART configuration | SmartDiscoveryService | discovery/ |
PKCE generated | SmartAuthRequestBuilder | auth/ |
Redirecting to authorize | SmartLaunchController | launch/ |
SMART EHR launch complete | SmartCallbackController | token/ |
id_token validated | IdTokenValidator | oidc/ |
Fetching Patient/ | UiController | ui/ |
Exploring the APIโ
After a successful launch, the session is authenticated. Use curl or your browser to
explore all API endpoints:
Session infoโ
Always safe โ works before patient is selected (standalone launch).
curl http://localhost:8080/api/session
{
"launchMode": "ehr",
"patientId": "erXuFYUfucBZaryVksYEcMg3",
"encounterId": "eEnc-789",
"needPatientBanner": true,
"grantedScopes": "launch openid fhirUser patient/Patient.rs ...",
"hasUserProfile": true,
"tokenExpiresAt": "2025-01-15T10:30:00Z"
}
Clinician profileโ
Requires openid scope.
curl http://localhost:8080/api/me
{
"subject": "eProvider-ABC123",
"displayName": "Dr. Jane Smith",
"fhirUser": "Practitioner/eProvider-ABC123",
"issuer": "https://fhir.epic.com/..."
}
Patientโ
Requires patient/Patient.rs scope.
curl http://localhost:8080/api/patient
{
"id": "erXuFYUfucBZaryVksYEcMg3",
"name": "Camila Lopez",
"birthDate": "1985-03-12",
"gender": "female",
"patientBanner": true
}
Conditionsโ
Requires patient/Condition.rs scope.
curl http://localhost:8080/api/conditions
[
\{
"id": "eCond-001",
"code": "44054006",
"display": "Type 2 diabetes mellitus",
"status": "active"
\}
]
Summaryโ
Combines all available data in one call.
curl http://localhost:8080/api/summary
Running the testsโ
Unit tests only (fast, no network)โ
mvn test
Runs 140+ unit tests with WireMock stubs โ no internet access required. Typically completes in 15โ30 seconds.
SMART Health IT integration testsโ
mvn verify -Psmart
Runs SmartHealthSandboxIT โ fetches the real discovery document from
launch.smarthealthit.org and reads a known synthetic patient. Requires internet access.
Epic sandbox integration testsโ
export EPIC_CLIENT_ID=your-non-production-client-id
mvn verify -Pepic
Runs EpicSandboxIT โ validates Epic's discovery document, builds an authorize URL
with all Epic-required parameters, and reads a known Epic sandbox patient.
Common issuesโ
Change the port in application.yml:
server:
port: 8081
Update your redirect URI accordingly and re-register it in your Epic app if using the Epic profile.
You haven't completed a launch yet โ the session has no SmartLaunchContext.
Run a launch from LaunchPad or SMART Health IT first.
Check the app logs. The most common cause is a mismatched redirect URI โ
what you registered in Epic or SMART Health IT must exactly match
smart.epic.redirect-uri in application.yml.
The selected patient may not have active conditions or medications in the sandbox.
Try a different patient, or check that the relevant scopes are in application.yml.
WARN IdTokenValidator - JWKS fetch failed โ skipping signature check
This is non-fatal. FHIR data access works normally. Full cryptographic RS256 signature
verification requires adding nimbus-jose-jwt โ see the OIDC guide.
Next stepsโ
- Configuration reference โ โ understand every property
- Epic Registration โ โ set up your free Epic developer account
- Architecture Overview โ โ understand the codebase structure
- EHR Launch Flow โ โ deep dive into the launch sequence