# AtmoRouter — Budgets

Source: https://atmorouter.dev/docs/budgets

Budgets limit the input and output rates you accept for paid requests, in USD per million tokens. They are not a monthly spending allowance. Open [Dashboard → Budgets](https://atmorouter.dev/dashboard/budgets) to choose your target and minimum discount.

## Estimate tokens before setting limits

Use the [Token Calculator](https://atmorouter.dev/calculator) to compare a hypothetical USD amount across current model price tiers. Choose input only, output only, or a mix by token count. Each estimate uses the input and output prices from one actual tier, with uncached input. The calculator does not make inference requests, deduct credit, or create budgets. Saved account and key rules are not included in its estimates.

The lowest listed tier may have no free capacity. Expand a model to compare other tiers, then set your own rate limits in Budgets. Minimum charges per paid response, cached tokens and actual request sizes can change your effective token count. Free models remain subject to eligibility and quota; estimates are not context or output limits.

## From API key to saved budget

In [API Keys](https://atmorouter.dev/dashboard/keys), choose Manage price budgets beside your key, or Set price budget immediately after creating it. The key is preselected in Budgets. Choose All models, a family, or an exact model, enter your minimum discount, review the price preview, and save. A draft has no effect until saved. Choose the account scope to apply a rule across your keys instead.

The session Playground applies account rules only; it does not use a selected API key. A successful Playground request cannot verify that key’s rules. Use the key in your client for that check. The [setup helper](https://atmorouter.dev/docs/helper) configures clients and does not manage budgets.

## Choose all models, a family, or a model

| Target | Scope fields | Applies to |
| --- | --- | --- |
| All models | scope_type: all; scope_value: empty string | Every eligible marketplace model. |
| Family | scope_type: family; scope_value: model-ID prefix, for example cb | Models sharing the first segment of the model id before /. The displayed family name is not accepted. |
| Model | scope_type: model; scope_value: cbcn/glm-5.3 | One exact catalog model id. |
| API key | Optional api_key_id on any target | Only that owned key; omit for an account rule. Key rules still intersect account rules. |

## How minimum discounts work

A minimum discount of 25% accepts input and output rates at most 75% of that model's current official input and output rates, calculated independently. For illustrative official rates of $2 input and $8 output, the caps are $1.50 and $6 per million tokens. Percentage rules follow current official rates rather than a snapshot's cheapest offer.

```text
input_cap = official_input_rate × (1 − discount_percent / 100)
output_cap = official_output_rate × (1 − discount_percent / 100)
```

Every matching account and API key rule applies, including all-model, family, and model rules. Exact model rate caps, request price headers, and catalog limits also apply. The lowest input cap and lowest output cap win independently. A broader or key-specific rule cannot loosen another limit. Removing a rule leaves every other applicable limit in place.

The percentage must be finite and between 0 and 100. A 0% rule caps rates at official prices; it does not remove the rule. A 100% rule disables paid requests: it does not make paid models free. If an applicable percentage rule cannot be evaluated because official rates are missing or invalid, the paid request is refused without charge.

## Routing wait, offers, and minimum charge

Routing may wait up to 30 seconds for capacity within your caps. This duration is fixed; generation time is additional. Allow time for both routing and generation in your client timeout. If no qualifying offer is available, the request is refused without a charge. A “From” price is the cheapest advertised snapshot offer, not a guaranteed execution price. Availability counts offers, not free capacity. Tier discounts can differ, and a tier above official rates carries a premium.

The paid-request minimum still applies to both holds and settled charges, including cached-input requests. Rate caps are not a cap on the total request cost. Read the current final USD minimum from `minimum_charge`; the amounts in these examples are illustrative. With no saved limits, marketplace requests remain bounded by catalog tiers; stale pricing fails closed. See [Billing](https://atmorouter.dev/docs/billing) for settlement.

## GET /api/dashboard/budgets

Requires a dashboard login session; an inference API key cannot authenticate this API. Returns exact model rate caps in `budgets`, percentage rules in `rules`, and the current `minimum_charge`.

```bash
curl -b jar.txt https://atmorouter.dev/api/dashboard/budgets
```

```json
{
  "budgets": [{"model":"cbcn/glm-5.3","max_input_price":1,"max_output_price":3,"queue_wait_seconds":30}],
  "rules": [{"scope_type":"family","scope_value":"cb","discount_percent":25,"queue_wait_seconds":30}],
  "minimum_charge":0.000001
}
```

## PUT /api/dashboard/budget-rules

Create or replace a percentage rule for the same target and optional owned API key. Requires your dashboard session. Use `scope_type`, `scope_value`, and `discount_percent`. Omit `api_key_id` for the account rule. Queue wait accepts only 30 seconds, defaulting to 30 when omitted.

```bash
curl -b jar.txt -X PUT https://atmorouter.dev/api/dashboard/budget-rules \
  -H 'Content-Type: application/json' \
  -d '{"scope_type":"all","scope_value":"","discount_percent":25,"queue_wait_seconds":30}'
```

To target a family, use `{"scope_type":"family","scope_value":"cb","discount_percent":25}`. Use the first segment of the model id before `/`, for example `cb` for `cb/model-name`. To target one model and key, use the exact model id with `scope_type: model` and add the owned key's `api_key_id`.

## DELETE /api/dashboard/budget-rules

Remove only the matching target and optional API key rule using the dashboard session. Send the same `scope_type` and `scope_value`, plus `api_key_id` if the saved rule belongs to a key. Discount and wait fields are not needed.

```bash
curl -b jar.txt -X DELETE https://atmorouter.dev/api/dashboard/budget-rules \
  -H 'Content-Type: application/json' \
  -d '{"scope_type":"all","scope_value":""}'
```

## PUT /api/dashboard/budgets: exact rate caps

Existing exact-rate budgets remain supported. Send an exact `model`, finite nonnegative `max_input_price` and `max_output_price`, optionally an owned `api_key_id`, and optionally `queue_wait_seconds: 30`. Zero on either rate disables paid requests. These caps intersect percentage rules.

```bash
curl -b jar.txt -X PUT https://atmorouter.dev/api/dashboard/budgets \
  -H 'Content-Type: application/json' \
  -d '{"model":"cbcn/glm-5.3","max_input_price":1,"max_output_price":3,"queue_wait_seconds":30}'
```

## DELETE /api/dashboard/budgets

Using your dashboard session, send `{"model":"cbcn/glm-5.3"}` and optionally `api_key_id` to remove one exact-rate budget. This does not delete percentage rules.

## Per-request price headers

`x-max-input-price` and `x-max-output-price` express final retail USD per million tokens. They can tighten saved limits but cannot raise them. Zero disables paid requests locally. For example, add the headers below to an authenticated inference call; they cap the rates, while the paid-request minimum still applies.

```bash
-H 'x-max-input-price: 1' \
-H 'x-max-output-price: 3'
```
