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.
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:
| Field | Type | Description |
|---|---|---|
maxCostUsdPerDay | number | Max USD spend across all runs in one calendar day |
maxCostUsdPerRun | number | Max USD spend for a single run |
maxTokensPerDay | integer | Max total tokens (in + out) per day |
maxRunsPerDay | integer | Max run count per day |
toolLimits | object | Per-tool call-count limits per day (key = connector action) |
hardFail | boolean | When true, a limit breach returns HTTP 402 and blocks the run. When false, the breach is logged but the run proceeds. |
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 ContentPre-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}.