{"openapi":"3.1.0","info":{"title":"nthbouncer Control API","version":"1.0.0","description":"Manage Capacity budgets, pools, pool keys, and metrics on nthbouncer. AI assistants normally use the MCP server at https:\/\/nthbouncer.com\/mcp instead."},"servers":[{"url":"https:\/\/nthbouncer.com"}],"tags":[{"name":"identity","description":"Token identity and granted abilities"},{"name":"budgets","description":"Capacity budgets shared across pools"},{"name":"pools","description":"Concurrency pools and keys"},{"name":"metrics","description":"Pool admit, queue, and reject series"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Organization Control API token from Settings \u2192 API tokens."}},"schemas":{"User":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"email":{"type":"string","format":"email"}},"required":["id","name","email"]},"Team":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"]},"Budget":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"pool_ids":{"type":"array","items":{"type":"integer"}},"origin_max_concurrent":{"type":"integer","nullable":true},"unallocated":{"type":"integer"}},"required":["id","name","pool_ids","origin_max_concurrent","unallocated"]},"PoolBudget":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"reserved_concurrent":{"type":"integer"}},"required":["id","name","reserved_concurrent"]},"Pool":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"subdomain":{"type":"string","description":"Pool label used in *.nthpool.cloud URLs and API paths."},"backend":{"type":"string","enum":["http","postgres"]},"max_concurrent":{"type":"integer"},"require_key":{"type":"boolean"},"has_credential":{"type":"boolean"},"budget":{"oneOf":[{"$ref":"#\/components\/schemas\/PoolBudget"},{"type":"null"}]}},"required":["id","name","subdomain","backend","max_concurrent","require_key","has_credential"]},"PoolKey":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":"string"},"last_four":{"type":"string"},"access":{"type":"string","enum":["read","write"]},"allowed_methods":{"type":"array","items":{"type":"string"}},"read_paths":{"type":"array","items":{"type":"string"}},"expires_at":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"key":{"type":"string","description":"Plaintext pool key returned once at creation."},"signing_secret":{"type":"string","description":"Signing secret returned once at creation when origin signing is enabled."}},"required":["id","label","last_four","access","allowed_methods"]},"PoolKeyCreateRequest":{"type":"object","properties":{"label":{"type":"string","maxLength":60},"expires_preset":{"type":"string","enum":["none","1h","24h","7d"],"description":"Key lifetime preset. Omit for no expiry."},"access":{"type":"string","enum":["read","write"],"description":"Omit for full write access (default)."}}},"MetricsRange":{"type":"object","properties":{"from":{"type":"string","format":"date-time","nullable":true},"to":{"type":"string","format":"date-time","nullable":true},"retention_days":{"type":"integer"},"clamped":{"type":"boolean"}},"required":["from","to","retention_days","clamped"]},"PoolMetricsSummary":{"type":"object","properties":{"pool_id":{"type":"integer"},"requests":{"type":"integer"},"admitted":{"type":"integer"},"admit_rate":{"type":"number"},"queued_count":{"type":"integer"},"queued_pct":{"type":"number"},"range":{"$ref":"#\/components\/schemas\/MetricsRange"}},"required":["pool_id","requests","admitted","admit_rate","queued_count","queued_pct","range"]},"Error":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}},"security":[{"bearerAuth":[]}],"paths":{"\/api\/v1\/me":{"get":{"operationId":"getCurrentIdentity","summary":"Current user, team, and token abilities","description":"Returns the authenticated user, their organization, and Sanctum token abilities.","tags":["identity"],"responses":{"200":{"description":"Identity payload","content":{"application\/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#\/components\/schemas\/User"},"team":{"$ref":"#\/components\/schemas\/Team"},"abilities":{"type":"array","items":{"type":"string"}}},"required":["user","team","abilities"]}}}},"401":{"description":"Missing or invalid token","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/api\/v1\/budgets":{"get":{"operationId":"listBudgets","summary":"List Capacity budgets","tags":["budgets"],"security":[{"bearerAuth":["budgets:read"]}],"responses":{"200":{"description":"Budget collection","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Budget"}}},"required":["data"]}}}}}}},"\/api\/v1\/budgets\/{budget}":{"get":{"operationId":"getBudget","summary":"Show a Capacity budget","tags":["budgets"],"parameters":[{"name":"budget","in":"path","required":true,"schema":{"type":"integer"}}],"security":[{"bearerAuth":["budgets:read"]}],"responses":{"200":{"description":"Budget","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/Budget"}},"required":["data"]}}}},"404":{"description":"Budget not found"}}}},"\/api\/v1\/budgets\/{budget}\/pools":{"get":{"operationId":"listBudgetPools","summary":"List pools on a budget","tags":["budgets","pools"],"parameters":[{"name":"budget","in":"path","required":true,"schema":{"type":"integer"}}],"security":[{"bearerAuth":["pools:read"]}],"responses":{"200":{"description":"Pool collection","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Pool"}}},"required":["data"]}}}}}}},"\/api\/v1\/pools":{"get":{"operationId":"listPools","summary":"List pools granted to this token","tags":["pools"],"security":[{"bearerAuth":["pools:read"]}],"responses":{"200":{"description":"Pool collection","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Pool"}}},"required":["data"]}}}}}}},"\/api\/v1\/pools\/{pool}":{"get":{"operationId":"getPool","summary":"Show a pool by subdomain","tags":["pools"],"parameters":[{"name":"pool","in":"path","required":true,"schema":{"type":"string"},"description":"Pool subdomain label."}],"security":[{"bearerAuth":["pools:read"]}],"responses":{"200":{"description":"Pool","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/Pool"}},"required":["data"]}}}},"404":{"description":"Pool not found"}}}},"\/api\/v1\/pools\/{pool}\/keys":{"post":{"operationId":"createPoolKey","summary":"Mint a pool key","tags":["pools"],"parameters":[{"name":"pool","in":"path","required":true,"schema":{"type":"string"},"description":"Pool subdomain label."}],"security":[{"bearerAuth":["keys:write"]}],"requestBody":{"required":false,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/PoolKeyCreateRequest"}}}},"responses":{"201":{"description":"Created pool key","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/PoolKey"}},"required":["data"]}}}}}}},"\/api\/v1\/pools\/{pool}\/keys\/{apiKey}":{"delete":{"operationId":"revokePoolKey","summary":"Revoke a pool key","tags":["pools"],"parameters":[{"name":"pool","in":"path","required":true,"schema":{"type":"string"},"description":"Pool subdomain label."},{"name":"apiKey","in":"path","required":true,"schema":{"type":"integer"}}],"security":[{"bearerAuth":["keys:write"]}],"responses":{"200":{"description":"Revoked pool key","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/PoolKey"}},"required":["data"]}}}},"404":{"description":"Key not found"}}}},"\/api\/v1\/pools\/{pool}\/metrics":{"get":{"operationId":"getPoolMetrics","summary":"Pool admit, queue, and reject metrics","tags":["metrics"],"parameters":[{"name":"pool","in":"path","required":true,"schema":{"type":"string"},"description":"Pool subdomain label."},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":["metrics:read"]}],"responses":{"200":{"description":"Metrics summary","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/PoolMetricsSummary"}}}},"404":{"description":"Pool not found"}}}}}}