Getting Started
This guide walks through connecting a third-party application to the Patient Access API using the SMART App Launch standalone flow with PKCE.
Submit your application registration request. Once approved, you will receive a
client_id that identifies your application in the authorization flow.
Fetch the SMART configuration document to discover all OAuth 2.0 endpoints. This document is updated automatically and should be fetched at application startup rather than hardcoded.
GET https://cms-api.wasatch.org/fhir/r4/.well-known/smart-configuration
Accept: application/json
The response includes the endpoints your application needs:
{
"authorization_endpoint": "https://<authorization-server>/authorize",
"token_endpoint": "https://<authorization-server>/token",
"scopes_supported": ["openid", "fhirUser", "launch/patient", "patient/*.rs", ...],
"capabilities": ["launch-standalone", "client-public", "permission-patient", ...]
}
Use the authorization_endpoint and token_endpoint values returned
by this document in the steps below — do not hardcode them.
The capability statement is also available at
https://cms-api.wasatch.org/fhir/r4/metadata.
Before redirecting the user, generate a PKCE code verifier and its SHA-256 challenge. PKCE is required — plain method is not supported.
// Pseudocode — generate PKCE values
code_verifier = base64url(random_bytes(32))
code_challenge = base64url(sha256(ascii(code_verifier)))
Then redirect the user to the authorization_endpoint with these parameters:
GET {authorization_endpoint}
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyourapp.example.com%2Fcallback
&scope=openid%20fhirUser%20launch%2Fpatient%20patient%2F*.rs%20offline_access
&state=RANDOM_UNGUESSABLE_VALUE
&aud=https%3A%2F%2Fcms-api.wasatch.org%2Ffhir%2Fr4
&code_challenge=BASE64URL_SHA256_OF_CODE_VERIFIER
&code_challenge_method=S256
Parameter notes:
redirect_uri— Must exactly match one of the URIs you registered during application registration. Requests with an unregistered URI will be rejected.scope— Space-separated list. See the Scopes Reference for all available values.state— Must be a random, unguessable value. Validate it on the callback to prevent CSRF.aud— The base URL of the FHIR server. Required by the SMART App Launch specification.code_challenge_method— OnlyS256is accepted.
After the user authorizes your application, they are redirected to your
redirect_uri with a code query parameter.
Exchange it for an access token by making a POST to the token endpoint:
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTHORIZATION_CODE_FROM_CALLBACK
&redirect_uri=https%3A%2F%2Fyourapp.example.com%2Fcallback
&client_id=YOUR_CLIENT_ID
&code_verifier=CODE_VERIFIER_GENERATED_IN_STEP_3
A successful response returns:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "0.A...",
"id_token": "eyJ...",
"patient": "123456",
"scope": "openid fhirUser launch/patient patient/*.rs offline_access"
}
Response field notes:
patient— The FHIR Patient ID of the authenticated patient. Use this value to construct patient-specific queries (e.g./Patient/123456).refresh_token— Only returned whenoffline_accessis in the requested scope. See Step 5 for how to use it.
When the access_token expires, use the refresh_token to obtain a new one
without prompting the patient again.
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=REFRESH_TOKEN_FROM_STEP_4
&client_id=YOUR_CLIENT_ID
The response has the same shape as the authorization code token response and may include
a rotated refresh_token — store it and discard the old one.
Include the access token in the Authorization header on every FHIR request.
All responses are returned as application/fhir+json.
GET https://cms-api.wasatch.org/fhir/r4/Patient/PATIENT_ID
Authorization: Bearer ACCESS_TOKEN
Accept: application/fhir+json
Use the patient value from the token response as PATIENT_ID.
Resources are automatically scoped to that patient — no additional filtering is required.
Example paginated query:
GET https://cms-api.wasatch.org/fhir/r4/Condition?_count=20&_offset=0
Authorization: Bearer ACCESS_TOKEN
Accept: application/fhir+json
Error responses are returned as FHIR OperationOutcome resources:
{
"resourceType": "OperationOutcome",
"issue": [{
"severity": "error",
"code": "forbidden",
"diagnostics": "The requested scope is not authorized."
}]
}
For patients to authorize your application to access their data, they must first be registered with Wasatch Behavioral Health. Direct your users to the Patient Registration page for instructions on completing in-person registration and linking their Microsoft EntraID account.
Register a Patient