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

# Where a cap is set

Every place a cap is set in the platform, who may change which cap, the four-field form, the five windows, and the scope on the wire.

> **A cap belongs to the thing it bounds, and every cap is reviewed in one place.** The organization's own caps and every key's caps live on **Settings → Organization → Limits**. A key's cap can also be set on that key's own row in **Settings → Organization → API keys**, and on the reveal step when the key is minted.

What a cap does on the wire is [Cap](https://docs.recovea.ai/products/cap/). This page is where it is set and who may set it.

## Where a cap is set

| Scope | Where | Control |
| --- | --- | --- |
| The whole organization | **Limits**, *Organization caps* | **Set a cap on this organization**, then **Add a cap on another window**, and **Edit** on each |
| One API key | **Limits**, *Caps on keys* | **Add a cap**, which opens a picker of your keys, and **Edit** |
| One API key, from the key | **API keys**, on the key's own row | **Cap**, or **Add a cap** when it has one, and the cap line links back to Limits |
| One API key, at mint time | the mint dialog's reveal step | **Set a cap on this key (optional)** |

There is no field to type a key id into: a key is always picked. The old `/budgets` address redirects to the Limits page.

## Who can change what

Five roles, enforced by the server. A role that cannot act sees the cap, its figures and its alerts, and no control.

| Action | Owner | Admin | Member | Billing | Viewer |
| --- | --- | --- | --- | --- | --- |
| The organization's cap: set, edit, arm, disarm, delete | yes | yes | view | no | view |
| Spend alerts on the organization's cap | yes | yes | view | no | view |
| A cap on a key: set, edit, arm, disarm, delete | yes | yes | yes | no | view |
| Spend alerts on a key's cap | yes | yes | yes | no | view |
| Mint, rotate, revoke a key | yes | yes | yes | no | no |
| Read the Limits page | yes | yes | yes | no | yes |

- **The organization's cap is an Owner and Admin act.** A Member who tries is refused `403` with `error.code` `forbidden` and the sentence *"Only owners and admins can change the organization cap."*
- **A Member keeps every key cap.** A Member sets, arms, disarms and deletes caps on any key in the organization.
- **Billing does not see caps.** The Limits page says so instead of failing: *"Your role can see billing, not caps. Limits are part of the organization’s operating surface."*

The whole matrix is [Roles](https://docs.recovea.ai/concepts/roles/).

## The Limits page

`/settings/organization/limits`, top to bottom:

1. **On Free, the ceiling note.** Caps work on Free; what Free carries is a ceiling on a cap's amount, and *"An armed cap always fires, on every plan; the kill switch has no ceiling."* The figure is on [the pricing page](https://recovea.ai/pricing).
2. **A warning, when it applies:** *"Some caps below have armed thresholds and no recipients — they still fire and are recorded, but email nobody. Edit to add an address."*
3. **Organization caps**: one card per window the organization has a cap on. A cap is per scope and window, and two caps on two clocks have no total, so they are never added up.
4. **Caps on keys**: a table, one line per cap, so a key with a daily and a lifetime cap has two lines, each with its own **Edit**.

### The organization cap card

```
Organization, monthly                                        [ Edit ]
Organization · Per month · $8,000.00

$4,581.60 of $8,000.00
$3,418.40 left
[▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░]
Resets in 12 days · Oct 1, 00:00 UTC · Sep 30, 6:00 PM MDT

SPEND ALERTS
Alert when spend reaches 50% ($4,000.00)              Edit   Delete
Alert when spend reaches 80% ($6,400.00)              Edit   Delete
Alert when spend reaches 95% ($7,600.00)              Edit   Delete
+ Add an alert
Alerts go to ken@… and 2 others.

Enforce a hard stop  [ ●───]  Armed                          Delete
```

- **What is left comes from the server**, and the platform never computes it. Past the cap, the second line says how much over instead of how much is left.
- **No measurement means no number.** A scope with nothing counted shows a dash, never a zero.
- **The bar only repeats the lines above it**, and turns from neutral to amber at your own lowest alert threshold, then red.
- **The reset line gives the interval, the UTC instant, and the same instant in your own clock.** The interval rounds down: 12.9 days to go reads "in 12 days". A lifetime cap reads *"Does not reset. Counts every dollar since the cap was created."*

## The cap form

One form, whichever door opens it, with four fields:

1. **The amount and the window**, one labelled group: *Daily cap*, *Weekly cap*, *Monthly cap*, *Yearly cap*, *Lifetime cap*.
2. **Enforce a hard stop**: one toggle. On arms the cap; off leaves it counting and alerting, refusing nothing.
3. **Spend alerts**: rows, each with its dollar figure ([Alert thresholds](https://docs.recovea.ai/concepts/alert-thresholds/)).
4. **Alert recipients**.

Above the fields, a sentence says what the cap is on; the scope is fixed by the door you came in through. Under **Advanced** are the cap's name, derived from the scope and window (*"Organization, monthly"*) until you type your own, and **At the cap**, shown while the hard stop is on: **Block (402)** or **Pause (429 with Retry-After)**.

Turning the hard stop off and moving the cap to another window work in one save, because the form disarms before it saves and arms after.

## The five windows

A cap names the clock it runs on. Every window opens and closes at 00:00 UTC.

| Window | Period key | Resets |
| --- | --- | --- |
| `day` | `YYYY-MM-DD` | every UTC midnight |
| `week` | `YYYY-Www`, the ISO week | every Monday, 00:00 UTC |
| `month` | `YYYY-MM` | the 1st, 00:00 UTC |
| `year` | `YYYY` | 1 January, 00:00 UTC |
| `lifetime` | `all` | never |

`month` is the default. One scope may carry several caps on different windows, a daily and a lifetime cap on one key, and the tightest decides. [Caps and windows](https://docs.recovea.ai/concepts/caps-and-windows/) has the detail, including what the week's key does at the turn of the year.

### The year asks first

A yearly cap alerts by default. Making it a hard stop takes a second, explicit act on every path: the switch asks and a second click arms; the form's toggle asks the same question before it saves; an armed cap cannot be moved onto the year from the edit form without disarming first; and the arm call itself is refused without `confirmHardStop=true`. A year is the window where a mistaken hard stop can stop a company's traffic for the longest.

## The wire

The platform calls these routes with your signed-in session:

| Route | What it does |
| --- | --- |
| `GET /platform/v1/budgets` | every cap, with what is used and left |
| `POST /platform/v1/budgets` | create a cap |
| `PATCH /platform/v1/budgets/{id}` | edit a cap |
| `DELETE /platform/v1/budgets/{id}` | delete a cap |
| `POST /platform/v1/budgets/{id}/arm` | turn the hard stop on; a yearly cap needs `confirmHardStop=true` |
| `POST /platform/v1/budgets/{id}/disarm` | turn the hard stop off |
| `PATCH /platform/v1/budgets/{id}/alerts` | change the alert thresholds |

The scope is an object. The organization's cap:

```jsonc
{
  "name": "Organization, monthly",
  "scope": { "type": "organization" },
  "window": "month",
  "capUsd": 8000,
  "mode": "block",
  "thresholds": [50, 80, 95],
  "recipients": ["ken@example.com"]
}
```

A cap on one key:

```jsonc
{
  "name": "Production, weekly",
  "scope": { "type": "key", "keyId": "key_0192f3a4b5c6d7e8f9a0b1c2d3e4f5a6" },
  "window": "week",
  "capUsd": 150,
  "mode": "block"
}
```

`keyId` is the key's record id, `key_` and 32 hex characters, never the secret. The `rcv_live_…` secret is shown once and not stored, so it can never be what a cap names.

> **On the wire the scope is still spelled `workspace`, and it is what a read emits.** `{"type": "organization"}` is accepted as an alias on **input**, everywhere `{"type": "workspace"}` is, on create and on patch; a read of the same budget answers `{"type": "workspace"}` byte for byte, unchanged. Both spellings name the same scope. Retiring the old one on the wire is a versioned API change with its own ticket, not something this rename did.

`thresholds` is your list of alert percentages, and its default is 50, 80 and 95.
