Skip to main content

Troubleshoot NUMBER_MONTHLY_SPEND_CAP_EXCEEDED (402)

The per-number monthly spend cap is a budget you pin on a single DID. When that number’s outbound SMS spend for the current UTC calendar month reaches the ceiling, further sends from that number are refused with 402 and code NUMBER_MONTHLY_SPEND_CAP_EXCEEDED. Nothing is dispatched and nothing is billed. The diagnostic tell: one sender returns 402 while every other number on the account sends normally and the wallet reads healthy. The fix lives on the number itself. Customers who search for “spend cap” usually land on the org-level page first, but the org-level fixes there do not clear this refusal, because this cap is scoped to one number and evaluates independently of your tenant balance.
This page covers the per-DID cap only. Org-level daily ceilings and per-campaign ceilings refuse with 429 and are covered by spend-cap refusals. The wallet balance gate is INSUFFICIENT_BALANCE (402).

The 402 vs the org-level cap codes

NUMBER_MONTHLY_SPEND_CAP_EXCEEDED fires per-DID, independent of tenant balance: a fully funded wallet and untripped org ceilings still refuse the send once the number’s own budget is exhausted. That is the control working as designed when you capped a number to contain its spend, and it is why topping up the wallet or raising an org ceiling never clears this 402.

What fires

The cap is checked before each send, ahead of dispatch. When the number’s month-to-date spend has reached the cap, the send is refused pre-flight with the envelope below (values shown for a number capped at $250.00):
The refused request never leaves the platform and is never billed. The counter the gate reads covers the number’s outbound SMS spend for the current UTC calendar month, incremented by the exact charged amount each time a send from the number is accepted, so it tracks actual spend rather than an estimate.
Don’t blind-retry this 402 within the same month. The counter only moves down at the UTC month rollover, so a retry loop returns the same refusal and burns your rate-limit budget on top.

Read the current state

  • The ceiling. monthly_spend_cap_cents is the cap you set on the number, in US cents; absent or null means the number is uncapped and this gate can never fire for it. The refusal’s details.monthly_spend_cap_cents echoes the live ceiling.
  • The running spend. details.month_to_date_cents is what the number has spent so far this UTC calendar month. The remaining budget is the difference between the two fields.
  • The reset. The counter is keyed to the UTC calendar month: on the 1st of each month (UTC) it starts at zero and sends from the number resume with no action from you. If refusals stop exactly on the 1st, the cap did its job and nothing is broken.

Fix it

Raise or clear the cap on the number

The ceiling is a field on the number, written with the standard number update: monthly_spend_cap_cents accepts an integer from 1 to 100000000 cents (up to $1,000,000), or null to remove the cap and return the number to the default uncapped behavior. The full parameter reference lives in the Numbers API reference.
The change applies immediately: the next send from the number is evaluated against the new ceiling. Send "monthly_spend_cap_cents": null only when you intend to retire the budget entirely, because the cap is the control that contains that number’s spend. The cap is a number setting, gated like every number mutation by org ownership: the credential making the update must belong to the organization that owns the DID. Where your team reserves number management to owners and admins, have an owner or admin apply the change.

Rotate traffic to a second number

The cap binds one DID, so a sibling number with budget headroom is unaffected. Point the affected traffic’s from at another SMS-capable number you own and sends resume immediately while the capped number waits for its reset. This is the right path when the cap is deliberate (a client’s budget, a campaign envelope) and the overflow traffic is legitimate.

Wait for the UTC reset

If the spend was intended, the refusal clears on its own at the 1st-of-month UTC rollover with no configuration change.

Separate it from the other refusals

  • INSUFFICIENT_BALANCE (402) is wallet-side: every send on the account fails, not one sender, and a top-up clears it. See INSUFFICIENT_BALANCE (402).
  • Org spend caps (429) (SMS_DAILY_SPEND_CAP and the related codes) gate the whole organization or a campaign per UTC day, reset daily, and are raised from Billing alert rules. See spend-cap refusals.
  • NUMBER_MONTHLY_SPEND_CAP_EXCEEDED (402, this page) gates one number per UTC month. A wallet top-up does not clear it and an org-ceiling raise does not clear it; only a change on the number (raise, clear, rotate) or the month rollover does.

When to escalate

Escalate when the 402 persists after you raised or cleared the cap, or after the UTC month rolled over. Include:
  • Your tenant ID (GET /api/v1/me → organizationId).
  • The refused number in E.164 and the current monthly_spend_cap_cents on it.
  • The exact code and the request ID of one refused send.

See also