API key format, scopes, and key management endpoints
Authentication
9thSense uses API key authentication. Every request (except open paths) must include the X-Api-Key header.
X-Api-Key: zk_a1b2c3d4_e5f6a7b8c9d0e1f2a3b4c5d6
Key Format
New keys follow the split-key pattern:
zk_<prefix>_<secret>
zk— fixed literal prefix<prefix>— 12-character hex token stored in plaintext for fast index lookup<secret>— 32-character hex token; the full keyzk_<prefix>_<secret>is verified with bcrypt
This approach allows O(1) DB lookup by prefix while never storing the secret in recoverable form.
Legacy keys (SHA-256 hashed, no prefix) are still accepted for backward compatibility. New keys should always use the split-key format.
Scopes
Each key is granted one or more scopes that control which endpoints it can call:
| Scope | Description |
|---|---|
read | Read-only access: list, get, search, export, analytics |
write | Mutation access: create, update, delete, deploy, run pipelines |
admin | Key management: create, list, revoke API keys |
Most production integrations need read + write. Admin access is restricted to key management endpoints only.
Key Management
Create API Key
POST /v1/admin/keysendpointRequires scope: admin
Request body:
tenant_idstringrequiredThe tenant this key will authenticate as.
namestringrequiredHuman-readable label for the key (e.g. "Production Integration").
scopesstring[]requiredList of scopes to grant. Values: "read", "write", "admin".
Example request:
{
"tenant_id": "acme-corp",
"name": "Production Integration",
"scopes": ["read", "write"]
}
Example response (201):
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tenant_id": "acme-corp",
"name": "Production Integration",
"scopes": ["read", "write"],
"raw_key": "zk_a1b2c3_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
"last_used": null,
"revoked": false,
"created_at": "2026-03-25T10:00:00Z"
}
The raw_key field is returned only once at creation time. Store it securely — it cannot be retrieved again.
List API Keys
GET /v1/admin/keysendpointRequires scope: admin
Query parameters:
tenant_idstringFilter keys by tenant. Defaults to the authenticated tenant.
Example response (200):
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tenant_id": "acme-corp",
"name": "Production Integration",
"scopes": ["read", "write"],
"last_used": "2026-03-24T18:30:00Z",
"revoked": false,
"created_at": "2026-03-20T09:00:00Z"
}
]
The raw_key is never included in list responses.
Revoke API Key
DELETE /v1/admin/keys/{key_id}endpointRequires scope: admin
Path parameters:
key_idstringrequiredUUID of the key to revoke.
Returns 204 No Content on success. Returns 404 if the key does not exist or is already revoked.
Error Responses
| Status | Detail |
|---|---|
401 Missing X-Api-Key header | No key provided |
401 API key invalid | Key not found in database |
401 API key revoked | Key has been revoked |
403 Insufficient scope | Key lacks the required scope for the endpoint |