ClinikAPI authenticates every request using a secret API key passed in the x-api-key header. There are no OAuth flows or session tokens to manage — you create keys in the Developer Dashboard, store them in environment variables, and include them on every server-side request.
API keys
Keys are created in the Developer Dashboard. Each key is tied to your organization and environment:
| Format | Environment | Use case |
|---|
clk_test_* | Test | Development, staging, CI/CD |
clk_live_* | Production | Live patient data |
Pass your key in the x-api-key request header:
curl -X GET https://api.clinikehr.com/v1/patients \
-H "x-api-key: clk_test_abc123def456"
When you use the SDK, the key is read once at initialization and attached to every request automatically.
ClinikAPI is a data API
ClinikAPI does not handle end-user authentication. You bring your own auth provider — Supabase, Clerk, Auth0, Firebase, or any other — and use ClinikAPI purely for clinical data storage and retrieval.
Patient (browser) → Your auth (Supabase / Clerk) → Your backend → ClinikAPI SDK → ClinikAPI
Your backend authenticates the end user with your auth provider, then calls ClinikAPI with your secret key. The SDK runs on your server only — your API key is never sent to the browser.
For frontend UI, use @clinikapi/react with the proxy pattern. React components make requests to your backend, which forwards them to ClinikAPI. See the React components overview for setup instructions.
Tenant isolation
Every resource stored in ClinikAPI is automatically tagged with your organization’s tenant ID at the FHIR level:
{
"meta": {
"tag": [
{
"system": "https://clinikapi.com/tenant",
"code": "org_abc123"
}
]
}
}
Tenant enforcement is automatic and cannot be bypassed:
- On create — the tenant tag is automatically injected before the resource is written to HealthLake
- On search — a
_tag filter is automatically applied; you only see resources belonging to your organization
- On read, update, and delete — ownership is verified before the operation proceeds
There is no way to access another tenant’s data through the API.
Multi-datastore routing
Requests are routed to different AWS HealthLake datastores based on your key type and plan:
| Key type | Plan | Datastore |
|---|
clk_test_* | Any | Shared test datastore |
clk_live_* | Sandbox / Starter / Pro / Team | Shared production datastore |
clk_live_* | Enterprise | Dedicated datastore |
Enterprise customers receive a fully isolated HealthLake datastore provisioned in their preferred AWS region.
Key scopes
When creating a key in the Dashboard, you can restrict it to specific operation types:
read — GET operations only
write — POST, PATCH, and DELETE operations
* — full access (default)
Use scoped keys to limit the blast radius of a compromised credential. For example, an analytics service that only reads data should use a read-scoped key.
Security best practices
Never expose your API key in client-side code, Git repositories, or application logs. Anyone with your key can read and write clinical data on behalf of your organization.
- Store keys in environment variables (
CLINIKAPI_SECRET_KEY) — never hard-code them
- Use
clk_test_* keys for development — they route to an isolated test datastore with no production data
- Rotate keys periodically from the Dashboard; revoked keys stop working immediately
- Use scoped keys where possible (for example,
read-only for analytics or reporting services)
- For client-side UI, use
@clinikapi/react with the proxy pattern so your secret key stays on the server