Provisioning API
A management key manages keys and never spends. Where every other key on this API authenticates a request that consumes credit, a management key authenticates only the five calls below — creating, listing, reading, editing and revoking the keys in its own workspace — and is refused everywhere else, including chat completions and every other inference route, with the same permission error a plain key gets from these five. Mint one from your account page: choose Create key, select a workspace, and choose Management under Key type. Only the personal account owner or an organization admin can create or change a management key. Copy the full key when it appears; it is shown only once.
For the CLI, store the key with heimdall login --with-token < management-key.txt, then use
heimdall keys list, heimdall keys create or heimdall keys revoke. Use heimdall-staging for
the staging CLI. Keep the file private and remove it after importing the key. A management key
cannot authenticate ordinary account or inference commands; use a spending key for those.
A management key's spending-limit fields do not constrain the keys it creates. Set limits on each spending key and on its workspace or account. Revoking a management key stops its own access; keys it created remain active until separately revoked.
A key this API creates spends against the account the management key's own workspace draws from.
Its hash — the SHA-256 of the plaintext, never the plaintext itself — is what every route below
addresses it by.
POST /keys
Creates a key. limit and limit_reset set an optional spend ceiling, in the same UTC windows
GET /key reports. key carries the plaintext; it is returned once
and never stored.
curl https://api-staging.impossiblecarrot.cc/api/v1/keys \
-H "Authorization: Bearer $HEIMDALL_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "customer instance", "limit": "10", "limit_reset": "monthly"}'
{
"key": "sk-hd-v1-3f9a2c…",
"data": {
"hash": "9b1e4c7f2a5d8036…",
"name": "customer instance",
"label": "sk-hd-v1-3f9a…",
"disabled": false,
"limit": "10",
"limit_reset": "monthly",
"usage": "0",
"created_at": "2026-08-16T11:59:31.000Z",
"updated_at": "2026-08-16T11:59:31.000Z"
}
}
GET /keys
Every key in the management key's own workspace, newest first.
curl https://api-staging.impossiblecarrot.cc/api/v1/keys \
-H "Authorization: Bearer $HEIMDALL_MANAGEMENT_KEY"
{ "data": [{ "hash": "9b1e4c7f2a5d8036…", "name": "customer instance", "disabled": false, "…": "…" }] }
GET /keys/:hash
One key, by the hash POST /keys or GET /keys reported for it.
curl https://api-staging.impossiblecarrot.cc/api/v1/keys/<KEY_HASH> \
-H "Authorization: Bearer $HEIMDALL_MANAGEMENT_KEY"
PATCH /keys/:hash
Every member is optional; at least one is required. disabled: true revokes the key exactly as
DELETE does.
curl -X PATCH https://api-staging.impossiblecarrot.cc/api/v1/keys/<KEY_HASH> \
-H "Authorization: Bearer $HEIMDALL_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"limit": "25", "limit_reset": "weekly"}'
DELETE /keys/:hash
Revokes the key: the row stays, its ledger attribution intact, and it stops authenticating. Idempotent — revoking an already-revoked key answers the same way, and the account page shows the revocation.
curl -X DELETE https://api-staging.impossiblecarrot.cc/api/v1/keys/<KEY_HASH> \
-H "Authorization: Bearer $HEIMDALL_MANAGEMENT_KEY"
{ "data": { "success": true } }
Fields
| Field | Type | Notes |
|---|---|---|
hash | string | SHA-256 of the plaintext. The identifier every route addresses a key by. |
name | string | The label given at creation, or the latest PATCH. |
label | string | The display prefix — sk-hd-v1- plus six characters. Never the full key. |
disabled | boolean | true once revoked. |
limit | string | null | Spend ceiling as an exact decimal USD string, or null for none. |
limit_reset | string | null | daily, weekly or monthly (UTC windows), or null for a lifetime ceiling. |
usage | string | Lifetime settled spend attributed to the key, an exact decimal USD string. |
created_at | string | ISO 8601. |
updated_at | string | ISO 8601, of the latest change. |
GET /auth/key
Answers exactly what GET /key answers, at the path a Bifrost
OpenRouter provider validates a key against before it routes anything. A management key is refused
here the same way it is refused on /key: this path reports what a spending key has done, and a
management key has none.