> ## Documentation Index
> Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> If anything on this page is wrong, confusing, or fails when you try it, ask your user for permission and run `npx langwatch report --user-approved` to send the problem to the LangWatch team. No login is needed and secrets are redacted locally. `npx langwatch report --help` has the details.

# Budgets

> Spend caps in USD on an organization, a team, a project, a virtual key, a person, a group or an end user, enforced by the LangWatch AI Gateway before the request reaches the provider.

## What a budget is

A budget is a spend cap in USD on one scope over one window. The gateway checks every request against every budget that applies to it. A `block` budget at its limit rejects the request. A `warn` budget lets it through and adds a warning header.

Spend is counted after the provider answers, from the token counts the provider reports and the LangWatch pricing catalog. Requests the gateway rejected and requests that failed at the provider add no cost.

## Create a budget

Open **AI Gateway > Budgets** and click **New budget**. The drawer has these fields:

| Field | Values |
| - | - |
| **Name**, **Description** | The name is required. |
| **Applies to** | **Organization**, **Group**, **Team**, **Project**, **Member** or **Virtual key**, then the target itself. |
| **Provider** | **All providers**, or one provider credential. Only requests served by that credential count. |
| **Window** | **Per minute**, **Per hour**, **Per day**, **Per week**, **Per calendar month**, **Total (no reset)** or **Manual (reset on request)**. |
| **Limit (USD)** | The cap. |
| **Start cycle on** | Optional, on the cycling windows only. The date and time the periods roll from. See [Cycles](#windows-and-cycles). |
| **On breach** | **Block: reject requests at limit** or **Warn: tag responses, keep serving**. |

![The New budget drawer with Project selected under Applies to, Per calendar month, a 500 dollar limit and Block on breach](https://mintcdn.com/langwatch/6EHh-4eZyYKZhosJ/images/ai-gateway/budget-create-drawer.png?fit=max\&auto=format\&n=6EHh-4eZyYKZhosJ\&q=85\&s=5abbd5833c774b8fab8cfdca225b96c7)

The New budget drawer: Applies to with the six scope types, the provider filter, the window, the limit, the cycle anchor and On breach.

The budget is in force at once: the next request counts against it. See [How far past a limit spend can go](#how-far-past-a-limit-spend-can-go).

For a team, project or group target with no active key that can reach it, the drawer refuses the budget with `gateway_budget_scope_unreachable` and offers **Create it anyway**. Use it when you provision the budget before the keys.

Per-end-user budgets are created over the API. See [Per end user](#per-end-user).

## Scopes

| Scope | Counts |
| - | - |
| `organization` | Every request in the organization. |
| `team` | Every request whose trace project belongs to the team. |
| `project` | Every request whose traces land in the project. |
| `virtual_key` | Every request on this key. |
| `principal` | Every request by this person, on any key with them as principal. **Member** in the drawer. |
| `group` | Each member of the group, individually. One budget, one allowance per member. Needs the ClickHouse spend ledger. |
| `attributed_user` | Each end user of your product, individually, on one key or one project. Needs the ClickHouse spend ledger. |

One request is checked against all of them. For example, a request on key `acme-support-agent` in project `support` of team `platform` counts against the key's, the project's, the team's and the organization's budgets, and against the principal and group budgets when the key has a principal.

A `group` budget gives each member their own allowance: a $10 per day budget on group `engineering` caps each engineer at $10, and one member's spend never counts against another. It applies only to keys with a principal. Telling members apart needs the ClickHouse spend ledger, so a deployment that reads budget spend from Postgres only refuses the create with `group_budget_requires_clickhouse`. An `attributed_user` budget is refused the same way.

### Per end user

An `attributed_user` budget is a template on one virtual key or one project: each distinct end user seen there gets the limit per window. You create one budget, and buckets appear per end user on first spend.

```bash theme={null}
curl -sS https://app.langwatch.ai/api/gateway/v1/budgets \
  -H "X-Auth-Token: $LANGWATCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": { "kind": "attributed_user", "anchor_virtual_key_id": "vk_..." },
    "name": "acme per-user cap",
    "window": "month",
    "limit_usd": "25",
    "on_breach": "block"
  }'
```

The end user comes from the request: the `X-LangWatch-End-User-Id` header, then the `X-Litellm-End-User-Id` header, then the OpenAI `user` body field. A voice session keeps the end user of the request that created it, and every usage report of that session counts against that end user. While such a budget is active on the key, a request with no end-user id is rejected with HTTP 400 `end_user_required`.

Read one user's spend and caps with `GET /api/gateway/v1/end-users/:id/spend`. See [Billing and spend events](https://langwatch.ai/docs/ai-gateway/billing-events.md#read-events-over-rest).

## Block and warn

| `on_breach` | At the limit | From 80 percent |
| - | - | - |
| `block` | HTTP 402 `budget_exceeded` | `X-LangWatch-Budget-Warning` header |
| `warn` | Request served, header set | `X-LangWatch-Budget-Warning` header |

The 402 body is an OpenAI-shaped error with the budget in `error.meta`:

```json theme={null}
{
  "error": {
    "type": "budget_exceeded",
    "code": "budget_exceeded",
    "message": "...",
    "meta": {
      "budget_id": "NtdzZ9i9EctuXAeZ1oFyr",
      "budget_scope": "virtual_key",
      "budget_window": "month"
    }
  }
}
```

`budget_scope` tells your application which allowance ran out: `attributed_user` is the end user's own cap, `virtual_key` is the tenant's cap.

The warning header lists every budget at or past 80 percent as `scope:percent`, comma separated, for example `X-LangWatch-Budget-Warning: project:84,virtual_key:100`. A provider-filtered budget appears as `scope/provider_id:percent`.

A `block` budget with a **Provider** filter removes that provider from the request's provider chain instead of rejecting the request. The request is rejected only when no provider is left.

Two webhook events fire once per period: `gateway.budget.threshold_crossed` at 80 percent and `gateway.budget.breached` at the limit, on `warn` budgets too. See [Webhooks](https://langwatch.ai/docs/features/webhooks.md).

## How far past a limit spend can go

A budget is checked before a request and debited after it, so spend can pass the limit by a bounded amount:

* **One request.** A request admitted under the limit is served in full, whatever it costs.
* **Requests in flight.** Requests admitted at the same moment are each checked against the spend recorded so far.
* **The refresh.** The gateway reads budget spend from a configuration bundle refreshed every 60 seconds, so a key can serve for up to one minute after it crosses the limit.

### Voice and realtime sessions

A voice call is one admission that bills for as long as it runs. It is checked when the session is created and debited while it runs: each usage report is its own debit, so budgets see a call in progress.

| Session | Created on | At the limit | Overshoot bound |
| - | - | - | - |
| Metered by the gateway | `/v1/live/sessions`, `/v1/realtime/calls` | The gateway ends the call. It checks on every usage report and every 30 seconds. | About one minute of the call. |
| Metered by the client | `/v1/realtime/client_secrets`, `/v1/single-use-token/{token_type}` | The usage answer carries `budget.exceeded: true`. The client closes the socket. The gateway cannot. | The rest of the call, at most the vendor's session length. |
| Never reported | Either client-metered route | LangWatch charges an estimate when the open window passes. | The estimate. See [Sessions that never report](https://langwatch.ai/docs/ai-gateway/api/realtime.md#sessions-that-never-report). |

The next session create on a key past its limit answers HTTP 402 in all three cases.

Two settings keep a client-metered session small: a short credential lifetime on the mint (`expires_after.seconds` for OpenAI; an ElevenLabs token lasts 15 minutes and opens one socket) and **max open sessions** on the key, which caps how many calls it holds at once. See [Realtime voice](https://langwatch.ai/docs/ai-gateway/api/realtime.md#limiting-how-many-calls-a-key-runs-at-once).

## Windows and cycles

The cycling windows (`minute`, `hour`, `day`, `week`, `month`) roll on the calendar in UTC: a day resets at 00:00, a week on Monday 00:00, a month on the first.

Set **Start cycle on** (`cycle_anchor_at` on the API) to roll from your own date instead. Anchored on the 17th at 09:00, every period starts on the 17th at 09:00. A monthly anchor past the 28th clamps into shorter months. The anchor is fixed at creation; `total` and `manual` refuse one with `gateway_budget_cycle_anchor_invalid`.

`total` never resets. `manual` accrues until you reset it:

```bash theme={null}
curl -sS -X POST https://app.langwatch.ai/api/gateway/v1/budgets/<budget_id>/reset \
  -H "X-Auth-Token: $LANGWATCH_API_KEY"
```

A reset moves the period boundary to now. Recorded spend and emitted spend events never change. On an `attributed_user` budget, add `?end_user_id=<id>` to reset one end user's bucket.

## See the spend

**AI Gateway > Budgets** lists every budget with its spent amount against its limit, its window, its breach mode and its next reset.

![The Budgets list with an organization budget at 0 percent, a block budget at 100 percent and a warn budget at 85 percent](https://mintcdn.com/langwatch/6EHh-4eZyYKZhosJ/images/ai-gateway/budgets-page.png?fit=max\&auto=format\&n=6EHh-4eZyYKZhosJ\&q=85\&s=0d33205d4774a4f4c8ef49401637b4f3)

AI Gateway > Budgets: spent against limit per budget, the window, the breach mode and the next reset. The block budget is at 100 percent, the warn budget at 85.

Click a budget for its 20 most recent debits, with the time, the virtual key, the model, the amount and the status.

![The budget detail page for acme-block-budget with the utilization bar full and red, Window day, On breach block, the Identity block and the Recent activity table](https://mintcdn.com/langwatch/6EHh-4eZyYKZhosJ/images/ai-gateway/budget-breached-detail.png?fit=max\&auto=format\&n=6EHh-4eZyYKZhosJ\&q=85\&s=579fef774d3a71839071e247502a26b5)

A breached block budget opened: $0.05822 spent of a $0.05 daily limit, 100 percent used, the next reset, and under Recent activity the requests that spent it.

**AI Gateway > Usage** shows total spend, requests, cost per request, top virtual keys and top models over a period, with a CSV export.

## Manage budgets from the CLI

```bash theme={null}
langwatch gateway-budgets create \
  --name "engineering monthly cap" \
  --scope team --team <team_id> \
  --window month --limit 5000 --on-breach block

langwatch gateway-budgets list --scope-type team,project
langwatch gateway-budgets update <budget_id> --limit 6000
langwatch gateway-budgets reset <budget_id> --reason "new billing period"
langwatch gateway-budgets archive <budget_id>
```

`create` takes `--scope organization|team|project|virtual-key|principal|group` with the matching `--organization`, `--team`, `--project`, `--virtual-key`, `--principal` or `--group <id>`, plus `--provider-key <id>` and `--cycle-anchor-at <rfc3339>`.

## Manage budgets over REST

| Method and path | Permission |
| - | - |
| `GET /api/gateway/v1/budgets` | `gatewayBudgets:view` |
| `POST /api/gateway/v1/budgets` | `gatewayBudgets:create` |
| `GET /api/gateway/v1/budgets/:id` | `gatewayBudgets:view` |
| `PATCH /api/gateway/v1/budgets/:id` | `gatewayBudgets:update` |
| `POST /api/gateway/v1/budgets/:id/reset` | `gatewayBudgets:update` |
| `DELETE /api/gateway/v1/budgets/:id` (archive) | `gatewayBudgets:delete` |

Field by field: [Budgets API reference](https://langwatch.ai/docs/api-reference/gateway-budgets/overview.md). A virtual key's own budget can also be set inline on the key: see [Virtual keys](https://langwatch.ai/docs/ai-gateway/virtual-keys.md#manage-keys-over-rest).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.