Authentication
Heads up — this page will change. How you obtain credentials is moving to
console.esus.health, which is currently in development. API key provisioning, team access, and initial login will happen through the console. The API-side verification (JWT onAuthorization: Bearer …, API keys onX-API-Key: …) is not changing, so code you write against the examples below will keep working. We will update this page with the new credential-issuance flow when the console ships.
ESUS supports two authentication methods: JWT Tokens for user sessions and API Keys for machine-to-machine communication.
Method 1: JWT Tokens
JWTs (JSON Web Tokens) are used for user authentication.
Login
curl -X POST https://api.esus.health/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@hospital.com",
"password": "SecurePass123!"
}'
Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": "900s"
}
Using the Access Token
Include the token in the Authorization header:
curl -X GET https://api.esus.health/fhir/Patient \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Renewing the Token
Access tokens expire after 15 minutes (900 seconds). Use the refresh token to obtain a new access token:
curl -X POST https://api.esus.health/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "YOUR_REFRESH_TOKEN"
}'
Method 2: API Keys
API Keys are ideal for server-to-server communication.
Create an API Key
curl -X POST https://api.esus.health/api-keys \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Server",
"scopes": ["Patient.read", "Observation.read", "Observation.create"]
}'
Response (HTTP 201 Created):
{
"id": "c1a2e3d4-5b6f-7890-abcd-ef1234567890",
"name": "Production Server",
"clientId": "a7b1c2d3e4f56789abcdef0123456789",
"secret": "3f8c2a105b4e4d8a9c1f2e7a8b6d4f906fa6c1a2e3d4b5c6",
"scopes": ["Patient.read", "Observation.read", "Observation.create"],
"expiresAt": null,
"active": true,
"rateLimit": null,
"createdAt": "2026-04-21T10:30:00Z"
}
Both clientId and secret are random hex strings (no prefixes). Save secret immediately — it is returned only once and cannot be retrieved again.
Using an API Key
Send the credentials in the X-API-Key header as clientId:secret:
curl -X GET https://api.esus.health/fhir/Patient \
-H "X-API-Key: a7b1c2d3e4f56789abcdef0123456789:3f8c2a105b4e4d8a9c1f2e7a8b6d4f906fa6c1a2e3d4b5c6"
Scope Permissions
Scopes follow the Resource.action pattern. The valid actions are read, create, update, and delete; searches (a GET on the collection) are authorized by read. Use Resource.* for all actions on a resource, or * (on its own, no prefix) for full access.
*.readis not valid: the resource wildcard only exists as a bare*.- The
writeaction grants no write permissions at runtime — usecreate,update, ordeleteas appropriate.
| Scope | Permission |
|---|---|
Patient.read | Read and search Patient resources |
Patient.create | Create Patients |
Patient.update | Update Patients |
Patient.delete | Delete Patients |
Patient.* | All Patient operations |
* | Full access (all resources and actions) |
Method 3: SMART on FHIR (OAuth 2.0)
SMART on FHIR is the standard OAuth 2.0 authorization flow for third-party healthcare apps. Use this when building apps that act on behalf of a user.
Discover the Authorization Server
curl https://api.esus.health/.well-known/smart-configuration
Response:
{
"authorization_endpoint": "https://api.esus.health/smart/authorize",
"token_endpoint": "https://api.esus.health/smart/token",
"capabilities": ["client-public", "client-confidential-symmetric", "context-ehr-patient", "sso-openid-connect", "permission-v2"],
"scopes_supported": ["openid", "fhirUser", "launch", "launch/patient", "patient/*.read", "patient/*.write", "user/*.read", "user/*.write", "offline_access"]
}
Step 1: Register Your Application
curl -X POST https://api.esus.health/smart/apps \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My FHIR App",
"redirectUris": ["https://myapp.com/callback"],
"scopes": ["patient/*.read", "openid", "fhirUser"],
"isConfidential": true
}'
Response:
{
"id": "app-12345",
"clientId": "client-abc",
"clientSecret": "secret-xyz",
"redirectUris": ["https://myapp.com/callback"]
}
Step 2: Authorization Request (PKCE)
Redirect the user’s browser to /smart/authorize (it is a GET endpoint; the user-agent performs the request):
GET https://api.esus.health/smart/authorize
?client_id=client-abc
&response_type=code
&scope=patient/*.read openid fhirUser
&redirect_uri=https://myapp.com/callback
&state=random-state-string
&code_challenge=BASE64URL(SHA256(code_verifier))
&code_challenge_method=S256
Step 3: Token Exchange
curl -X POST https://api.esus.health/smart/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "redirect_uri=https://myapp.com/callback" \
-d "client_id=client-abc" \
-d "client_secret=secret-xyz" \
-d "code_verifier=YOUR_CODE_VERIFIER"
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "patient/*.read openid fhirUser",
"patient": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"fhirUser": "Practitioner/a7b1c2d3-e4f5-6789-abcd-ef0123456789"
}
Step 4: Use the Token
curl https://api.esus.health/fhir/Patient/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
SMART Scopes
| Scope | Access |
|---|---|
patient/*.read | Read all resources for the in-context patient |
patient/*.write | Write resources for the in-context patient |
user/*.read | Read resources accessible to the current user |
user/*.write | Write resources accessible to the current user |
openid | OpenID Connect identity token |
fhirUser | Current user FHIR resource reference |
Quick Reference
| Method | When to Use | Header |
|---|---|---|
| JWT | User sessions, internal apps | Authorization: Bearer token |
| API Key | Server to server, CLI tools | X-API-Key: clientId:secret |
| SMART on FHIR | Third-party apps, user-delegated access | Authorization: Bearer oauth_token |
Next Steps
Now that you understand authentication, learn about the most important FHIR resource: Patient.