Skip to main content

API Key Authentication

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-key for 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 scopes
  • POST /api/employer/api-keys: create a new key (raw secret returned once)
  • GET /api/employer/api-keys/{keyId}: read key metadata
  • DELETE /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

ScopePurpose
cohort:readRead cohort and patient roster data
cohort:writeUpload and update cohort data
export:readRead export metadata and download exports
export:createTrigger export job creation
simulate:runRun simulation endpoints
authorization:readRead authorization workflows
authorization:writeReview or update authorizations
webhook:manageManage outbound webhook subscriptions
sso:manageManage employer SSO/SCIM configuration
fhir:readRead FHIR resources
fhir:writeCreate/update FHIR resources

5. Routes currently migrated to API keys

  • POST /api/employer/upload-cohort requires cohort:write
  • GET /api/employer/export requires export:read
  • GET /api/employer/export/pdf requires export:read
  • POST /api/employer/export/csv requires export:create
  • GET /api/employer/export/csv/exports/{exportId} requires export:read
  • GET /api/employer/export/csv/exports/{exportId}/download requires export:read
  • GET/POST/PATCH/DELETE /api/employer/webhooks* requires webhook:manage
  • GET/POST /api/employer/sso requires sso:manage
  • GET/POST /api/fhir/Patient, GET /api/fhir/Patient/{id}, GET /api/fhir/CarePlan require 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:

StatusCodeMeaning
401INVALID_API_KEYBad key format or unknown key
401API_KEY_REVOKEDKey was revoked
401API_KEY_INACTIVEKey disabled
401API_KEY_EXPIREDKey expired
403API_KEY_IP_NOT_ALLOWEDCaller IP outside allowlist
403INSUFFICIENT_SCOPEKey scope missing for endpoint
429RATE_LIMITEDAPI-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/429 rates
  • Alert on repeated API_KEY_IP_NOT_ALLOWED events
  • 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_ALLOWED events per employer.
    • Emits audit alert records and sends notification email when thresholds are crossed.
  • 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.