DocsAPI Reference
Admin Guide

Claude Pool

Serve an organization's Claude traffic on registered Claude subscription setup-tokens, metered and billed exactly like API-key usage.


The Claude Pool lets a platform admin register Claude subscription setup-tokens (or Anthropic API keys) for an organization. Tokamak then uses those tokens as the upstream credential for that organization's Anthropic requests through the ordinary /v1/messages router.

Three properties define it:

  • It is a credential source, not a product path. The pool changes only which secret Tokamak puts on the upstream call. Provider resolution, billing admission, the execution id, the usage row, pricing, settlement, usage.cost, /v1/generation and usage limits are the same code the provider-key path runs. A pooled generation is admitted, metered, priced and charged exactly like an API-key one.
  • Tokens never leave the server. They are validated once, encrypted at rest, decrypted per request in memory, and never shown again. Only the last four characters are visible.
  • Members see nothing. There is no member-facing pool surface. tokamak launch claude behaves as today; when the organization's pool is on, the router serves it on pooled tokens.

How Anthropic accepts a setup-token

Anthropic serves a subscription token as Authorization: Bearer sk-ant-oat…. Haiku-class models are served on any request. Sonnet, Opus and Fable-class models are served only when the first system block is Claude Code's own identity line. Claude Code always sends that line, so Claude Code traffic through the router needs no rewriting. Other clients (SDKs, curl) sending their own system prompt get an instant 429 rate_limit_error on those models, and Tokamak forwards bodies as received — it never prepends the identity line to make a request eligible. Such a request simply uses the organization's provider API key, untouched.

Turning it on

1. Platform switch (operator)

On tokamak-core:

TOKAMAK_CLAUDE_POOL_ENABLED=true
TOKAMAK_CLAUDE_POOL_TOKEN_ENCRYPTION_KEY=<a long random secret>
TOKAMAK_CLAUDE_POOL_TOKEN_ENCRYPTION_KEY_ID=v1

Core refuses to boot with the switch on and no key. With the switch off (the default) the pool does not exist: nothing is consulted on the request path and the admin API answers 404. See Environment variables for the optional knobs.

2. Organization switch (platform admin)

In the admin console, open Organizations, choose the organization and click Claude Pool. Turn it On and set the priority. Nothing here is visible to the organization's members.

SettingOptionsMeaning
PriorityPool first (default)Pooled credentials are tried first; the provider API key is the fallback when the pool is exhausted or rejected.
Provider key firstThe provider API key is tried first; the pool is the fallback.

Eligibility is not configurable: a request whose first system block is Claude Code's identity line, or any Haiku request, may ride the pool; everything else uses the organization's provider API key, untouched, whichever priority is set.

3. Register tokens (platform admin)

The token owner runs:

claude setup-token

and hands the sk-ant-oat01-… value to the admin, who pastes it into Register token on the same panel, optionally with an alias. Tokamak proves the token live with one count_tokens call, encrypts it, and stores the last four characters as the visible hint. Anthropic API keys (sk-ant-api…) are accepted too. Claude Code session files (auth.json) are not accepted: Tokamak does not hold refresh chains.

Operating it

The credentials table shows, per token: alias, hint, status, Anthropic's own five-hour and seven-day utilization (read from the response headers on every pooled call), when it was last used, and today's pooled requests and cost attributed to it.

StatusMeaningAction
activeSelectable—
pausedAdmin took it out of rotationResume
invalidAnthropic answered 401/403Resume to re-test, or revoke and register a fresh token
revokedTerminal—

How the router picks a credential for a request:

  1. The requesting member's own credential first (when an admin registered one on their behalf), then the least recently used shared credential.
  2. Credentials that are rate-limited, or whose five-hour utilization is at or above TOKAMAK_CLAUDE_POOL_UTILIZATION_CEILING (default 90 %) inside its window, are skipped.
  3. A session stays on the same credential for TOKAMAK_CLAUDE_POOL_AFFINITY_TTL (default 60 s) so Anthropic's prompt cache keeps hitting. The key is the organization, user, model and the client's session id (a request without a session id shares one slot per user and model). With REDIS_URL set, every core replica shares it; affinity only reorders credentials that pass the checks above.
  4. If the upstream rejects the credential (401/403, or a real 429 with retry-after), it is marked — a real 429 quarantines every token of the same Anthropic account — and the request falls through to the next credential in the order, ending with the provider API key, inside the same byte-for-byte forward: the request bytes are re-sent unchanged, only the credential differs. At most TOKAMAK_CLAUDE_POOL_MAX_RETRIES (default 2) such retries happen per request, and only rejections that produced no generation are retried, so nothing is ever billed twice.
  5. Pooled secrets are released only to HTTPS endpoints on TOKAMAK_CLAUDE_POOL_ALLOWED_HOSTS (default api.anthropic.com). An Anthropic-kind provider pointed anywhere else is served on the provider key.
  6. A token registered with an owner and not shared serves only that member. Shared tokens (the default) serve every member. Rows copied from the previous pool keep their shared flag.

When the pool took part in a request, the response carries X-Tokamak-Credential-Source: pool or provider_key naming the credential that answered. Deployments with the pool off never see those two values. An organization's own provider key (bring your own key) is tried before the pool: a request it served, or a 503 byok_key_unavailable about it, carries org_key, and one that fell back from it carries org_key_fallback unless the pool then served it. Responses served on a pooled token do not expose the shared account's anthropic-ratelimit-*, organization or workspace headers.

Metering and billing

Pooled rows in token_usage differ from provider-key rows in exactly two columns: credential_source (pool) and pool_credential_id. Everything else — model, provider, tokens, estimated_cost_usd, execution_id, the settled charge — is produced by the same funnel, at the same catalog prices. Usage dashboards, usage limits and invoices therefore include pooled traffic with no special handling.

Migrating from the previous agent pool

Deployments that still run the pre-prune agent pool keep their tokens: migration 000081 copies active setup_token and api_key rows into the new store, switches those organizations on with the default policy so nobody loses the pool on deploy, scrubs every secret column from the old rows and renames the old table rather than dropping it (an audit skeleton remains: who contributed what type, when). session and auth_json rows are not copied; their owners should hand an admin a fresh claude setup-token. Copied rows are re-encrypted under the new key by the claude-pool-rekey job at boot.

The old CLI's GET /v1/agent-pool/launch-auth answers 404 with an upgrade hint and never returns a token; the CLI then offers the router path. Run tokamak update.

On this page