Authorization: Bearer <key> header or as an x-api-key: <key> header — both are accepted and equivalent. Pick one; if both are present, the Authorization header wins.
Every key starts with the prefix
dai_sk_. The dashboard’s session cookie auth (/api/v1/auth/me, /api/v1/auth/verify) is for the web UI only — programmatic access always uses API keys.Key scopes
Scope controls what data a key can see. It’s set at creation time and is immutable.| Scope | What it sees | When to use |
|---|---|---|
global | Everything in the org | SDK init for an app that spans multiple workspaces; the only scope that can create or revoke other keys |
workspace | One workspace (specified at create time) | CI key for one team’s repo |
project | One project under a workspace | Per-environment keys (dev / staging / prod) |
Key permissions
Permissions control what actions a key can take, orthogonal to scope. Default isadmin for backwards compatibility.
| Permission | Allowed methods |
|---|---|
read | GET only |
write | GET + POST / PUT / PATCH (ingest, register, attach) |
admin | All of the above + DELETE / destructive ops |
write. An SRE read-only on-call key should be read. Use admin only for keys that need to delete data.
Expiration
Keys can optionally expire. Pass an ISO-8601expires_at when creating; omit for a non-expiring key (the historical default).
Once expired, requests return 401 with the response body {"detail": "API key has expired"} — a distinct detail string from the revoked-key case (also 401, {"detail": "API key has been revoked"}), so callers can prompt regeneration without a generic “auth failed” branch. Both are authentication failures, so they share the 401 status with a missing or malformed key; the detail string is what distinguishes them.
Creating a key
From the dashboard
- Sign in to the DecimalAI Dashboard
- Go to Settings → API Keys
- Click Create API Key, choose scope, permissions, and optional expiry
- Copy the key — it’s shown only once and stored as a SHA-256 hash on the server
Programmatically
Requires an existingglobal-scoped key with admin role (only global keys can mint other keys):
A security-alert email goes to the org’s billing contact when a new key is created. If you didn’t expect it, revoke immediately.
Listing keys
created_at, and last_used_at for each key. Raw keys are never returned. Only global-scoped keys can list.
last_used_at is updated as a fire-and-forget UPDATE on every successful auth — use it to surface stale-but-not-revoked keys for cleanup.
Rotating a key
There’s no in-place rotation. To rotate:
The last step is the only way to know rotation is complete — if
last_used_at is still climbing, something still has the old key.
Revoking a key
POST.
Security checklist
- Never commit keys to source control. Use environment variables or a secret manager.
- Use the narrowest scope and permissions that work. A CI key that only sends traces should be
workspace/write, notglobal/admin. - Set
expires_aton keys handed to humans. Long-lived keys without expiry should belong to automated systems with rotation procedures. - Audit
last_used_atquarterly. Revoke anything that hasn’t been used in 90 days. - Lost a key? Revoke first, regenerate second. The new key won’t have the old key’s
id— update any infra that pins to it.