Task budgets, the job dies at $5

Provider spend caps stop at monthly totals for one vendor: no per-run ceiling, no cross-provider budget, and tool spend isn't counted. A task budget is the number that actually matters, what this job is allowed to cost, across every model and tool it touches, enforced before the money is spent.

How it works

A task groups many calls under one hard ceiling. Three rules:

1, The first preflight that names a task_ref creates the task and fixes its task_ceiling.
2, Every later preflight atomically reserves against the same budget; the call that would cross the ceiling is blocked before it runs.
3, Records report reality: a failed run releases its reservation, and spend that lands past the ceiling is still recorded and flagged task_exceeded, never silently dropped.

Quick start, curl

# First call creates the task: this job dies at 50 units
curl -X POST https://agentbill.dev/preflight \
  -H "Authorization: Bearer agb_your_key" \
  -H "Content-Type: application/json" \
  -d '{"agent_id":"researcher","estimated_units":2,
       "task_ref":"job-42","task_ceiling":50}'

# ... run the LLM / tool call, then record what actually happened
curl -X POST https://agentbill.dev/events \
  -H "Authorization: Bearer agb_your_key" \
  -H "Content-Type: application/json" \
  -d '{"customer_id":"default","event_type":"llm_call",
       "idempotency_key":"job-42-step-1","units":2,"task_ref":"job-42"}'

# The call that would cross the ceiling is refused:
# {"approved":false,"reason":"task_ceiling_exceeded",
#  "task_used_units":48,"task_remaining_units":2}

Python

pip install agentbill-sdk  # >= 0.4.0
from agentbill import AgentBillClient, TaskCeilingExceededError

client = AgentBillClient(api_key="agb_your_key")

# preflight before, record after, or wrap it all with the gate decorator:
@client.gate("researcher", estimated_units=2,
             task_ref="job-42", task_ceiling=50)
def run_step(query: str) -> str:
    return call_llm(query)

# the run that would cross 50 units raises TaskCeilingExceededError
# a run that throws releases its reservation automatically

Node.js

npm install agentbill  # >= 0.2.0
import { preflight, record, getTask } from 'agentbill'

await preflight({ agentId: 'researcher', estimatedUnits: 2,
                  taskRef: 'job-42', taskCeiling: 50 })
// ... run the call ...
await record({ agentId: 'researcher', units: 2, taskRef: 'job-42' })

const t = await getTask('job-42')  // live burn-down
console.log(t.usedUnits, '/', t.ceilingUnits)

API reference

POST /preflight, extra fields

task_ref, job identifier (1-128 chars). Same ref = same budget.
task_ceiling, required on the first preflight of a new task_ref; fixed at creation, ignored afterwards.
Approved responses include task_remaining_units. A blocked run returns reason: "task_ceiling_exceeded"; a new task_ref without a ceiling returns 422 task_ceiling_required.

POST /events, extra field

task_ref, attributes the spend to the task. success: false releases the reservation without billing. Responses include task_used_units, task_remaining_units and task_exceeded.

GET /tasks and GET /tasks/:task_ref

Per-agent cost attribution: every job's ceiling, spend, live reservations and overage flag. Filter with ?agent_id=.

Get a free API key →

Related guides

Task budgets, a hard cost ceiling per agent job How to add billing to a LangChain agent How to add a spend ceiling to an OpenAI agent How to limit cost per agent run