keys
Scoped API keys for programmatic access (CLI / MCP / SDK)
GET /v1/keys
List my API keys
Metadata only — key material is never returned after creation. Revoked keys stay listed with revoked_at set so audit history keeps resolving. Newest first.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer | Page size. |
cursor | query | string | Opaque cursor from the previous page's |
Responses
| Status | Description | Body |
|---|---|---|
200 | Page of API keys. | ApiKeyPage |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
POST /v1/keys
Create an API key
Mints a scoped programmatic key. The plaintext key (lucen_sk_...) is returned once, in this response, and never again — only an argon2 hash is stored. Requested scopes must be a subset of what the caller can grant (read ⊂ write ⊂ train); the redundant lower scopes may be omitted since they are implied. daily_gpu_hour_quota, when set, caps the GPU hours this key may reserve on priced executors per 24 h, inside the account's own RUN_DAILY_GPU_HOUR_QUOTA (createRun).
Request body
| Field | Type | Description |
|---|---|---|
name | string | |
scopes | array of ApiKeyScope | |
daily_gpu_hour_quota | number | null |
Responses
| Status | Description | Body |
|---|---|---|
201 | Key created; | ApiKeyCreated |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
422 | Request failed validation. | Problem |
DELETE /v1/keys/{key_id}
Revoke an API key
Revocation takes effect on the next request and cannot be undone. The row is retained (audit rows point at it); it keeps appearing in GET /v1/keys with revoked_at set. Idempotent — revoking an already-revoked key is still 204.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
key_id | path | Id | API key id ( |
Responses
Schemas (5)
The schemas these operations reach before any other tag’s do. A type that links elsewhere is rendered on that tag’s page.
ApiKeyPage
| Field | Type | Description |
|---|---|---|
items | array of ApiKey | |
next_cursor | string | null |
ApiKeyCreate
| Field | Type | Description |
|---|---|---|
name | string | |
scopes | array of ApiKeyScope | |
daily_gpu_hour_quota | number | null |
ApiKeyCreated
A freshly minted key. key is the plaintext secret and is present only in this response — store it now; the server keeps an argon2 hash and cannot show it again.
| Field | Type | Description |
|---|---|---|
id | Id | |
name | string | |
key_prefix | string | |
scopes | array of ApiKeyScope | |
daily_gpu_hour_quota | number | null | |
last_used_at | string (date-time) | null (date-time) | |
revoked_at | string (date-time) | null (date-time) | |
created_at | string (date-time) | |
key | string | The plaintext key — |
ApiKey
API key metadata. The secret itself is never returned here.
| Field | Type | Description |
|---|---|---|
id | Id | |
name | string | Human label shown in the settings UI. |
key_prefix | string | Display fragment of the key ( |
scopes | array of ApiKeyScope | Scopes as granted (implied lower scopes are not expanded). |
daily_gpu_hour_quota | number | null | Per-key daily GPU-hour cap. Stored from M2, enforced from M7; |
last_used_at | string (date-time) | null (date-time) | Last time this key authenticated a request. |
revoked_at | string (date-time) | null (date-time) | Set once revoked; a revoked key authenticates nothing. |
created_at | string (date-time) |
ApiKeyScope
Granted scope. Hierarchical: write implies read, train implies write.