Anything that talks to the PrivateMind API (a script, a notebook, your own backend, the OpenAI SDK) does it with a key minted from Settings → API. The same page also surfaces live usage, rate limits, and the model catalogue your key can call.
This page covers the lifecycle from the UI side. For the wire format and how to attach a key to requests, see Authentication.
Where the page lives
Open the app, then Settings → API (or /settings/api-keys). You see three things at once:
- a row of stat cards: active / expired / revoked counts, plus total requests, tokens, and spend across every key you own
- a searchable table of your keys with their status, rate limit, allowed models, usage, and expiry
- a model reference panel on the right showing what your org can actually invoke today
The page is yours alone. Other users in your org have their own keys, their own counters, their own table.
Creating a key
Click Create Key. Fill in:
- Description: required, up to 120 characters. Shows up later as the name in the table. Use something you'd recognise three months from now (
Python trading bot,nightly summariser), nottest. - Expiration: 30 days, 90, 6 months, 1 year, 2 years, or 10 years. The key stops working the moment it expires; there is no grace period.
- Rate limit: requests per minute, from 10 to 600. Enforced per-key with a sliding window. Going over returns
429. - Budget (USD): optional spend cap. Leave empty for unlimited. Every chat, embedding, and tool call is priced and deducted; when the key's spend hits this number, further calls return
402until you raise the cap or mint a new key. - Allowed models: optional allowlist. Check none to mean "every model my org can call". Check some to lock this key to that subset. The list is your org's actual entitlement, not the global catalogue, so you can't accidentally grant something you don't own.
Click Create Key. A dialog reveals the secret.
The full bearer token has the shape <access_key_id>:<secret>. See Authentication for what to do with it.
Reading the table
Each row tells you everything you need to know about one key:
- Key: the description you gave it and the prefix (first 12 chars of the access key id). The full id stays hidden; the secret is never shown again at all.
- Status: Active, Expired (passed
expiration_datebut not revoked), or Revoked. - Rate: requests per minute the key is capped at.
- Models: first two allowed models inline, plus
+Nif more, orAllif none are set. - Usage: running totals: requests and tokens since the key was minted.
- Expires: the date. If the key has 30 days or less left, the cell turns yellow and shows the day count.
Click any row to open a detail dialog with the breakdown: full request/token/rate/spend stats, a budget bar if a cap is set, the full list of allowed models, created/expires/last-IP/permission metadata, and a copy-pasteable Python snippet pre-filled with that key's access id.
The Test Key button at the top of the page checks a pasted key by running a small request to GET /v1/models.
Rotating
There is no in-place rotation. The pattern is mint-new-then-revoke-old:
- Create a new key with the same scope (description, models, rate, budget).
- Roll it out to your client (environment variable, secret manager, whatever ships your secrets).
- Confirm the new key is serving traffic (the old key's request counter stops growing; the new key's starts).
- Revoke the old key.
The two keys can run in parallel for as long as you like. There's no shared per-user quota that splits between them; each key has its own rate limit and budget.
Revoking
Click the trash icon on a key's row (or Revoke in the detail dialog). A confirmation prompt asks you to type the key's name to confirm.
Revocation is immediate and permanent. The next request from that key returns 401. There is no undo; if you revoke a key you still need, mint a new one.
Budgets, rate limits, and what your key inherits
Three things govern what a key can do, and they compose:
| Layer | Limit | Returns when hit |
|---|---|---|
| Per-key rate limit | rate_limit_rpm from the create dialog |
429 |
| Per-key budget | budget_usd from the create dialog (optional) |
402 |
| Per-key allowed models | allowed_models from the create dialog (optional) |
403 on the disallowed model |
| Org-level model entitlement | Set by your org admin in Settings → Org | 403 if your org doesn't own the model |
| Org-level monthly budget | Set by your org admin; visible on Account Settings | 402 once org spend exceeds it |
The most restrictive layer applies. A key with no budget can still be stopped by the org budget; a key allowed every model can still be blocked from one your org isn't entitled to.
Per-call cost is included on every chat and embedding response in the usage block. See Rate limits & budgets for how to read it.
Verifying a key
The quickest check is the Test Key button on the page. Or, from the shell:
curl -s -o /dev/null -w "%{http_code}\n" \
"https://api.privatemind.com/v1/models" \
-H "Authorization: Bearer $PMIND_KEY"200: the key is valid, active, and your org can list models. 401: bad credentials or revoked. 403: your org has zero entitled models, which usually means a fresh org without an admin assignment yet.
Where next
- Authentication: the bearer-token format and how to attach a key to a request
- Rate limits & budgets: what
429and402actually look like, and how to read per-call cost - Account settings: your profile, org info, and monthly budget
- My usage: spend, activity heatmap, and history rollups for everything across your keys