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

  1. Open Organization settings → API tokens.
  2. Create a token. Choose when it expires: 1 month, 6 months, or 1 year.
  3. 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