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 on Authorization: Bearer …, API keys on X-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.write"]
  }'

Response (HTTP 201 Created):

{
  "id": "c1a2e3d4-5b6f-7890-abcd-ef1234567890",
  "name": "Production Server",
  "clientId": "a7b1c2d3e4f56789abcdef0123456789",
  "secret": "3f8c2a105b4e4d8a9c1f2e7a8b6d4f906fa6c1a2e3d4b5c6",
  "scopes": ["Patient.read", "Observation.read", "Observation.write"],
  "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:

ScopePermission
Patient.readRead Patient resources
Patient.writeCreate/update/delete Patients
Patient.*All Patient operations
*.readRead all resources
*Full access

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": ["launch-ehr", "client-public", "client-confidential-symmetric", "sso-openid-connect"],
  "scopes_supported": ["openid", "fhirUser", "patient/*.read", "patient/*.write", "user/*.read", "system/*.read"]
}

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

ScopeAccess
patient/*.readRead all resources for the in-context patient
patient/*.writeWrite resources for the in-context patient
user/*.readRead resources accessible to the current user
system/*.readSystem-level read (for backend services)
openidOpenID Connect identity token
fhirUserCurrent user FHIR resource reference

Quick Reference

MethodWhen to UseHeader
JWTUser sessions, internal appsAuthorization: Bearer token
API KeyServer to server, CLI toolsX-API-Key: clientId:secret
SMART on FHIRThird-party apps, user-delegated accessAuthorization: Bearer oauth_token

Next Steps

Now that you understand authentication, learn about the most important FHIR resource: Patient.