LanternDOCS

Budgets

Budgets are policy-as-code per-agent limits. When a run would exceed a hard-fail limit, Lantern returns HTTP 402 before execution begins. Soft budgets log and continue. Use POST /v1/runs/forecast to check whether a run would exceed budget before submitting it.

In plain termsAI agents spend real money with every model call — and a buggy loop can burn through a month's budget in an afternoon. A budget is a spending cap you set per agent: dollars per day, dollars per run, or even "this agent may only send 10 emails a day". With hard-fail on, Lantern refuses to start a run that would blow the cap — the money is never spent, rather than flagged after the fact.

Setting a budget

PUT /v1/agents/{name}/budget
Content-Type: application/json

{
  "maxCostUsdPerDay": 5.00,
  "maxCostUsdPerRun": 1.00,
  "maxTokensPerDay": 500000,
  "maxRunsPerDay": 100,
  "toolLimits": {
    "gmail.send": 10,
    "github.createIssue": 5
  },
  "hardFail": true
}

Response: 200 OK
{ "agentName": "research-agent", "maxCostUsdPerDay": 5.00, ... }

Field reference:

FieldTypeDescription
maxCostUsdPerDaynumberMax USD spend across all runs in one calendar day
maxCostUsdPerRunnumberMax USD spend for a single run
maxTokensPerDayintegerMax total tokens (in + out) per day
maxRunsPerDayintegerMax run count per day
toolLimitsobjectPer-tool call-count limits per day (key = connector action)
hardFailbooleanWhen true, a limit breach returns HTTP 402 and blocks the run. When false, the breach is logged but the run proceeds.
Day boundary. The daily rollup resets at local midnight using LANTERN_DEFAULT_TIMEZONE (deployment-wide IANA zone; defaults to UTC when unset). A schedule with timezone: "America/New_York" rolls at New York midnight, not UTC.

Reading a budget

GET /v1/agents/{name}/budget

Response: 200 OK
{ "agentName": "research-agent", "maxCostUsdPerDay": 5.00, "hardFail": true, ... }

GET /v1/budgets
Response: 200 OK — bare array of all tenant budgets
[{ "agentName": "...", ... }]

Removing a budget

DELETE /v1/agents/{name}/budget

Response: 204 No Content

Pre-run cost forecast

Before submitting a run, call the forecast endpoint to estimate cost and check whether it would breach a budget:

POST /v1/runs/forecast
Content-Type: application/json

{
  "agentName": "research-agent",
  "input": { "topic": "quantum computing" }
}

Response: 200 OK
{
  "estimatedTokensIn": 800,
  "estimatedTokensOut": 2000,
  "estimatedCostUsd": 0.004,
  "confidence": 0.82,
  "wouldExceedBudget": false,
  "blockReason": ""
}

// If over budget:
{
  "estimatedCostUsd": 1.20,
  "wouldExceedBudget": true,
  "blockReason": "would exceed maxCostUsdPerRun (1.00)"
}

Budget gating on voice calls

Voice calls count against the same agent_budgets as runs. An inbound call over a hard-fail budget is declined before any media is allocated (Twilio: <Reject>; LiveKit: HTTP 402 on the token request). A flat cost estimate is reserved on connect, then reconciled to the actual call duration when the provider status callback fires at POST /v1/voice/calls/status/{provider}.