Contract snapshot 0.101.0 · Deployment and client release availability follow the integration note for your environment.
Create only the access you need
Choose the minimum scopes required by the workflow and a useful key name. Minting requires the permissions specified by the connected contract. The create response contains the secret; display it only to the authorised caller.
Prepare the first organisation key
An organisation administrator can use POST /v1/keys/first with a session and no body. It makes the first key once, with data:read and usage:read scopes and 90-day expiry. Later calls reuse it with secret:null, even if expired or revoked. Never retry a write automatically or persist its one-time secret.
List without exposing secrets
Use the key listing for metadata and lifecycle state. Do not reconstruct a key from its prefix or store a displayed secret in analytics.
Revoke deliberately
A revoked key can no longer authorise requests. Confirm which workflow uses the key before revoking it, and handle failed writes without automatically repeating them.
Plan a rotation before revocation
Identify the server or workflow using the existing key. Create replacement access through the authorised process, update the server’s secret store and verify a bounded read before retiring the old key. Do not paste the replacement into a client bundle or a support conversation to test it.
Show lifecycle state clearly
A management screen should distinguish a listed key’s metadata from the secret shown at creation. Show scope and revocation state from the server response. If a create request times out, inspect the known key inventory before repeating it; the absence of a visible success message does not prove that no key was created.
POST
/v1/keys/first
Get your organisation's first API key, made once
For the dashboard's Start page (D-1601). The first call for an organisation with no key makes one ("First key", scopes data:read and usage:read, 90 days) and answers with `created: true` and its secret, shown once and never again: only its SHA-256 is stored. Every later call, at the same moment or after, answers with the same key, `created: false` and `secret: null`; if the organisation already had keys (made with createKey), it answers with the oldest of them, `created: false` and `secret: null`, and makes nothing. Always 200: `created` says which. It never makes a second key, even when the first is revoked or expired: use createKey for more. No request body. Organisation admins only, with a session, like createKey: a member or an API key gets `forbidden`. Sent with Cache-Control: no-store.
| Status | Meaning |
|---|---|
| 200 | Success |
| 401 | Error. The `error.code` is one of: - `session_expired`: retry advice `refresh_credentials` - `unauthenticated`: retry advice `refresh_credentials` |
| 403 | Error. The `error.code` is one of: - `forbidden`: retry advice `never` - `org_missing`: retry advice `never` |
| 429 | Error. The `error.code` is one of: - `rate_limited`: retry advice `after_reset` |
| 500 | Error. The `error.code` is one of: - `internal`: retry advice `bounded` |
| 503 | Error. The `error.code` is one of: - `unavailable`: retry advice `bounded` |
Full response fields and reusable schemas are in the downloadable OpenAPI contract.
POST
/v1/keys
Mint an API key for your organisation
Organisation admins only, signed in with a session (an API key cannot mint keys). The secret is in this response and nowhere else: only its SHA-256 is stored. The response is sent with Cache-Control: no-store.
Request body schema
{
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateKeyRequest"
},
"example": {
"name": "pricing agent",
"scopes": [
"data:read"
],
"expiresInDays": 30
}
}
}
}| Status | Meaning |
|---|---|
| 201 | Success |
| 400 | Error. The `error.code` is one of: - `invalid_json`: retry advice `fix_request` - `invalid_request`: retry advice `fix_request` |
| 401 | Error. The `error.code` is one of: - `session_expired`: retry advice `refresh_credentials` - `unauthenticated`: retry advice `refresh_credentials` |
| 403 | Error. The `error.code` is one of: - `forbidden`: retry advice `never` - `org_missing`: retry advice `never` |
| 413 | Error. The `error.code` is one of: - `payload_too_large`: retry advice `fix_request` |
| 415 | Error. The `error.code` is one of: - `unsupported_media_type`: retry advice `fix_request` |
| 429 | Error. The `error.code` is one of: - `rate_limited`: retry advice `after_reset` |
| 500 | Error. The `error.code` is one of: - `internal`: retry advice `bounded` |
| 503 | Error. The `error.code` is one of: - `unavailable`: retry advice `bounded` |
Full response fields and reusable schemas are in the downloadable OpenAPI contract.
GET
/v1/keys
List your organisation's API keys
Any signed-in member. Newest first, including expired and revoked keys. Never returns a secret, only its first 12 characters (`prefix`).
| Status | Meaning |
|---|---|
| 200 | Success |
| 401 | Error. The `error.code` is one of: - `session_expired`: retry advice `refresh_credentials` - `unauthenticated`: retry advice `refresh_credentials` |
| 403 | Error. The `error.code` is one of: - `forbidden`: retry advice `never` - `org_missing`: retry advice `never` |
| 429 | Error. The `error.code` is one of: - `rate_limited`: retry advice `after_reset` |
| 500 | Error. The `error.code` is one of: - `internal`: retry advice `bounded` |
| 503 | Error. The `error.code` is one of: - `unavailable`: retry advice `bounded` |
Full response fields and reusable schemas are in the downloadable OpenAPI contract.
POST
/v1/keys/{id}/revoke
Revoke an API key
Organisation admins only, with a session. Takes effect on the next request. Revoking twice is harmless and keeps the first revocation time. A key of another organisation, or no such key, is `not_found`: the API never confirms that it exists. Keys are never deleted.
Parameters
[
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
]| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Error. The `error.code` is one of: - `invalid_request`: retry advice `fix_request` |
| 401 | Error. The `error.code` is one of: - `session_expired`: retry advice `refresh_credentials` - `unauthenticated`: retry advice `refresh_credentials` |
| 403 | Error. The `error.code` is one of: - `forbidden`: retry advice `never` - `org_missing`: retry advice `never` |
| 404 | Error. The `error.code` is one of: - `not_found`: retry advice `fix_request` |
| 429 | Error. The `error.code` is one of: - `rate_limited`: retry advice `after_reset` |
| 500 | Error. The `error.code` is one of: - `internal`: retry advice `bounded` |
| 503 | Error. The `error.code` is one of: - `unavailable`: retry advice `bounded` |
Full response fields and reusable schemas are in the downloadable OpenAPI contract.