# Billing webhook payloads

React to balance alerts and settled payments. Events describe billing state; they do not authorize purchases or replace the current balance.

## Subscribe and test

Register a JSON destination and select the billing/subscription events you need. Store its secret on your server and test before relying on notifications. Acknowledge and retain unknown future events without applying a guessed balance change.

- [Verified receiver](https://www.monocrawl.com/docs/webhook-receiver)

- [Billing](https://www.monocrawl.com/dashboard/billing)

## Event fields under data

| Event | Payload fields | Meaning |
| --- | --- | --- |
| billing.low_balance | balance: number; threshold: number; threshold_source: default or custom | Threshold crossing. The default uses 20% of latest settled payment credits, or initial free allowance before payment. Use the supplied threshold. |
| billing.credits_exhausted | balance: number | Once per exhaustion episode. Free reads remain usable; optional extra usage has separate eligibility. |
| billing.purchase_succeeded | payment_id: string; pack: string or null; credits: number; balance: number; source: string when supplied | Settled purchase granted permanent credits. Includes current and historical paths. |
| billing.auto_recharge.succeeded | payment_id: string; credits: number; balance: number | Authorized auto-reload settled. The event name retains auto_recharge for compatibility. |
| billing.auto_recharge.failed | payment_id: string; pack: string | Payment needs attention. Do not infer later success is impossible or start a replacement automatically. |
| subscription.renewed | plan: string; credits_granted: number; carried_over: number; expired: number when supplied | Current allowance reset and historical paths. Historical carry-over fields do not promise rollover on current plans. |
| subscription.ended | plan: string; expired_credits: number when supplied | Legacy event; not every modern cancellation emits it. |
| test.ping | Test payload; no credit grant | Receiver test; do not apply it to your balance. |

Payloads differ across event and settlement paths. Additional fields are allowed. The outer envelope contains id, type and created_at. balance describes emission time and can be stale on delivery.

## Illustrative payloads

**JSON · low balance**

```
{
  "id": "whd_example_low",
  "type": "billing.low_balance",
  "created_at": "2026-09-22T10:00:00.000Z",
  "data": {
    "balance": 180,
    "threshold": 200,
    "threshold_source": "custom"
  }
}
```

**JSON · auto-reload settlement**

```
{
  "id": "whd_example_paid",
  "type": "billing.auto_recharge.succeeded",
  "created_at": "2026-09-22T10:01:00.000Z",
  "data": {
    "payment_id": "pay_example",
    "credits": 5000,
    "balance": 5180
  }
}
```

IDs and values are fictional. Settlement has already changed the Monocrawl balance. Your receiver must not purchase again to apply those credits.

## Recover late or missing notifications

Deduplicate the envelope id in durable storage before acknowledging, and correlate payment_id across event types. Refresh current balance before authorizing new work; do not add credits for every delivery or treat a late balance snapshot as current.

For auto-reload failure, direct the account owner to Billing. Do not silently increase caps, change plans or start replacement purchases. For missing notifications, inspect delivery history and reconcile payment/subscription state. No event does not prove no payment occurred.

The low-balance alert threshold, auto-reload trigger, auto-reload money cap and extra-usage cap are separate. A subscription renewal resets allowance; it is not a permanent top-up. Purchased balances do not expire at an allowance reset.

- [Credit lifecycle](https://www.monocrawl.com/docs/credits)

- [Auto-reload recovery](https://www.monocrawl.com/docs/auto-reload)

- [Retries and rotation](https://www.monocrawl.com/docs/webhook-receiver#recovery)
