Control API
Introduction
The Control API manages Capacity budgets, the pools on them, pool keys,
and pool Metrics from your tools. It lives on your nthbouncer host (for
example https://nthbouncer.com), not on api.nthpool.cloud.
The API token is not a pool key. It never admits traffic on the proxy.
It is also not how AI assistants connect. Those use the MCP server at
https://nthbouncer.com/mcp. See Agents for how to add that URL
in Claude or Cursor. There is no token to paste. Use an API token for CI,
scripts, and infrastructure code, where a value in an environment variable is
the right shape.
Authentication
- Open Organization settings → API tokens.
- Create a token. Choose when it expires: 1 month, 6 months, or 1 year.
- Copy the plain token once. Send it as
Authorization: Bearer ….
Only owners and admins can create or revoke tokens. A token authenticates as
the person who created it in that organization. It can call the Control API
for every budget and pool on the org. Verb abilities still apply
(budgets:read, pools:read, pools:write, keys:write, metrics:read).
curl -sS "https://nthbouncer.com/api/v1/me" \
-H "Authorization: Bearer $NTHBOUNCER_CONTROL_TOKEN" \
-H "Accept: application/json"Endpoints
Pool path segments use the pool subdomain (the *.nthpool.cloud label).
| Method | Path | Ability | Purpose |
|---|---|---|---|
GET |
/api/v1/me |
(any valid token) | Current user, team, abilities |
GET |
/api/v1/budgets |
budgets:read |
List granted budgets |
GET |
/api/v1/budgets/{id} |
budgets:read |
Budget detail |
GET |
/api/v1/budgets/{id}/pools |
pools:read |
Pools under that budget |
GET |
/api/v1/pools |
pools:read |
List granted pools |
GET |
/api/v1/pools/{subdomain} |
pools:read |
Pool detail |
POST |
/api/v1/pools/{subdomain}/keys |
keys:write |
Mint a pool key |
DELETE |
/api/v1/pools/{subdomain}/keys/{id} |
keys:write |
Revoke a pool key |
GET |
/api/v1/pools/{subdomain}/metrics |
metrics:read |
Admit / queue / reject series |
Create pools and attach them to Capacity budgets in the dashboard. The Control API lists budgets and their member pools; it does not create pools under a budget.
Mint a pool key (optional TTL)
curl -sS -X POST "https://nthbouncer.com/api/v1/pools/$POOL_SUBDOMAIN/keys" \
-H "Authorization: Bearer $NTHBOUNCER_CONTROL_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"label":"session","expires_preset":"1h"}'expires_preset accepts none, 1h, 24h, or 7d. You may send expires_at
(ISO-8601) instead. The raw key is returned once.
Session runs should prefer a TTL. Project keys in a repo skill may omit expiry.
Key access
POST /v1/pools/{pool}/keys accepts access:
| Value | Methods admitted |
|---|---|
write (default) |
Every method |
read |
GET, HEAD, OPTIONS, plus any methods the pool treats as reads |
A read-only key is refused with 403 on any other method, before the request
reaches your origin and before it takes a concurrency slot. The response
includes access and allowed_methods so a caller can check what it holds.
When the pool scopes extra read methods to path prefixes, the response also
includes read_paths, keyed by method ({ "POST": ["/services/rest/query/"] }).
Omitting access keeps the previous behavior, so keys minted before this
existed are unchanged.
On a database pool, access: read and access: write
both connect as the read role. Method scope is not applied: every query is
POST. Writes are refused by Postgres, not by the key.
MCP
AI assistants use https://nthbouncer.com/mcp, not this token. Connection
steps are on Agents. Tools and session keys are on
MCP server.
Related
- OpenAPI 3.1 spec
- Agents
- MCP server
- Reuse one pool across agent runs
- Access
- Concurrency locks (lock API on
api.nthpool.cloud)