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

# Troubleshoot spend-cap refusals (SMS_DAILY_SPEND_CAP, CHANNEL_DAILY_SPEND_CAP, VOICE_DAILY_SPEND_CAP, CAMPAIGN_VOICE_SPEND_CAP_REACHED)

> Your sends stopped because a spend cap fired — determine which cap tripped, raise it, and separate the tenant-owned daily/campaign caps from insufficient-balance 402s, warming caps, and agent cost controls.

# Troubleshoot spend-cap refusals

Spend-cap refusals are **tenant-owned ceilings you (or the platform fraud guard) set** — they differ from the wallet balance gate (`INSUFFICIENT_BALANCE` 402) and from warming caps on new numbers. When a send, call, or campaign launch is refused with one of the codes below, the request never leaves the platform pre-flight; nothing is dispatched and nothing is billed beyond the estimate hold.

This page answers: **which cap fired, where the ceiling is raised, and how to tell this apart from a balance 402 or a warming 429.**

<Note>
  A **warming cap** (`DAILY_CAP_EXCEEDED` / `WARMING_QUOTA_EXCEEDED` on a fresh 10DLC number) is a carrier-side ramp gate — see
  [number warming caps](/troubleshooting/number-warming-caps). This page covers the paid-envelope spend ceilings only.
</Note>

## The enforcement codes

Every spend-cap refusal is a `429` on the synchronous send path. Campaign voice caps also auto-pause the campaign.

| Code                               | Asset gated                                                                                                                   | HTTP status | Where the ceiling is set                                                                                                                                                                                                          | Tenant control                                                                                                                                               |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SMS_DAILY_SPEND_CAP`              | Outbound SMS / MMS segments for the tenant, summed against an estimate-per-segment counter, per UTC day.                      | 429         | `Settings → Billing → Alerts` and the API (`POST /api/v1/billing/alerts` with `threshold_type: "daily_spend"`). The platform fraud guard also enforces `env.DEVOTEL_SMS_MAX_DAILY_SPEND_CENTS` when no org ceiling is configured. | Raise or clear the daily-spend alert rule, or split send traffic across numbers so a single-day estimate stays under the threshold. Resets at UTC midnight.  |
| `CHANNEL_DAILY_SPEND_CAP`          | Per-channel envelope (SMS / MMS / WhatsApp / RCS / Email / etc.) summed against the same estimate-based counter, per UTC day. | 429         | Cross-channel fraud guard — `env.DEVOTEL_<CHANNEL>_MAX_DAILY_SPEND_CENTS` per-channel ceilings, or an org-configured daily-spend alert rule one level up.                                                                         | Same as the SMS code: raise the ceiling or re-route to another channel.                                                                                      |
| `VOICE_DAILY_SPEND_CAP`            | Outbound voice minutes summed against the per-minute counter for the tenant, per UTC day.                                     | 429         | Voice fraud-guard daily-spend ceiling (`env.DEVOTEL_VOICE_MAX_DAILY_SPEND_CENTS`) raised in the Settings → Billing → Alerts spend rules.                                                                                          | Raise the ceiling, or route concurrent dial traffic across trunks so the aggregate estimate stays under it. Resets at UTC midnight.                          |
| `CAMPAIGN_VOICE_SPEND_CAP_REACHED` | One dialer campaign — calls placed by the campaign burn against `campaigns.voice_spend_cap_cents`.                            | 429         | Campaign config on the campaign row (`voice_spend_cap_cents`). When the cap trips, the campaign auto-pauses (`status: paused`).                                                                                                   | Raise the campaign cap, or split the call list across sister campaigns (campaigns are isolated envelopes). The campaign stays paused until you re-enable it. |

## Distinguish spend-cap refusals from balance and warming gates

Three different 4xx families stop outbound traffic. Work the descriptions against the error code returned by the API:

* **`INSUFFICIENT_BALANCE` (402)** — the **wallet pre-flight** couldn't cover the estimate hold. You are out of **money on account**: either top up, or let auto-top-up fund the wallet. The gateway halts **before** any spend ceiling is considered. See
  [INSUFFICIENT\_BALANCE (402)](/troubleshooting/insufficient-balance).
* **Spend-cap `429` (this page)** — the wallet was funded, but the tenant-owned daily or campaign **ceiling** evaluated before the send left the platform. You are out of **budget room**, not wallet balance: raising the ceiling (or the campaign cap on a dialer row) clears the refusal without touching wallet funds. Triggering when `balance_cents` reads fine is the diagnostic tell.
* **Warming cap `429` on a fresh number** (`DAILY_CAP_EXCEEDED` / `WARMING_QUOTA_EXCEEDED` / `NUMBER_MPS_EXCEEDED`) — the carrier-side ramp on a newly acquired 10DLC sender, unrelated to balance or org ceilings. See
  [number warming caps](/troubleshooting/number-warming-caps).

## Worked example — agency hitting a per-campaign voice cap

You run a dialer campaign on behalf of a client with a hard spend limit. The campaign's `voice_spend_cap_cents` is the campaign row's ceiling; the dialer launches each call only after it claims against the campaign counter.

1. Call #412 returns `429 CAMPAIGN_VOICE_SPEND_CAP_REACHED` and the dialer pauses the campaign (`status: paused`).
2. Read the campaign row (`GET /api/v1/campaigns/:id`) — the ceiling is on the campaign, not the org.
3. Either raise `voice_spend_cap_cents` on the campaign (the client raised their cap), or split the remaining call list into a sister campaign (tenant-owned envelope isolation).
4. Re-enable the campaign (`PUT /api/v1/campaigns/:id` with `status: "active"`).

The same isolation principle covers a tenant that can't raise an org-level daily-spend alert: route the overflow through a new campaign or number envelope rather than looping the same refusal.

## Where daily spend surfaces

Three dashboard/API surfaces surface today's spend before the refusal arrives:

* **Billing → Alerts** — the spend-alert rules (`daily_spend` / `spend_amount`) you chose. When a rule trips it either notifies or pauses/blocks outbound (`SENDING_PAUSED` 402) — text notifications come from
  [usage & delivery anomaly alerts](/billing/usage-anomaly-alerts) on the **Spend** metric if configured against the wallet.
* **`GET /api/v1/me`** header → dashboard Billing widget — the current outbound-paused flag and running balance, so operators see a cut-off org before they trip the pause code.
* **Billing → Alerts → clear the alert** re-arms outbound once a pause/block alert fired and the enforced envelope is re-admitted.

## When to escalate

Escalate when the refusal persists **after** you raised the ceiling on the surface the response names. Include:

* Your **tenant ID** (`GET /api/v1/me` → `organizationId`).
* The **exact code** and the **request ID** of one refused call.
* For a campaign voice cap: the **campaign ID** and the current `voice_spend_cap_cents` ceiling.

Do **not** blind-retry a `429` spend refusal: unlike a warming reset it never re-evaluates until you raise the ceiling, so a retry loop burns your queue and trips the per-second rate guard on top.

## See also

* [Spend caps, budget alerts, and auto-cutoff](/billing/spend-caps) — how the alert rules, resumable pause/block, and the sub-account monthly latch are configured.
* [INSUFFICIENT\_BALANCE (402)](/troubleshooting/insufficient-balance) — the wallet pre-flight the spend gate short-circuits before.
* [Number warming caps](/troubleshooting/number-warming-caps) — carrier-side ramp refusals for fresh 10DLC numbers.
* [Agent cost controls](/agents/cost-controls) — per-run/per-conversation LLM ceilings (`COST_LIMIT`, `CONVERSATION_COST_CAP_REACHED`) separate from the wallet envelope.
* [Error codes reference](/reference/error-codes) — the canonical list of every enforcement code.
