---
title: "Mint a managed agent key"
method: POST
path: "/v1/agent-keys"
tags: ["agent-keys"]
---

# Mint a managed agent key

`POST /v1/agent-keys`

## Request

- Base URL: `https://api.bubblio.dev`
- URL: `https://api.bubblio.dev/v1/agent-keys`
- Auth: HTTP bearer

Called by the PLATFORM'S SERVER (the SDK's `mintAgentKey` / `createAgentKeyRoute`).
`ctx` is the platform-signed user-context JWT — Bubblio checks WELL-FORMEDNESS ONLY
(three dot-separated base64url segments) and can neither verify nor forge it (it
stores only a hash of the API key the signing secret derives from). Custody rules:
the raw `bak_` key is returned ONCE and stored SHA-256; the ctx is encrypted at
rest immediately and never logged.

`max_active_per_user` (#49) is the opt-in per-user active-key quota, enforced
INSIDE the mint: a pre-check refuses the common at-cap case before any write, and
the post-insert count is the race-proof enforcement — concurrent mints can fail
CLOSED (a spurious 409 a retry resolves) but can never overshoot the cap, PROVIDED
every concurrent mint for that user carries the cap (the SDK's
`createAgentKeyRoute` stamps it on every mint, grant path included). An UNCAPPED
rival mint commits outside the enforcement and is never rolled back, so mixing
capped and uncapped mints for one user can exceed the number the capped ones asked
for.

## Request body

- object
  - `ctx` string, required: The platform-signed user-context JWT (shape-checked only).
  - `label` string
  - `externalUserId` string
  - `userHint` string: Display-only, e.g. a masked email.
  - `max_active_per_user` integer: Requires externalUserId — the cap counts one user's active keys.

## Response `201`

The raw key — returned exactly once, never retrievable again.

- object
  - `key` string, required: bak_…
  - `id` string, uuid, required

## Other responses

- `400`: One calm sentence naming the malformed field.
- `409`: `code: key_cap_reached` — the user is at the requested cap (revoke a key or raise the cap); or `code: migration_pending` while the keys table lags.
- `429`: The per-customer mint ceiling (default 30/hour).

---

[API](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api.md) · [All operations](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api/revisions/d858aff9c01d?raw)
