---
title: "Create a new API key for a workspace the user owns/admins; returns the secret key exactly once."
method: POST
path: "/api/v1/api-keys"
tags: ["api-keys"]
---

# Create a new API key for a workspace the user owns/admins; returns the secret key exactly once.

`POST /api/v1/api-keys`

Cookie session only — never inspects Authorization header; pm_live_ Bearer NOT accepted. Caller must be admin or owner of workspaceId (workspace_members.role). Requested scopes are capped to deriveScopesFromRole(role); exceeding them is a 403. Billing-gated on the api_keys metric (403 with plan_limit_reached body). The secret 'key' (format pm_live_<64 hex chars>) is returned ONLY in this 201 response and can never be retrieved again — afterward only keyPrefix is exposed.

## Request body

- object
  - `name` string, required — Human label for the key.
  - `workspaceId` string, required — Workspace the key belongs to; caller must be admin/owner.
  - `scopes` string[] — Subset of read | write | admin. Defaults to ['read','write']. Must be non-empty and within the scopes the caller's role permits.

## Response `201`

Key created; secret 'key' returned once.

- object

## Other responses

- `400` — Missing name, missing workspaceId, empty/non-array scopes, or unrecognized scope values.
- `401` — No valid session cookie (API keys not accepted).
- `403` — Caller is not workspace admin/owner; requested scopes exceed role-derived scopes; OR billing limit reached (body { error:'plan_limit_reached', metric:'api_keys', current, limit, plan }).
- `429` — Rate limit exceeded (apiKeysWrite bucket, 20/h).
- `500` — Membership lookup failure, insert failure, or internal error.
- `503` — SUPABASE_SERVICE_ROLE_KEY not configured (admin client unavailable).

---

[API](https://skmtc.dev/pathmode/apis/pathmode-api.md) · [All operations](https://skmtc.dev/pathmode/apis/pathmode-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/pathmode/pathmode-api/revisions/e419abb0a327/schema)
