API Reference · API keys
API Reference

API keys: pf_ and 48 hex chars

Developer keys authenticate the public /v1 surface. They are issued and managed with your JWT, never expire on their own, and stop working the moment they are revoked.

POST/api-keysJWT Bearer

Issues a new key: the prefix pf_ followed by 48 hex characters (24 random bytes). No body required.

curl
curl -X POST http://localhost/api/api-keys \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
201 Created
{
  "apiKey": {
    "id": "cml4ka7cd0001jq8f9b2c4e6a",
    "userId": "cml4k9x2b0000jq8f3h5a1d2e",
    "key": "pf_9f2c4e6a8b0d1f3e5a7c9b8d7e6f5a4b3c2d1e0f9a8b7c6d",
    "createdAt": "2026-08-06T10:16:02.000Z"
  }
}
GET/api-keysJWT Bearer

Lists your keys, newest first — including the full key material for each.

curl
curl http://localhost/api/api-keys \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
200 OK
{
  "apiKeys": [
    {
      "id": "cml4ka7cd0001jq8f9b2c4e6a",
      "userId": "cml4k9x2b0000jq8f3h5a1d2e",
      "key": "pf_9f2c4e6a8b0d1f3e5a7c9b8d7e6f5a4b3c2d1e0f9a8b7c6d",
      "createdAt": "2026-08-06T10:16:02.000Z"
    }
  ],
  "total": 1
}
DELETE/api-keys/:idJWT Bearer

Revokes a key immediately. Requests using it start failing with 401 at once.

curl
curl -X DELETE http://localhost/api/api-keys/cml4ka7cd0001jq8f9b2c4e6a \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
# → 204 No Content
FieldTypeDescription
404ApiError“API key not found.” — also the response for keys owned by another account.

Keys are stored in plaintext today

Keys are stored and returned in full so they can be looked up directly and re-read later. Hash-at-rest with show-once semantics is a planned hardening pass — until it lands, treat every key like a password: keep it out of source control, logs, and client-side code, and revoke any key that touches something public.

Continue to the public v1 surface