Budgets
Limits, periods, alert-only vs hard-deny, thresholds, and what actually happens at the cap.
Every project has a budget: a dollar limit, a period it resets on, and a mode that decides what happens at the limit. The mode is the whole game — alert_only tells you, hard_deny stops the spend.
Set a budget
A project's budget lives on its Budget & Alerts tab.
- Open the project and select Budget & Alerts.
- Set the limit in USD.
- Pick the period: daily, weekly, or monthly. On the Free tier, monthly is the only period; daily and weekly unlock on Production and above.
- Pick the mode:
alert_onlyorhard_deny. - Save. The form tracks unsaved changes — nothing applies until you save.
What happens at the limit
hard_deny blocks the call before it is dispatched. The SDK's pre-flight check comes back denied, the provider is never reached, and your code sees a BudgetExceededError — the same denial the CLI reports as exit code 4. The blocked call is recorded as budget_denied, excluded from spend — it never happened — and surfaced on the Costs tab as blocked-call savings.
alert_only never blocks. Calls proceed past the limit; you get notified. The budget is a tripwire, not a wall.
Every tier can run a hard cap, with one gate: the Free tier allows one hard-deny project. On paid tiers, every project can hard-deny. See Budget enforcement for the SDK's view of a denial.
Per-run caps (SDK v0.3.0+)
Budgets can also cap an individual agent run, not just the project period. Runs are identified by the stable run id the SDK carries on every admission inside a solwyn.run(...) scope — configure the cap in Cloud, and the SDK enforces it automatically once the scope is open. (From SDK v0.4.0 a token-billed run draws on a budget lease rather than checking before every call; the cap is enforced the same way, just without the per-call round-trip.) A per-run denial behaves like any other budget denial: the same BudgetExceededError (with budget_period="agent_run"), the same mode semantics. See Agent runs: per-run budget caps and Budget enforcement for the SDK-side mechanics.
Runaway-run rules
A runaway run rule is a wildcard per-run cap: it applies to every run in the project rather than one named run id. Create one from the Budget & Alerts tab (or as a runaway_run entry in the budget's thresholds) with:
- a run spend cap in USD (whole cents, greater than zero, at most $1,999,999.99);
- optionally a call threshold and a window of 1–1440 minutes — both or neither — that flag a run making too many calls too fast;
- a mode:
alert_only(the default) notifies when a run crosses the cap;hard_denymakes the cap enforceable, so a run at its cap is denied further calls withdenied_by_period: "agent_run".
A runaway-run rule denies calls; it does not stop the run. Stopping is an operator action — see below. Each rule fires at most once per run per UTC day, and a firing shows a Stop run button in the alert sidebar.
Scoped budgets
SDK v0.5.0+. A scoped_budget rule caps one slice of a project's spend on the project's period — one model, one provider, one agent run (by the raw id your code saw), or one exact tag pair. Add one from the Budget & Alerts tab, or as an entry in the thresholds array of PUT /api/v1/projects/{project_id}/budget:
{
"type": "scoped_budget",
"scope": "tag",
"match": "customer_tier",
"match_value": "enterprise",
"limit": 50.0,
"mode": "hard_deny",
"channel_ids": []
}match is the selector — a model id, a provider name, a run id, or (for tag) the tag key, in which case match_value is the tag value and is required; it is invalid for the other scopes. limit is in USD at micro-dollar precision. Each scoped rule carries its own mode: a hard_deny scoped rule denies matching calls even when the project's mode is alert_only, and the SDK reports the denial with budget_period set to the scope ("model", "provider", "agent_run", "tag"). A tag rule can only deny a call that carries the tag — the SDK sends its merged tag snapshot on every budget check for exactly this reason — and a tag denial is never sticky. The rule's response carries its live current_usage, or null when it is temporarily unavailable. One selector may hold one limit.
Stopping a run
A stop is different from a cap. Stop on a run in the project's Agents tab denies every future budget check for that run and revokes its leases; the SDK raises RunStoppedError on the run's next call, and the stop cannot be undone for that run id. Caps are budget decisions the mode can soften; a stop is not.
Thresholds — notification, not enforcement
Percent thresholds fire notifications as spend crosses them. They never block anything — enforcement belongs to the project mode, and to the per-rule mode of a scoped or runaway-run entry.
Every project starts with a 100%-of-budget email alert armed by default. Add thresholds (1–100%) on the Budget & Alerts tab; the number of rules a project can hold is tier-capped — one on Free, ten on Production and Team, unlimited on Scale — with a hard payload cap of fifty entries.
Delivery defaults — the second form on the tab
Below the budget form, the Delivery defaults card sets where this project's notifications go by default: the severity floor, default channels, and which event types deliver. The two forms save independently — saving the budget does not save delivery settings, and each tracks its own unsaved changes.
Old links to a project's separate Alerts or Delivery pages redirect here.
Cross-references
- The SDK raises
BudgetExceededErroron a denial and reports abudget_denieddenial receipt — see Budget enforcement. A denied call still counts toward the Free tier's monthly request quota. - A stopped run raises
RunStoppedErrorinstead — see Run control and Agent runs. - The CLI's
solwyn budgetchecks, settles, and updates the same budget; denials are exit code4. - Alert rules beyond simple thresholds — forecasts, anomalies, the account-wide cap — live on the Alerts page.