Skip to main content

Set a budget

Do this to bound what an agent can spend before it spends it. There are four ceilings — monthly spend, per-run spend, service spend and tokens — and they are enforced in different places, so choosing the right one matters more than the number. Do not use a budget to stop an agent doing something specific; that is a tool rule. And do not expect a tightened budget to interrupt a task that is already running. New workspaces are seeded with a baseline: 500.00 USD per month, 50.00 USD per run, 20,000,000 tokens total and 100,000 tokens per call. You are usually adjusting those rather than creating them from nothing.

Prerequisites

  • You can create policy rules through /v1/policies.
  • Read budgets and quotas, in particular which ceiling is admission-only.
Examples assume API=http://localhost:8000 and a bearer token in $TOKEN.

Steps

1. Choose the ceiling

Amounts are accepted as a string or a number; use a decimal string such as "250.00" to avoid float rounding. They come back as strings.

2. Create the cap

Scope it more tightly by changing the subject. subject_type: "agent" with the agent UUID bounds one agent; subject_type: "user" with a user id bounds whatever that person launches. Lower scopes may only lower the number.

3. Adjust an existing cap instead of stacking one

The workspace baseline already contains a monthly and a per-run cap. Find the row and patch it rather than adding a second:
PATCH replaces params wholesale, so include period even when only the amount changes. To switch a cap off without deleting it, send {"enabled": false} — disabled rules are skipped when the layer compiles.

4. Bound a single task

A per-task ceiling rides on task creation:
This can only tighten. A task asking for more than the agent or workspace allows is rejected.

Verify

Preview the merged ceiling before running anything:
Confirm the snapshot a task carries:
Confirm the monthly cap bites. Once month-to-date spend reaches the cap, task creation returns HTTP 402 with a problem document naming the numbers:
Confirm the run budget bites. The loop emits BudgetWarning at 80 percent and BudgetExceeded when it stops:

Troubleshooting

422 when creating the rule or previewing. A lower scope tried to raise a higher one’s ceiling. Budgets merge by taking the minimum, and the resolver rejects rather than silently clamping so the mistake is visible. Raise the parent first, or lower the child. The cap was set and the task still overspent. The monthly cap is admission control only. A task that starts under the cap runs to completion no matter how far past the cap the workspace goes, and the check is a read-then-decide with no lock, so concurrent task creation can cross it. For a hard per-task bound use the run budget, which is enforced inside the loop and before each call. Month-to-date looks wrong. It is summed from total_cost on the workspace’s task rows from the first of the current UTC month. Spend from a task still in flight is not fully counted until it finishes, so the figure trails reality while work is running. A task is rejected because a ceiling is missing. Runtime execution requires an explicit run budget, total and per-call token ceilings, and agent-loop limits in the resolved governance snapshot. Deleting the persisted workspace defaults does not reveal a built-in numeric fallback; it makes the runtime contract invalid. Restore the missing policy rows and re-check the preview output. max_tokens_per_call appears lower than expected. It is enforced on every LLM call. The resolver takes the strictest positive value from the effective policy, the request, and the model’s declared output capability, so inspect all three sources before changing the workspace rule. The numbers do not match between the loop and the per-call gate. They are two enforcement points reading one resolved ceiling — the tighter of the per-request budget and the policy value. If they disagree, the request carried its own budget_usd; the minimum wins, so check what the caller sent. A budget denial appears as a failed activity, not a graceful stop. The per-call gate raises rather than returning a message the model can answer. The graceful path — the loop noticing exhaustion and completing — comes from the in-workflow tracker. Both are expected; which you see depends on where the ceiling was crossed.