# balance.empty

Balance billing only. The balance reached $0 and no auto top-up covered it (auto top-up off, the card declined, or the monthly limit reached), so new pay-per-use (SMS, calls, numbers, X and the rest) answers 402 with `code` until the balance is funded.

### When it fires

Once per time the balance runs out, within about a minute of the usage that emptied it. Funding the balance and running out again fires it again.

### Who receives it

The billing owner's endpoints, like `balance.low`. Restricted keys need the `money` resource group.

### How to act

Send the user to `fundingUrl`, or, for `usage_limit_reached`, raise `monthlyLimitCents` with `PATCH /v1/balance/auto-recharge`.




**Payload for `balance.empty`:**

- **id** (required) `string`: Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.
- **test** `boolean`: Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.
- **event** (required) `string`: No description - one of: balance.empty
- **balance** (required) `object`: 
  - **spendableCents** (required) `integer`: What pay-per-use can spend, in USD cents: 0 or below (usage already in flight can take it under 0).
- **code** (required) `string`: The 402 code pay-per-use calls get until the balance is funded. `usage_limit_reached` when the auto top-up monthly limit is what keeps it at $0. - one of: insufficient_balance, usage_limit_reached
- **fundingUrl** (required) `string` (uri): Dashboard link that opens the top-up drawer in Billing.
- **timestamp** (required) `string` (date-time): UTC time at which Zernio generated this event. Retries and redeliveries keep the original value.