DEV Community

entradox
entradox

Posted on Edited on

Per-agent cost attribution: how I put a hard spending cap on every AI agent I run

If you run more than a couple of AI agents, the token bill arrives and you can't answer the one question that actually matters: which agent burned the money? Trace viewers (Langfuse, LangSmith,Helicone) show you every request after the fact.

Some of them do have enforcement. Helicone has cost-based rate limits and can return a 429 before the request goes out. Portkey's gateway has per-key Budget Limits that expire the key when a USD or token ceiling is reached, and returns a 412 Budget exhausted. MLflow's AI Gateway has budget policies that c a block a request. So "observability can't stop anything" would be too strong, and I'm not going to pretend otherwise.

What I wanted was narrower: a spending limit per agent, enforced before the provider is contacted, where the cap is the primary object rather than a rate-limit side effect. Not an alert. A refusal.

The design

The unit of accounting is the agent id, not the trace. Every LLM call gets metered against that agent's ledger.

Meter. Record the model, the input tokens and the output tokens per call. Cost is computed from the provider's own reported usage with cache-aware pricing. Anthropic bills input at four different rates depending on cache state, so a flat rate gets it badly wrong. On one Claude Code session I priced the same tokens two ways. Every input token at the flat list rate came to $112.85. Priced against Anthropic's actual tiers (fresh input at 1x, 5-minute cache write at

1.25x, 1-hour cache write at 2x, cache read at 0.1x), the same session is $15.22. Same tokens,

7.4x, and the entire difference is the cost model. The price table ships with a source URL and

an as-of date per model, so you can check the arithmetic rather than trust mine.

https://aiagentscity.com/v1/pricing

Check. Before the call goes to the provider, estimate its maximum cost and compare it against the agent's remaining budget.

Refuse. If it would cross the cap, return 402 Payment Required and never contact the provider.

Through the proxy or the wrapper, the money is not spent.

The honest caveat

This only works if the traffic actually flows through the enforcement point. That is a proxy (your client points at a different base URL) or a one-line Python wrapper. The wrapper is the extra on the Python package. It repoints an SDK you already use, adds two headers, and subclasses nothing. Anthropic's client works the same way.

Traffic that bypasses the proxy is outside anyone's reach. That is true of every gateway-based approach, not just this one. AgentLedger holds no provider key. The credential rides in the request headers, is forwarded, and is never written to disk. Nothing here claims a bypass is impossible.

What a blocked call looks like
You point a client at the proxy, and it gets a 402 Payment Required back. The body is a typed error envelope where the error type is the HTTP-level class ("budget_error") and the code is the specific reason ("budget_exceeded"). The message names the model, the estimated maximum cost of the call in cents, the agent, and the cap it would have crossed. It ends with the only sentence that matters: nothing was sent upstream. The provider never saw the request.

The error envelope is shared by every REST and MCP error response, so both surfaces agree on shape. The full contract, in prose:

https://aiagentscity.com/llms.txt

The OpenAPI 3 schema:

https://aiagentscity.com/openapi.json

Alerts and reports
Caps alone aren't enough. You want to know before the block.

A webhook fires at 80% of budget, on cap cross, and on spending anomalies. You register the destination in the API, and the delivery-receipts endpoint returns successes and failures, so a dropped alert is visible rather than silent.

Per-agent P&L: totals, by rail, by service, budget status, anomalies.

Read-only report links, HMAC-signed and expiring (7 days by default, 90 at most), and revocable in bulk by bumping the agent's share epoch. Anyone holding the URL can read that one agent's report until it expires. It can't write, and it can't read any other agent.

Webhook payloads carry cost metadata only: an agent id, a number, a model name. Never a secret,a prompt, or a response.

Two things that surprise people
A dollar cap does not protect a token-metered agent. If an agent runs on a flat-rate or subscription arrangement, there is no per-call dollar amount to record, so a dollar cap measures

zero on every call and never fires. Not a misconfiguration. The quantity it measures is zero.

Dollar caps cover the non-token rails; token caps cover token rows. They are independent, and a token-metered agent needs its own token cap.

Collapsing tokens into a dollar estimate reintroduces the problem it was meant to solve: a cheap model looping burns tokens at roughly zero dollars, and an expensive model burns dollars at a perfectly sane token count. The two runaway modes hide each other. Convert one into the other early and you can see neither.

An unpriced model is never blocked. The call passes through and an alert fires instead, because a silent zero would read as "this agent spends nothing."

An agent can open its own ledger
The workspace path needs no signup, no login, and no card. One press mints a workspace key, and an agent can do it with no handoff. A small mechanical fact with a real consequence: the thing that spends the money can be the thing that accounts for it. An accounting tool that assumes a person in the loop at setup time cannot be adopted by the party doing the spending.

What it does not do

Two enforcement mechanisms, and the difference matters.

Through the proxy or the wrapper, the call is refused before the provider is contacted, so the spend genuinely does not happen.

Through the plain API (the track endpoint, which is what the CLI track command and a direct HTTP call produce), the ledger write that would cross the cap is rejected. Recording stops. The charge, if your agent already made it, does not.

The boundary, in the product's own words.

https://aiagentscity.com/security

Where to find it
Every line below is a real destination, and each URL is the last thing on its line.

START HERE

The product front door

https://aiagentscity.com

Get a workspace, no signup, no login, no card

https://aiagentscity.com/start

The three ways in

https://aiagentscity.com/quickstart

Paste a workspace key, see every agent on one page

https://aiagentscity.com/dashboard

INSTALL AND SOURCE

Python package, with the wrapper extra

https://pypi.org/project/aiagentscity-ledger/

Node package, no clone

https://www.npmjs.com/package/aiagentscity-ledger

Source code

https://github.com/entradox/agent-ledger

FOR AGENTS

The full API contract in prose. Start here

https://aiagentscity.com/llms.txt

OpenAPI 3 schema

https://aiagentscity.com/openapi.json

MCP manifest

https://aiagentscity.com/server.json

Capability, auth and pricing manifest

https://aiagentscity.com/.well-known/agent.json

MCP streamable-HTTP endpoint, nine tools: track, set budget, report, alerts, list agents, API docs, examples, rotate secret, revoke secret

https://aiagentscity.com/mcp/

MORE

The enforcement boundary

https://aiagentscity.com/security

Comparison

https://aiagentscity.com/compare

Who operates it

https://aiagentscity.com/about

Live uptime and version

https://aiagentscity.com/status

Live counters

https://aiagentscity.com/st ats

Terms

https://aiagentscity.com/terms

Privacy

https://aiagentscity.com/privacy

Try it
Free tier covers 3 agents per workspace with every feature, no signup and no card. Past 3 agents,

Pro is $19/mo for unlimited tracked agents, same workspace and same key. Upgrading from a workspace you already hold goes through the checkout endpoint, which returns a payment link bound to your workspace rather than a b are link that would charge you and leave you capped.

Current version 0.4.1, active in the official MCP registry as io.github.entradox/agent-ledger, with nine tools. If you only read one thing, read this. An agent can understand the credential model and start tracking without a human reading a line of documentation.

https://aiagentscity.com/llms.txt

Top comments (0)