$ curl -X POST https://aiagentscity.com/proxy/openai/v1/chat/completions \
-H "Authorization: Bearer sk-your-own-provider-key" -d @payload.json
HTTP/1.1 402 Payment Required
{"error":{"type":"budget_exceeded","message":"blocked before the provider:
this call's estimated maximum cost (4160 cents) would put support-triage over
its monthly budget (99720 of 100000 cents). Nothing was sent upstream."}}
The provider never saw the request, so the money was never spent. That is the whole product — and the rest of the market only reports the number after you have paid it.
Install the wrapper, swap the base_url, or add the MCP server —
three paths, one dashboard. quickstart →
Every agent, its spend, its budget bar and its alerts on one page. /dashboard → · see a demo →
One number. Crossing it returns 402 to your caller and the
provider never sees the call.
No signup, no login, no card. The workspace key is shown once, on the spot.
agent_id, not by request trace. Which of my twenty agents is burning money? is the primary query, not a derived one.402. Same error envelope, different guarantee — and we say which is which everywhere.model and tokens_in/tokens_out and the price is looked up; cache-aware, because Anthropic bills input at four different rates and a flat rate was 7.4x wrong on a real session.Cost metadata only. An entry stores the agent id, rail, service label, amount, token counts, model and timestamp. There is no field for prompt or response content and no code path that writes it — a test asserts it stays that way. Read the security page →
Your provider key is yours. The proxy is pass-through: the key rides in the request headers, is forwarded verbatim, and is never stored — a test greps the whole data directory for it after a proxied call and fails if it appears. You can use the proxy without giving us a key at all.
Claude Code
claude mcp add --transport http agent-ledger https://aiagentscity.com/mcp/
Codex
codex mcp add agent-ledger --url https://aiagentscity.com/mcp/
Cursor / any MCP client — merge into mcp.json:
{
"mcpServers": {
"agent-ledger": {
"url": "https://aiagentscity.com/mcp/"
}
}
}
Or the Python wrapper — one line, every call metered and capped:
pip install "aiagentscity-ledger[wrapper]" client = agentledger.wrap(OpenAI(), agent_id="my-agent", workspace_key="wk_live_...")
Published on PyPI as
aiagentscity-ledger — the umbrella namespace, which nobody else can
register because it is our domain.
Tools: ledger_track, ledger_set_budget, ledger_report, ledger_alerts, ledger_list_agents, plus open docs tools ledger_api_docs and ledger_examples. Registered as io.github.entradox/agent-ledger.
Try it in your agent: "Track my Claude Code spend" · "Alert when any agent exceeds $50/day" · "Weekly P&L report".
Two mechanisms, two different guarantees — and we never blur them.
Through the proxy or the wrapper: the call is refused with 402 before
the provider is contacted, so the money is never spent.
On the plain API: the cap can only block the write when crossed — the ledger entry that would cross it is rejected, but the provider has already charged. That stops the recording, not the spend.
Traffic that bypasses the proxy is not enforced. Any caller that can reach your provider directly is outside our reach. If a cap has to be real, route the traffic through the proxy or the wrapper.
Trace tools answer "what did my agent do?" — $39/seat (LangSmith), $79/mo (Helicone), $249/mo (Braintrust). They bill per seat or per trace, and none of them stop the $401st call. AgentLedger is $19 per workspace, flat, and its unit of accounting is the agent. Full comparison, with dated prices →
1. Get a workspace_key — no signup, no login, no card: /start. Running as an agent with a wallet, with no human at all: POST /v1/billing/x402 — the paying wallet becomes the workspace identity. Testnet only right now: that path settles on Base Sepolia (eip155:84532) with testnet USDC, so a mainnet wallet cannot complete it until mainnet onboarding lands. Without a testnet wallet, use /start.
2. Track a spend event — dollars and tokens
curl -sL --post301 -X POST https://aiagentscity.com/v1/track \
-H "Content-Type: application/json" \
-H "AL-API-Version: 2026-09-01" \
-d '{"agent_id":"my-agent","rail":"x402","amount_cents":100,"service":"search","tokens_in":4500,"tokens_out":1200,"model":"gpt-4o","workspace_key":"YOUR_WORKSPACE_KEY"}'
A key claims, a secret writes: the first call for a new agent_id must carry "workspace_key":"wk_live_..." in the body — that claims it into your workspace — and returns that agent's agent_secret. Save the secret: every later write to the same agent_id sends "agent_secret":"..." instead and needs no workspace_key. Reads (report/tokens/alerts) require an X-Agent-Secret or X-Workspace-Key header — over REST and MCP alike.
The AL-API-Version header is required on writes. Omit it and the call is
rejected — that is deliberate, so a future breaking change cannot silently alter what your
agent meant.
3. Set a monthly cap — enforced, not just logged:
curl -X POST https://aiagentscity.com/v1/budget \
-H "Content-Type: application/json" \
-H "AL-API-Version: 2026-09-01" \
-d '{"agent_id":"my-agent","monthly_cents":5000,"agent_secret":"YOUR_SAVED_SECRET"}'
4. Pull the P&L — totals, by rail, by service, budget status and anomalies:
curl "https://aiagentscity.com/v1/report/my-agent?days=30" \ -H "X-Agent-Secret: YOUR_SAVED_SECRET"
Token burn: /v1/tokens/my-agent. CSV: /v1/report/my-agent/csv.
Browser view: /v1/report/my-agent/html. Everything at once:
/dashboard.
Already have a workspace_key? Post it to /v1/billing/checkout and the upgrade link is built for that workspace.