API keys

Create, list, rotate, and revoke sk-coco-* API keys — from the app or programmatically.

Last updated

API keys are how external clients authenticate to Cocobox. This page covers both the app workflow and the management endpoints.

Create a key in the app

  1. Open Settings → API keys.
  2. Click Create new key.
  3. Give it a descriptive name (e.g. laptop-opencode, ci-bot).
  4. (Optional) Restrict to specific models, set a request budget, toggle tools_enabled.
  5. Click Create. The full secret appears with a Copy button.

Create a key programmatically

You authenticate the meta-CRUD endpoints with your user session (Auth0 JWT) — not with another API key. This is intentional: managing keys is something a human does from a logged-in context.

POST https://api.cocobox.io/api-keys Authenticated with Authorization: Bearer <Auth0 JWT>

Request body

Field Type Description
name
required
string Human-readable label. Must be non-empty after trimming.
allowedModels
optional
string[] Array of model aliases this key may call (e.g. ["tambor","sonnet"]). Empty = unrestricted.
requestBudget
optional
number | null Lifetime cap on requests. Once requestsUsed equals this, requests return 429. null = unlimited.
toolsEnabled
optional
boolean Whether the key may invoke MCP tools.
Default: true

Response (201)

{
  "id": 42,
  "name": "laptop-opencode",
  "keyPrefix": "sk-coco-7c4f1a2e",
  "allowedModels": ["tambor", "sonnet"],
  "requestBudget": null,
  "requestsUsed": 0,
  "toolsEnabled": true,
  "isActive": true,
  "lastUsedAt": null,
  "key": "sk-coco-7c4f1a2e3b8d9a4c6f5e1d2b3a8c9d0e"
}

The key field appears only on creation. Subsequent reads omit it and return only the prefix.

List your keys

GET https://api.cocobox.io/api-keys Authenticated with Authorization: Bearer <Auth0 JWT>

Returns an array of key objects in reverse chronological order (newest first). Never includes the full secret — only keyPrefix for display.

[
  {
    "id": 42,
    "name": "laptop-opencode",
    "keyPrefix": "sk-coco-7c4f1a2e",
    "allowedModels": ["tambor", "sonnet"],
    "requestBudget": null,
    "requestsUsed": 318,
    "toolsEnabled": true,
    "isActive": true,
    "lastUsedAt": "2026-04-30T14:22:11.000Z"
  }
]

Update a key

PATCH https://api.cocobox.io/api-keys/:id Authenticated with Authorization: Bearer <Auth0 JWT>

All fields are optional; only provided ones are updated.

Field Type Description
name
optional
string Rename the key.
allowedModels
optional
string[] Replace the model allowlist.
requestBudget
optional
number | null Raise, lower, or remove the lifetime cap.
toolsEnabled
optional
boolean Toggle MCP tool access.
isActive
optional
boolean Disable the key without deleting it. Disabled keys return 401 key_inactive.

The hash is never rotated by PATCH. To change the secret, create a new key and revoke the old one.

Revoke a key

DELETE https://api.cocobox.io/api-keys/:id Authenticated with Authorization: Bearer <Auth0 JWT>

Hard-deletes the key. Within ~1 second, every node returns 401 for that key. The audit log retains the deletion event indefinitely.

If you only want to pause a key, prefer PATCH … { "isActive": false } — that’s reversible.

Rotation playbook

# 1. Create new key with same scopes
curl https://api.cocobox.io/api-keys \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "laptop-opencode (rotated 2026-05-01)",
    "allowedModels": ["tambor","sonnet"],
    "toolsEnabled": true
  }'

# 2. Roll the new key into your secret store, deploy, smoke-test.

# 3. Watch the old key's lastUsedAt go stale (Settings → API keys).

# 4. Revoke the old key.
curl -X DELETE https://api.cocobox.io/api-keys/41 \
  -H "Authorization: Bearer $JWT"

Audit trail

Every create / update / delete on a key writes to your workspace audit log, including the actor, IP, and the set of fields changed. Logged-in human actions and machine actions are both captured. See Audit log.