# Budgets and limits

> Cap or watch what your organisation, a project or a gateway key spends on browsers and sandboxes each month, and the limits on concurrent sessions and requests.

Web page: https://kuiper.sh/docs/budgets/

## Budgets

A budget caps or watches what the organisation, one project or one [gateway key](https://kuiper.sh/docs/gateway-keys.md) spends in a calendar month (UTC). Owners and admins set budgets in the **Budgets** section of the organisation's **Usage** page, or with the CLI. Members see budgets without amounts.

```sh
kuiper budgets create --scope org --limit 200                    # block at $200
kuiper budgets create --scope project -p proxima --limit 20 \
  --action notify --notify-at 50,90                              # alerts only
kuiper budgets create --scope key --key gk_… --limit 5
kuiper budgets                                                   # spent, limit, alerts
kuiper budgets set bud_… --limit 40
kuiper budgets rm bud_…
```

| Setting | |
| --- | --- |
| `--scope` | `org`, `project` (with `-p`) or `key` (with `--key`, the key's `gk_…` ID). |
| `--limit` | US dollars a month. |
| `--action` | `block` (the default) refuses new browser sessions and sandboxes once the budget is used up. `notify` only alerts. |
| `--notify-at` | Percentages of the limit to alert at. The default is `50,80,100`. |

### What counts

- **The organisation or a project:** everything it is billed for this month, the same total as the **Usage** page, plus what its live browser sessions and sandboxes hold.
- **A key:** the browser sessions, quick actions, proxy traffic and sandboxes made with it.

### How a budget blocks

- **Holds.** A new or resumed browser session or sandbox holds its first hour, or its whole timeout if that is shorter, at its price. A quick browser action holds its own price. A `block` budget refuses whatever wouldn't fit with **402** `budget_exceeded`. The hold itself is never charged: you pay for the time a session or sandbox actually ran.
- **Long sessions** hold one hour at a time. At the end of each hour, a session or sandbox whose `block` budget can't pay for the next hour is released with `releaseReason: "budget_exceeded"`.
- **Extending** a sandbox's timeout holds what the extension adds to its current hour.
- Kuiper's gateways learn what has been spent every few seconds. When several gateways serve you at once, a budget can be overshot by what they admit in those seconds.

### Alerts

Each percentage in `--notify-at` is recorded once a month, in the activity log and as a banner across the dashboard. A `notify` budget does nothing else.

When a budget is deleted, its spend history stays. A budget on a project or key is deleted with that project or key.

## Limits

Limits protect everyone from runaway agents. They apply whatever your budgets say.

| Limit | Default | Past it |
| --- | --- | --- |
| Live browser sessions per organisation | 10 | **429** `too_many_sessions` |
| Live sandboxes per organisation | 10 | **429** `too_many_sandboxes` |
| Requests to the browser API per key | 300 a minute | **429** `rate_limited` |
| Requests to the sandbox API per key | 600 a minute | **429** `rate_limited` |

- Hibernated sessions and sandboxes don't count towards the concurrent limits.
- Request limits don't count CDP and live-view traffic, or traffic to a sandbox's exposed ports.
- Every 429 carries `Retry-After`, in seconds.
- If you need higher limits, ask Kuiper.

Kuiper can also stop an organisation's browsers or sandboxes, for example after abuse. Creating or resuming one then answers **403** `browsers_stopped` or `sandboxes_stopped`, and live ones end with `releaseReason: "stopped_by_admin"`.

## Reading a refusal

Every refusal has a `code`, so a client can tell a budget from a limit:

| Status | `code` | What to do |
| --- | --- | --- |
| 402 | `budget_exceeded` | Raise the budget, or wait for next month. |
| 429 | `too_many_sessions`, `too_many_sandboxes` | Release or hibernate one, then retry. |
| 429 | `rate_limited` | Wait `Retry-After` seconds. |
| 403 | `browsers_stopped`, `sandboxes_stopped` | Contact Kuiper. |
