API Key Authentication
Last updated: 2026-02-18
This document defines server-to-server authentication for enterprise integrations.
1. Authentication model
Bounded Health enterprise APIs support two auth modes:
x-api-keyfor server-to-server integrations- Clerk session auth for browser/UI clients
Most enterprise routes are dual-mode. API-key calls must satisfy route scope requirements.
2. API key lifecycle endpoints
These endpoints are Clerk-authenticated admin flows for key management:
GET /api/employer/api-keys: list keys and available scopesPOST /api/employer/api-keys: create a new key (raw secret returned once)GET /api/employer/api-keys/{keyId}: read key metadataDELETE /api/employer/api-keys/{keyId}: revoke key
3. Key format and storage
- Key prefix:
mt_live_ - Raw key is shown once at creation and never stored
- Persisted value is SHA-256 hash only
- Per-key metadata includes:
- scope set
- optional CIDR allowlist
- optional expiration
- usage telemetry (
lastUsedAt,lastUsedIp,requestCount)
4. Available scopes
| Scope | Purpose |
|---|---|
cohort:read | Read cohort and patient roster data |
cohort:write | Upload and update cohort data |
export:read | Read export metadata and download exports |
export:create | Trigger export job creation |
simulate:run | Run simulation endpoints |
authorization:read | Read authorization workflows |
authorization:write | Review or update authorizations |
webhook:manage | Manage outbound webhook subscriptions |
sso:manage | Manage employer SSO/SCIM configuration |
fhir:read | Read FHIR resources |
fhir:write | Create/update FHIR resources |
5. Routes currently migrated to API keys
POST /api/employer/upload-cohortrequirescohort:writeGET /api/employer/exportrequiresexport:readGET /api/employer/export/pdfrequiresexport:readPOST /api/employer/export/csvrequiresexport:createGET /api/employer/export/csv/exports/{exportId}requiresexport:readGET /api/employer/export/csv/exports/{exportId}/downloadrequiresexport:readGET/POST/PATCH/DELETE /api/employer/webhooks*requireswebhook:manageGET/POST /api/employer/ssorequiressso:manageGET/POST /api/fhir/Patient,GET /api/fhir/Patient/{id},GET /api/fhir/CarePlanrequire FHIR scopes
6. Example calls
Create key (Clerk session):
http
POST /api/employer/api-keys
Content-Type: application/json
{
"name": "HRIS nightly sync",
"scopes": ["cohort:write", "export:read"],
"allowedIpCidrs": ["10.20.0.0/16"],
"expiresAt": "2027-01-01T00:00:00.000Z"
}
Server-to-server call:
bash
curl -X POST https://<host>/api/employer/upload-cohort \
-H "x-api-key: mt_live_***" \
-H "content-type: application/json" \
-d '{"patients":[{"email":"member@example.com","firstName":"A","lastName":"B"}]}'
7. Error model
Common API-key auth errors:
| Status | Code | Meaning |
|---|---|---|
401 | INVALID_API_KEY | Bad key format or unknown key |
401 | API_KEY_REVOKED | Key was revoked |
401 | API_KEY_INACTIVE | Key disabled |
401 | API_KEY_EXPIRED | Key expired |
403 | API_KEY_IP_NOT_ALLOWED | Caller IP outside allowlist |
403 | INSUFFICIENT_SCOPE | Key scope missing for endpoint |
429 | RATE_LIMITED | API-key rate limit exceeded |
8. Security requirements
- Never log raw API keys in client or server logs
- Use IP allowlists for production machine identities
- Rotate keys on a defined schedule (recommended: 90 days)
- Revoke keys immediately on suspected exposure
- Restrict scopes to minimum needed permissions
- Store raw keys in a managed secret store (not in source control)
9. Operational checklist
- Create one key per integration system (not shared across systems)
- Add monitoring on
401/403/429rates - Alert on repeated
API_KEY_IP_NOT_ALLOWEDevents - Validate key inventory monthly (active vs. expected)
- Confirm audit events are visible for
api_key.*actions
10. Operational automation
- Hourly integration anomaly alerts:
GET /api/cron/integration-alerts- Detects repeated
API_KEY_IP_NOT_ALLOWEDevents per employer. - Emits audit alert records and sends notification email when thresholds are crossed.
- Detects repeated
- Monthly API key inventory validation:
GET /api/cron/api-key-inventory-review- Compares active key count against expected bounds (
API_KEY_INVENTORY_EXPECTED_MIN/MAX). - Flags stale active keys and expiring keys, then records monthly review audit entries.
- Compares active key count against expected bounds (