> ## 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.

# Alert thresholds

The percentages a cap warns at: whole numbers from 1 to 100, up to ten per cap, each fired once per window and re-armed at the reset.

A threshold is a percentage of a cap's amount. When spend in the cap's window reaches it, the alert fires once and emails every recipient on that cap. A threshold is any whole percentage from 1 to 100; 50, 80 and 95 are the default, not the only choices.

## A warning, not the refusal

A threshold fires on a cap whose hard stop is off, too, and it says the cap was *reached*, never that anything was *stopped*. The refusal is a separate event: the `402` your caller receives, and the notice that a cap refused traffic.

Recovea does both: the warning on the way up, the refusal at the line. Threshold alerts are Team and above; a refusal mails your owners and billing contacts on any plan, Free included, once per budget each month.

## Where you set them

Thresholds are rows on the cap form and on the organization's cap card on **Settings → Organization → Limits**, each row with its dollar figure:

```
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
```

- **The figure is the alert's own arithmetic.** The platform multiplies in whole micro-dollars and rounds down, and reads the cap you type as digits rather than as a floating-point number, so the figure on the row is the figure the email names.
- **The figure moves when the cap moves.** Change the cap in the form and every row's figure changes with it, before you save.
- **The figure is left out rather than guessed.** While the cap field is empty or half-typed, a row shows its percentage alone.
- **No alerts is a state with a sentence:** *"No spend alerts on this cap. A cap still refuses at the cap whether or not you are warned first."*

On a plan below Team, the form keeps the rows, saves your percentages, and says so under them: *"Threshold emails are part of Team and above. On Free we store your percentages and keep them ready; nothing is emailed."* An organization that moves to Team keeps the percentages it already set.

**Who may change them** follows the cap they are on: alerts on the organization's cap are an Owner and Admin act, and alerts on a key's cap are Owner, Admin and Member. A role that cannot change them still sees every row and every figure. [Where a cap is set](https://docs.recovea.ai/products/caps/) has the table.

## The rules

| Rule | What the server does |
| --- | --- |
| whole numbers from 1 to 100 | refuses anything else with the percentage it was given |
| at most ten per cap | refuses the eleventh: *"Each one emails every recipient once per window."* |
| stored ascending | sorts them, however they arrive |
| 0 is refused | refuses it with its own sentence: every cap is already at 0% of itself, so a 0 would fire once and tell you nothing |
| a duplicate is refused | *"… is listed twice. Each threshold fires once per window, so a repeat changes nothing."* |
| an empty list is allowed | the cap refuses at the line with no warning first |
| at most 32 recipients per cap | refuses the thirty-third |

Ten is a limit on mail, not on storage: each threshold emails every recipient once per window, so ten thresholds and thirty-two recipients is at most 320 emails in one period.

## Once per window, and how it re-arms

A threshold fires once per cap, per window period, per percentage. Re-arming needs no job: a new window is a new period, and a new period is a new firing. A weekly cap's thresholds re-arm every Monday at 00:00 UTC because `2026-W36` and `2026-W37` are different periods, not because anything resets them ([Caps and windows](https://docs.recovea.ai/concepts/caps-and-windows/)).

## 100% is reached, not refused

It is the percentage most likely to be added and most likely to be misread. The platform says, the moment a 100 is in the list: *"100% warns you the moment the cap is reached. It is a warning, not the refusal: it fires on a disarmed cap too, and it never means a request was blocked."*

## The wire

`POST` and `PATCH /platform/v1/budgets`, and `PATCH /platform/v1/budgets/{id}/alerts`, take the thresholds in two shapes:

```jsonc
{ "thresholds": [25, 60, 90] }                          // the list
{ "thresholds": {"50": true, "80": true, "95": false} } // the toggles, every client before the list
```

A JSON array never parses as a map, so the two cannot be confused. Leaving the field out means the default, all three of 50, 80 and 95. The toggle shape accepts only those three keys and answers a wrong key with *"Thresholds must be keyed 50, 80, and 95."*

A read of a budget returns `thresholds` as a plain array of integers. `GET /platform/v1/alerts/config` returns `thresholdsPct`, the cap's actual percentages, beside the toggle map for the three default values; a cap stored as `[25, 60, 90]` reports all three toggles as `false`, which is true.
