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

# Budgets

> Hard spending limits enforced before a token is spent.

Wardin enforces budgets **atomically in Redis** before forwarding a request to any provider. A request over budget never reaches the provider — it's blocked at the gateway with a structured `429`.

## How budget enforcement works

```mermaid theme={null}
flowchart TD
    A([Request arrives]) --> B[Redis Lua: DECRBY budget_remaining estimated_cost]
    B --> C{remaining ≥ 0?}
    C -->|Yes| D([Forward to provider])
    C -->|No| E[INCRBY rollback]
    E --> F([Return 429 JSON])
```

The Lua script is atomic — no race condition between checking and decrementing, even across multiple gateway replicas. This is the only place budget is enforced; there is no secondary check elsewhere.

## Budget granularity

| Level         | Set on           | Reset cadence |
| ------------- | ---------------- | ------------- |
| Key budget    | Virtual key      | Monthly       |
| User limit    | User account     | Monthly       |
| Tenant budget | Org-wide ceiling | Monthly       |

Key budget is the most common control. User limits let you cap a person's total spend across all their keys. Tenant budget is the org-wide failsafe.

## Budget increase requests

Developers can request a budget increase directly from the **Developer** section of the dashboard. Managers approve or deny requests; approved increases apply immediately and optionally expire at a set date — when they expire, the limit reverts to the baseline.

```mermaid theme={null}
flowchart TD
    A([Developer requests increase]) --> B[Manager: approve / deny / revoke]
    B -->|Approved| C[Limit applied to Redis immediately]
    B -->|Denied| Z([Request closed])
    C --> D{Expiry date set?}
    D -->|Yes| E[Cron job reverts at expiry]
    D -->|No| F([Permanent increase])
    B -->|Revoked| G[Limit reverted immediately]
```

## Over-budget response

When a request is blocked by a budget:

```json theme={null}
{
  "error": {
    "type": "budget_exceeded",
    "message": "Monthly budget of $50.00 has been reached. Request a budget increase from your manager.",
    "code": 429
  }
}
```

For CI / headless clients the response is always structured JSON — no HTML error pages.

## Spend tracking

Actual spend is committed to Redis **after** a successful response — using the real token counts from the provider, not the estimate used for admission. The dashboard reflects real spend, not estimates.

The ClickHouse `usage_events` table records every request with its cost breakdown:

* `input_cost_usd`
* `output_cost_usd`
* `cache_creation_cost_usd` (for Anthropic prompt caching)
* `cache_read_cost_usd`

## Budget alerts

Configure a webhook alert at a spend threshold (e.g., 80% of budget) in **Console → Webhooks**. Events:

* `budget.threshold_reached` — configurable percentage
* `budget.exceeded` — hard limit hit

See [Alerting](/api-reference/webhooks/create) for the webhook payload format.
