krn_ prefix and are hashed before storage — the raw key is only shown once at creation time.
The two API planes
The platform API is split into two planes:Key scopes
Every API key carries ascopes field — a JSON array of permission strings set at creation time and never changed afterwards.
A key without the required access gets an HTTP
403 with this body:
Defined scopes
Keep
control-plane keys internal — treat them like server credentials.
Never embed one in a client app, mobile app, or browser code. Ship
data-plane-only keys (the default) to anything customer-facing.API_KEY env var) and cron/webhook secrets are internal infrastructure, not customer keys — they are unaffected by scopes.
POST /api/v1/api-keys
Generate a new API key. Admin only.Request Body
Example — data-plane key (default)
Example — control-plane key (management access)
Example — SCIM-scoped key
Response (201)
GET /api/v1/api-keys
List all active (non-revoked) API keys for the tenant. Returns prefixes and scopes — not the full key. Admin only.Response
DELETE /api/v1/api-keys?id=
Revoke an API key (soft delete). The key immediately stops working. Admin only.Query Parameters
Request Body (optional)
Response
204 No Content on success.