Every cost belongs to a matter
Legal work is already organised around the matter: time is billed to one, disbursements are allocated to one, and cost that cannot be attributed to one is cost the firm absorbs. An LLM credential shared across review, summarisation and drafting produces exactly that — one monthly total with no matter attached to any part of it.
What a provider dashboard leaves you with
01
Document review across a large corpus is the single largest variable cost in the workflow, and it is invisible until invoiced.
02
Without per-matter attribution, agent spend cannot be passed through or recovered.
03
A run over the wrong document set is only discovered once it has finished paying for itself.
What Capsera does about it
- Attribution per matter
- The same mechanism that attributes spend to an end customer attributes it to a matter, so cost arrives already allocated.
- A ceiling per run
- A review run gets an envelope. Exceeding it stops the call rather than producing a larger invoice.
- Sub-agents inherit identity
- A graph composed at runtime stays attributable, because sub-agents take their parent's identity from an in-process context stack.
The number this is judged on
Spend per matter
None of this is assumed. We scanned 133 public agent repositories and found a cost defect in most of the ones making live model calls.
Read the method and limitationsimport capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)