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

# Budgets and Alerts

> The three kinds of spend budget the gateway enforces (per key, per application, per team), how each resets, where to set it, and the alerts it sends.

## What this is for

Guardway can stop spend at three levels: on one **API key**, on an **application** (every key bound to it), and on a **team** (every key that belongs to it). They differ in what they cover, whether they reset, and which alerts they send, so the budget you set has to be the one you meant. A "$1,000 budget" on a key is spent once and never comes back; a "$1,000 monthly budget" on an application refills every month.

This page compares the three kinds, shows where each is set in the dashboard and through the Claude connector, and describes the `budget.threshold` and `budget.exceeded` alerts.

All three are hard caps enforced by the gateway. Spend is the cost of each request as priced on [Settings → Pricing](/platform/settings/pricing).

## Options

### The three kinds at a glance

| Kind | Covers | Resets | Where to set it | Alerts before the cap | When the cap is hit |
| - | - | - | - | - | - |
| **Per-key budget** | One API key | **Never.** A lifetime cap on the key's total spend | **Configuration → API Keys** (create dialog), **FinOps → Budgets**, or the Claude connector | `budget.threshold` at the key's **Budget alert thresholds (%)** below 100 (dialog default `50,80,100`) | HTTP 429 `budget_exceeded`; `budget.exceeded` on every refused request |
| **Application budget** | Every key bound to the application, combined | **Daily**, **Monthly**, or **Total (lifetime)**, chosen per policy | **Security → Apps** (**New application**) or **Security → Policy** (**Budget** section), or the Claude connector | `budget.threshold` at 50% and 80%, once per period | HTTP 402 `budget_exceeded_for_application`; `budget.exceeded` once per period |
| **Team budget** | Every key that belongs to the team, combined | **Monthly**, on the calendar month in UTC | **Configuration → Access → Teams** or **FinOps → Budgets**. Not through the Claude connector | None | HTTP 429 `team_budget_exceeded`; `budget.exceeded` on every refused request |

The alert behavior in the last two columns depends on the gateway version. See [Alerts](#alerts).

A request must fit within every budget that applies to it. A key bound to an application and belonging to a team is refused as soon as any one of its key, application, or team budget is used up.

### Per-key budget

A per-key budget is a **lifetime** spend cap in USD on one key. The gateway adds up everything the key has spent since it was created and refuses the key's requests once that total reaches the budget. It never resets: to let the key spend again, raise or remove the budget, or issue a new key.

| Field | Where | Notes |
| - | - | - |
| **Budget (\$)** | **Create API key** → **Limits** (**Rate limits & budget**) | Optional. Leave blank for no budget. |
| **Budget alert thresholds (%)** | Same step, shown once a budget is entered | Comma-separated percentages of the budget. Default `50,80,100`. |
| **Cap amount (USD)** | **FinOps → Budgets**, on the key's row or with **New cap** | Changes or adds the budget of an existing key. The key's alert thresholds are kept. |

A key's detail panel shows its budget as, for example, **\$1,000.00 lifetime cap**, with its alert thresholds underneath.

<Note>
  The key's edit panel does not change the budget. Use **FinOps → Budgets** or the Claude connector to change the budget of an existing key.
</Note>

### Application budget

An application budget is the **budget** section of an application's policy: a limit in USD and a period. It covers the combined spend of every key bound to the application, so you can budget an agent or a service rather than one credential. A key is bound to an application with the **Application** field of the key (see [API Keys](/platform/configuration/api-keys#key-settings)).

| Field | Where | Notes |
| - | - | - |
| **Monthly budget (USD)** | **Security → Apps** → **New application** (**Protect an application**) | Creates the application's policy with a monthly budget. |
| **Budget (USD)** | **Security → Policy**, policy editor → **Budget** | The cap. Blank means no cap. |
| **Period** | Same section | `Daily`, `Monthly`, or `Total (lifetime)`. |

How the period works:

* **Daily** and **Monthly** windows start when the application first spends under the budget and then roll forward by one day or one month at a time. They do not follow the calendar.
* **Total (lifetime)** never resets.
* The spend counter starts at \$0 when the budget is first used. Spend from before the budget existed is not counted.
* A changed limit applies from the next request once the gateway has the updated policy, usually within a minute. Lowering the limit below current spend blocks the application right away; raising it lets requests through again.

A budget set on the organization-wide or gateway policy is inherited by every application that does not set its own, and each application then has its own counter against that limit. Keys that are not bound to an application are not covered by application budgets.

### Team budget

A team budget caps the combined spend of the keys that belong to a team **in the current calendar month (UTC)**. It resets at 00:00 UTC on the first day of each month.

| Field | Where | Notes |
| - | - | - |
| **Monthly spend limit (USD)** | **Configuration → Access** → **Teams**, in **Create Team** or the team's edit panel | Blank means no limit. See [Access](/platform/configuration/members#teams-tab). |
| **Cap amount (USD)** | **FinOps → Budgets**, on the team's row or with **New cap** | The same limit. |

A team budget counts only keys that belong to the team. A key's team is set when the key is created through the Claude connector (`team_id`); the **Create API key** dialog has no team field.

### How to choose

<AccordionGroup>
  <Accordion title="A hard ceiling on one credential, for its whole life">
    Use a **per-key budget**. Good for a trial key, a contractor, a CI job, or a demo that must never cost more than a set amount. Remember that it does not refill.
  </Accordion>

  <Accordion title="A recurring allowance for an app, an agent, or a service">
    Use an **application budget** with a **Monthly** or **Daily** period, and bind each of the app's keys to the application. Every key draws from the same allowance, and rotating or adding keys does not reset it.
  </Accordion>

  <Accordion title="A monthly allowance for a group of people">
    Use a **team budget**. It follows the calendar month, so it lines up with monthly reports.
  </Accordion>

  <Accordion title="Both a recurring allowance and a lifetime ceiling">
    Combine them. For example, a $500 monthly application budget plus a $2,000 per-key budget on a key you hand to a contractor. The first budget to run out stops the request.
  </Accordion>
</AccordionGroup>

### Setting budgets with Claude

The Claude connector can set per-key and application budgets. It cannot set a team budget: set that in **Configuration → Access → Teams**.

| You want | What Claude does |
| - | - |
| A lifetime cap on one key | Sets the key's budget (`quota.budget_usd`) and, if you ask for them, its alert percentages (`quota.budget_alert_thresholds`), when it creates or edits the key. |
| A daily, monthly, or lifetime budget shared by an application's keys | Creates the key bound to the application (`application_id`), then sets the **budget** section (`limit_usd`, `period`) of the application's policy, or creates the policy if the application has none. |
| A team's monthly budget | Points you to **Configuration → Access → Teams**. |

When a request does not say which kind of budget you mean, for example "create a key with a \$1,000 budget" or "team budget of 1,000", Claude asks first:

> A lifetime cap on this key only, or a monthly or daily budget for an application, shared by all keys bound to it?

Say which one to skip the question:

* "Create a key called `ci-bot` with a **\$20 lifetime budget on the key** that alerts at 80%."
* "Create a key called `support-worker` for the support app, and give the support app a **\$500 monthly budget** shared by all of its keys."

Applications are created only in the dashboard (**Security → Apps**). If the application you name does not exist, Claude asks you to create it there first. Removing a key's budget, or raising or removing an application's budget, loosens a limit: Claude shows what will change and asks you to confirm before applying it.

## Alerts

<Warning>
  **Available from gateway v0.6.4.** `budget.threshold` alerts for any budget, and `budget.exceeded` for application budgets, need this gateway version or later. On older gateways a key's **Budget alert thresholds (%)** are stored but no warning is sent, and an application budget's refusals send `spend.threshold` only. `budget.exceeded` for per-key and team budgets is sent by current gateways.
</Warning>

Budgets send two events, delivered through [Settings → Notifications](/platform/settings/notifications) to webhook endpoints and alert rules.

| Event | When it fires |
| - | - |
| `budget.threshold` | Spend reaches one of the budget's alert thresholds below 100%. A warning only: requests are still served. |
| `budget.exceeded` | The budget starts refusing requests. |

### When each event fires

| Budget | `budget.threshold` | `budget.exceeded` |
| - | - | - |
| **Per-key** | Once per threshold for each budget amount, at the key's **Budget alert thresholds (%)** below 100. Changing the budget re-arms every threshold; adding a threshold arms it. | On **every** refused request. |
| **Application** | At 50% and 80% of the limit, once per threshold per period. A new daily or monthly window, or a changed limit, re-arms them. The thresholds cannot be changed. | Once per period, on the first refused request. Later refusals in the same period send `spend.threshold`. |
| **Team** | Never. Team budgets have no thresholds. | On **every** refused request. |

A threshold of 100% or more is never sent as `budget.threshold`: reaching the budget is reported once, by `budget.exceeded`, when the next request is refused. With the dialog default `50,80,100`, a key sends warnings at 50% and 80% and `budget.exceeded` when it is blocked.

Alerts are evaluated after each request's spend is recorded, never on the request path. An alert that cannot be evaluated is retried on the budget's next recorded spend, and no request is delayed or refused because of it. Several gateway replicas that share one database send each alert once.

### Subscribing

Pick these events in a webhook endpoint's **Events** list, or use them as an alert rule **Condition**:

| You subscribe to | You receive |
| - | - |
| **Spend Threshold** (`spend.threshold`) | `budget.threshold` and `budget.exceeded` |
| **Token Budget Warning** (`tokens.budget_warning`) | `budget.threshold` and `budget.exceeded` |
| Alert rule on `budget.threshold` | `budget.threshold` only |
| Alert rule on `budget.exceeded` | `budget.exceeded` only |

The event's own name is in the delivery, so one receiver can tell a warning from a block.

### Payload

Every `budget.threshold` and `budget.exceeded` payload from a budget carries:

| Field | Meaning |
| - | - |
| `scope` | `api_key` or `application`. |
| `type` | `budget`. |
| `organization_id` | Your organization. |
| `budget`, `limit` | The budget in USD. |
| `spend`, `used` | Spend so far in USD. |
| `threshold` | The threshold crossed, as a percentage (`80` means 80%; `100` on `budget.exceeded`). |
| `percent` | Spend as a percentage of the budget. |

Per kind:

* **Per-key** `budget.threshold`: `key_id`, `key_name`, `key_prefix`, and `team_id` when the key belongs to a team.
* **Application** events: `application_id`, `budget_id`, `period`, `period_start`, and `period_end` for daily and monthly budgets. `budget.exceeded` also keeps the fields its `spend.threshold` carried (`current_spend`, `path`, `budget_enforced`, `streaming`) and adds the refused client's `ip`.
* **Per-key and team** `budget.exceeded`: `key_id`, `type`, `used`, `limit`, `path`, and `ip`; a team refusal adds `team_id`. These do not carry `scope` or `threshold`.

```json Example: per-key budget.threshold theme={null}
{
  "scope": "api_key",
  "type": "budget",
  "organization_id": "6f1c…",
  "key_id": "2b7e…",
  "key_name": "ci-bot",
  "key_prefix": "sk-Mv…",
  "budget": 20,
  "limit": 20,
  "spend": 16.04,
  "used": 16.04,
  "threshold": 80,
  "percent": 80.2
}
```

## How to configure

<Steps>
  <Step title="Decide which budget you need">
    Use the [comparison table](#the-three-kinds-at-a-glance): per key (lifetime), per application (daily, monthly, or lifetime), or per team (calendar month).
  </Step>

  <Step title="Set the budget">
    * **Per key:** **Configuration → API Keys** → **Create Key** → **Limits**: set **Budget (\$)** and **Budget alert thresholds (%)**. For an existing key, use **FinOps → Budgets**.
    * **Per application:** **Security → Apps** → **New application** and set **Monthly budget (USD)**, or open the application's policy in **Security → Policy** and set **Budget (USD)** and **Period** in the **Budget** section. Bind the application's keys with the key's **Application** field.
    * **Per team:** **Configuration → Access** → **Teams**: set **Monthly spend limit (USD)** when creating or editing the team.
  </Step>

  <Step title="Route the alerts">
    In **Settings → Notifications**, create a webhook endpoint subscribed to **Spend Threshold** or **Token Budget Warning**, or an alert rule on `budget.threshold` or `budget.exceeded`. See [Notifications](/platform/settings/notifications).
  </Step>

  <Step title="Check the gateway version">
    Threshold warnings and application `budget.exceeded` need gateway v0.6.4 or later. See [Alerts](#alerts).
  </Step>
</Steps>

## Limits

* **Spend comes from pricing.** A model with no price on [Settings → Pricing](/platform/settings/pricing) costs \$0, so it never moves a budget.
* **The crossing request completes.** Budgets are checked before each request against the spend recorded so far. The request that takes spend past the limit is served, so final spend can end slightly above the cap; the next request is refused.
* **Per-key and team budgets fail closed.** If the gateway cannot read the spend, it answers HTTP 503 `quota_check_failed` rather than serve the request. Application budgets fail open: the request is served.
* **A zero-dollar application budget** refuses every request from the application's keys.
* **Each gateway counts its own spend.** Budgets are measured against the request history in the gateway's own database. Gateways that do not share a database each count only the spend they served, so a key used on two such gateways can spend up to its budget on each.
* **Request retention shortens a per-key "lifetime".** A per-key budget sums the key's requests still in the gateway's local history. With `GUARDWAY_RETENTION_DAYS` set (see [Environment](/guardway-gateway/environment)), requests older than the retention window are deleted and stop counting, so the cap then covers roughly that window instead of the key's whole life.

## FAQ

<AccordionGroup>
  <Accordion title="My key shows a budget but I get no alerts">
    Check, in order:

    1. **Gateway version.** Before v0.6.4, per-key thresholds are stored but never sent. The key's detail panel says "(not sent yet)" next to them.
    2. **Thresholds.** A key created without **Budget alert thresholds (%)** sends no warnings, only `budget.exceeded` when it is blocked. A key created through Claude has thresholds only if you asked for them.
    3. **Only below 100%.** A threshold of 100 is reported as `budget.exceeded` when the key is blocked, not as `budget.threshold`.
    4. **Already sent.** Each threshold fires once per budget amount. A key already past 80% does not warn again until you change its budget.
    5. **Subscription.** The webhook must be subscribed to **Spend Threshold** or **Token Budget Warning**. An alert rule on `budget.exceeded` does not fire on warnings.
  </Accordion>

  <Accordion title="I set a $1,000 budget on a key and it stopped working after a few months">
    A per-key budget is a lifetime cap and never resets. If you wanted a monthly allowance, set an application budget with **Monthly** period and bind the key to the application, or raise the key's budget.
  </Accordion>

  <Accordion title="Why does my team budget never warn me before it blocks?">
    Team budgets have no alert thresholds. You get `budget.exceeded` when the team's keys are refused. For warnings, use an application budget, which warns at 50% and 80%.
  </Accordion>

  <Accordion title="I get a budget.exceeded on every request after my key is blocked">
    Per-key and team budgets send `budget.exceeded` for every refused request. Use an alert rule with a **Cooldown** to limit how often you are notified.
  </Accordion>

  <Accordion title="My application budget doesn't reset on the 1st of the month">
    Daily and monthly application budgets run from the application's first spend under the budget, not from the calendar. Team budgets are the ones that follow the calendar month (UTC).
  </Accordion>

  <Accordion title="Can Claude set a team budget?">
    No. Set it in **Configuration → Access → Teams**. Claude can set per-key and application budgets.
  </Accordion>
</AccordionGroup>

## Related

* [API Keys](/platform/configuration/api-keys) — create keys, set a per-key budget, and bind a key to an application.
* [Access](/platform/configuration/members) — teams and their monthly spend limit.
* [Notifications](/platform/settings/notifications) — webhook endpoints and alert rules that receive budget alerts.
* [Pricing](/platform/settings/pricing) — the per-token prices that budgets are measured in.
* [Spend](/platform/dashboard/spend) — where spend against budgets is reported.


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