Concepts · Budgets

Budgets

A budget is a spend limit attached to a scope. Esy enforces it before a run executes, using the run’s estimated cost, so a run that would breach the limit is rejected rather than discovered after the provider has already been billed.

Enforcement is on the estimate

Budget checks run pre-flight against the run’s estimate (see Costs). Actuals reconcile afterward, so a budget is a guardrail on intent, not a billing reconciliation. Set limits with the estimate’s typical cost in mind.

Scope

Every budget belongs to a workspace (organization). It optionally narrows to a single project or workflow within that workspace. The scope is derived from which id is set.

ScopeApplies toSet
workspaceEvery run in the organization.Neither projectId nor workflowId.
projectRuns in one project.projectId.
workflowRuns of one workflow template.workflowId.

Period

The limit applies over a window. Spend is summed from the provider cost ledger within the current window, using the actual cost where reconciled and the estimate otherwise.

PeriodWindow
totalAll-time. The limit is a lifetime cap.
dailySince 00:00 UTC today.
weeklySince Monday 00:00 UTC.
monthlySince the 1st of the month, 00:00 UTC.

Enforcement modes

ModeBehavior
hard_stopReject the run when current spend + run estimate would exceed the limit. The safe default for real provider money.
allow_overageTolerate spend up to limit + overageUsd, then reject. A grace band over the limit.
allow_one_morePermit the single run that crosses the limit, then reject subsequent runs.
track_onlyNever blocks. Records and surfaces burn so spend is visible without gating runs.

Per-run cap

A budget may also carry a perRunCapUsd — a hard ceiling on a single run’s estimate, independent of the period limit. It applies under any blocking mode and is useful for catching a misconfigured high-cost model before it runs at volume.

Example budget

POST /v1/budgetsjson
{
  "id": "b1a2c3d4-...",
  "workspaceId": "8f0e...",
  "projectId": null,
  "workflowId": null,
  "scope": "workspace",
  "name": "ESY LLC monthly cap",
  "limitUsd": 50,
  "period": "monthly",
  "perRunCapUsd": 0.25,
  "enforcementMode": "hard_stop",
  "overageUsd": null,
  "currency": "USD"
}

How a run is evaluated

On run creation, Esy prices the template, resolves every budget that applies to the run’s scope (workspace-wide budgets always apply; project and workflow budgets apply on a match), and evaluates each. The most restrictive applicable budget wins. If one blocks, the run is never created and the API returns 402 budget_exceeded with the scope, limit, current spend, and the remaining headroom.

rejected runjson
HTTP/1.1 402 Payment Required

{
  "detail": {
    "code": "budget_exceeded",
    "reason": "hard_stop",
    "scope": "project",
    "enforcementMode": "hard_stop",
    "limitUsd": 50,
    "spendUsd": 49.92,
    "runEstimateUsd": 0.21,
    "remainingUsd": 0.08
  }
}
Relationship to Costs

Budgets sit on top of the same provider cost ledger that powers Costs. The ledger supplies current spend per scope and period; budgets decide whether the next run may add to it.