Spend caps on the dashboard
Your spend cap is the ceiling you set on your own prepaid wallet — separate from the platform fraud envelope every send is measured against. This page walks the full loop: where the cap panel lives and how it relates to the wallet, how to set a monthly budget and threshold rules with real hard cutoffs, how to rehearse the over-cap path in sandbox before it fires on live traffic, what an over-cap send returns, and the three recovery levers available when one trips.1. Where the cap panel lives — and how it relates to the wallet
Everything tenant-owned lives under Billing → Alerts in the dashboard. The page holds two controls:- The monthly-budget card — a dedicated card at the top of Billing → Alerts with an inline editor. It stores org
monthly_budget_cents, the denominator everyspend_percentrule computes against. The same value is editable under Settings → Account → General (both surfaces write one value). Until you set it,spend_percentrules report themselves inapplicable and the dashboard disables the percent option with a “set a monthly budget first” pointer. - The alert-rules list — the threshold rules themselves: metric, threshold, recipients, action, cooldown. Create, read, and dry-run them here.
2. Set a cap: budget first, then a layered rule set
Step 1 — set the monthly budget. Without it, percent-based rules are inert. There is no public budget endpoint — set it on the monthly-budget card in Billing → Alerts, or under Settings → Account → General. Rules created via the API read the same value either way. Step 2 — create the rules. The API surface isGET/POST /api/v1/billing/alerts[/:id], plus POST /:id/test-fire for a no-side-effects dry run — all mirrored on the dashboard. This example builds a two-layer ladder: a soft notification at 70%, and a hard pause at 90%:
spend_percent (share of monthly budget), spend_amount (month-to-date cents), daily_spend (today’s cents), and balance_remaining (a floor, compared less-than). A layered set keeps any single threshold from being your only line of defense: the 70% notify gives you hours of warning, so the hard 90% stop — when it does fire — is never a surprise.
Hard vs soft cutoff. The action chooses the cutoff character:
notify— soft. Recipients get email/SMS; traffic untouched. Use for warning bands.pause_outbound— hard. Sets the org’s outbound-paused flag; new sends return 402SENDING_PAUSEDuntil a human clears the alert in the dashboard.block_outbound— hard, operator-reviewed. The stricter gate used when the stop should hold until someone looks at it, not just until someone clicks clear.
POST /api/v1/billing/alerts/:id/test-fire evaluates a stored rule against today’s spend and balance and reports whether it would trigger — without notifying anyone, stamping the rule, or gating traffic. Test-fire every new rule before it guards real traffic.
The field-by-field reference (validation ranges, the worked 201 create response, cooldown semantics) is Spend caps, budget alerts, and auto-cutoff. Steps below stay deliberately thin and point there.
3. Rehearse the over-cap path in sandbox
A pause rule is only tested when it fires, and firing it on live traffic costs a real incident. Rehearse it against a sandbox key (dv_test_sk_*):
- Calc the probe size. Set the sandbox budget to a small value (e.g. $5). One message to a magic-number recipient resolves
deliveredper the sandbox magic-numbers table (for pause drills you do not need a failure scenario — you need a countable, cheap send). The what-if preview endpoint from api-recipes task 22 prices a send before you fire it. - Arm a low threshold. Create a
spend_amountrule with a threshold of one message’s cost (or adaily_spendrule with a handful of cents) andaction_on_hit: "pause_outbound". Low thresholds in sandbox are free; in production this same shape is how you test without touching live traffic. - Send until the tick trips. Fire one sandbox send per the numbered example below; wait for the billing scheduler’s 10-minute tick to evaluate; watch the recipients receive the rule’s name plus the observed value, then confirm the paused flag.
- Read the state.
GET /api/v1/billing/alertsshows the rule’slast_triggered_atstamped; the dashboard wallet header shows the org paused.
4. What happens on over-cap
The response differs by layer, and reading the error code wrong is the most common misdiagnosis:
Suppression behavior: the refusal happens before the channel leg dispatches, so an over-cap send never reaches the carrier, never debits the wallet, and never generates a delivery receipt. Your webhook sees nothing for the refused send — the 402 response is the entire signal. If the send path retries, it re-fails against the gate; dedupe is on you via idempotency.
Full remediation code-by-code lives in Troubleshooting: billing-gate outbound blocks; the wallet-empty branch is Troubleshoot INSUFFICIENT_BALANCE (402).
5. Recover: raise the cap, top up, or split traffic
Three levers, in order of use:- Raise the cap. When the rule was too tight for legitimate volume, edit the rule’s
threshold_valuein Billing → Alerts, then clear the tripped gate withPOST /api/v1/billing/alerts/reset-outbound(owner or admin; the dashboard’s clear button calls the same route). The gate re-arms once you have cleared, with the new threshold in effect from the next tick. - Top up. When a
balance_remainingfloor orINSUFFICIENT_BALANCEwas the stop, auto top-up keeps the wallet funded at a chosen trigger level so the floor rule trips less; manual top-up ends the current stoppage immediately. - Split traffic. When one sender profile keeps smashing the org-wide line, move it to a sub-account with its own monthly latched cap (reseller pattern, Spend caps §4) — the blast radius shrinks to that child account and the rest of the org keeps sending.
6. Per-channel and per-scope caps
- Org-wide rules (
Billing → Alerts) measure one org-wide metric — there is no per-country org alert; the metric family covers percent/amount/daily/balance, not destination. - Agent LLM spend has its own daily USD cap under Settings → Agents (
GET/PUT /api/v1/settings/agents/spend-cap) — the details are in Spend caps §3, refused withAGENT_DAILY_SPEND_CAP_REACHED(429). - Sub-accounts (resellers) get a hard per-child monthly latch that stays tripped until a new UTC month or a refund releases it — per destination without per-country selection.
- The fraud envelope’s per-channel daily ceilings exist precisely because org alert rules are global — they take up the per-channel slack your rules cannot express.
7. Pair with anomaly rules and recipes
The usage-anomaly rules (spend, outbound volume, delivery rate) are read-only over your ledger — they fire-event feeds and Notification Center pings, never gate. Cross-link them on top of a hard cap exactly as the fixed-threshold / detector pairing is done intentionally: the anomaly tells you where to look, the cap enforces while you look. Two useful recipes from api-recipes: task 22 prices a send before you fire thresholds (the sandbox drill above), and the errors-as-recipes table maps the refund/retry semantics of 402 codes to your clients.8. Next: API-level budgets
The spend cap guards money. To guard request volume per API key — a leaked-key or runaway-integration signal that shows up before any spend moves — set the per-key monthly quota and usage-alert thresholds in Per-API-key usage budgets and threshold alerts. An org can be well under its spend cap while one key is burning through a quota; the two layers are complementary and both are tenant-owned.For the endpoint-by-endpoint field reference see Spend caps, budget alerts, and auto-cutoff and the Billing API reference.