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.
On this page
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 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).
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:
{ "thresholds": [25, 60, 90] } // the list
{ "thresholds": {"50": true, "80": true, "95": false} } // the toggles, every client before the listA 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.