SOLWYN

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.

  1. Open the project and select Budget & Alerts.
  2. Set the limit in USD.
  3. Pick the period: daily, weekly, or monthly. On the Free tier, monthly is the only period; daily and weekly unlock on Production and above.
  4. Pick the mode: alert_only or hard_deny.
  5. 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_deny makes the cap enforceable, so a run at its cap is denied further calls with denied_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 BudgetExceededError on a denial and reports a budget_denied denial receipt — see Budget enforcement. A denied call still counts toward the Free tier's monthly request quota.
  • A stopped run raises RunStoppedError instead — see Run control and Agent runs.
  • The CLI's solwyn budget checks, settles, and updates the same budget; denials are exit code 4.
  • Alert rules beyond simple thresholds — forecasts, anomalies, the account-wide cap — live on the Alerts page.

On this page