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

# Real-Time Billing

> Debit a customer's prepaid wallet continuously as usage accrues — typically within ~5 seconds — instead of waiting for period end. The customer watches their balance draw down in real time; the period closes with a single paid summary invoice.

With **postpaid** and **prepaid** billing, the customer is charged at period end. **Real-time billing** charges them *as they go*: as usage events arrive, Monigo reconciles the running cost and debits the customer's prepaid wallet — typically within **\~5 seconds** — so the balance always reflects exactly what has been consumed so far. There's no invoice to chase and no end-of-period bill surprise; the customer only ever spends what they've already funded.

Real-time billing works best for:

* AI and agent products metered by tokens, calls, or seconds
* Pay-as-you-go APIs where customers fund a balance and draw it down
* Any product where you want the customer to watch their balance decrease live

<Info>
  Real-time billing is wallet-backed: it reuses the same prepaid wallet, pause-on-empty, and auto-resume-on-top-up machinery as [Prepaid Billing](/guides/prepaid-billing). The difference is *when* the wallet is debited — continuously, rather than once at period end.
</Info>

<Note>
  For a complete, copy-paste integration walkthrough using an AI agent as the example — customer creation, metric, plan, wallet widget, and event ingestion — see the [AI Prepaid Wallet](/guides/ai-prepaid-wallet) guide. This page focuses on the billing mode itself.
</Note>

## How it works

```mermaid theme={null}
flowchart TD
    A[Usage Event Ingested] --> B[Metering Hook<br>marks subscription dirty]
    B --> C[Flush Worker<br>drains dirty set every ~5s]
    C --> D["Reconcile:<br>marginal = price of total usage − charged so far"]
    D --> E{Wallet Covers Marginal?}

    E -->|YES| F[Wallet Debited Atomically]
    F --> G[charged_amount Updated]
    G --> A

    E -->|NO| H[Subscription Paused<br>+ further events blocked]
    H --> I[/subscription.prepaid_balance_insufficient<br>webhook fired/]
    I --> J([Customer Tops Up Wallet])
    J --> K[Auto-Resume<br>charge residual usage]
    K --> A

    L[Period Ends] --> M[One 'paid' Summary Invoice<br>no extra debit]
    M --> N[/invoice.paid webhook fired/]

    style A fill:#1F2937,color:#fff,stroke:#374151
    style B fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style C fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style D fill:#F3F4F6,color:#1F2937,stroke:#6B7280
    style E fill:#F3F4F6,color:#1F2937,stroke:#6B7280
    style F fill:#DCFCE7,color:#14532D,stroke:#16A34A
    style G fill:#DCFCE7,color:#14532D,stroke:#16A34A
    style H fill:#FEE2E2,color:#991B1B,stroke:#EF4444
    style I fill:#FEE2E2,color:#991B1B,stroke:#EF4444
    style J fill:#EFF6FF,color:#1E40AF,stroke:#3B82F6
    style K fill:#EFF6FF,color:#1E40AF,stroke:#3B82F6
    style L fill:#1F2937,color:#fff,stroke:#374151
    style M fill:#DCFCE7,color:#14532D,stroke:#16A34A
    style N fill:#16A34A,color:#fff,stroke:#14532D
```

Charging is **asynchronous and batched**, so it never sits on your ingest hot path. The wallet's double-entry ledger is the system of record throughout; the period-end invoice is just a record of what was already debited.

***

## Setting up a real-time plan

Set `"billing_mode": "realtime"` and attach prices for your metrics:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/plans \
    -H "Authorization: Bearer mk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "name": "AI Prepaid — token billing",
      "currency": "NGN",
      "plan_type": "collection",
      "billing_period": "monthly",
      "billing_mode": "realtime",
      "prices": [
        { "metric_id": "<metric_id>", "model": "per_unit", "unit_price": "0.100000" }
      ]
    }'
  ```

  ```go Go theme={null}
  plan, err := client.Plans.Create(ctx, monigo.CreatePlanParams{
      Name:          "AI Prepaid — token billing",
      Currency:      "NGN",
      PlanType:      "collection",
      BillingPeriod: "monthly",
      BillingMode:   "realtime",
      Prices: []monigo.PriceParams{
          {MetricID: metricID, Model: "per_unit", UnitPrice: "0.100000"},
      },
  })
  ```

  ```ts TypeScript theme={null}
  const plan = await client.plans.create({
    name: "AI Prepaid — token billing",
    currency: "NGN",
    plan_type: "collection",
    billing_period: "monthly",
    billing_mode: "realtime",
    prices: [
      { metric_id: metricId, model: "per_unit", unit_price: "0.100000" },
    ],
  });
  ```
</CodeGroup>

<Warning>
  `billing_mode: "realtime"` requires **`plan_type: "collection"`** and **`billing_period: "monthly"`** — usage is aggregated per calendar month, and other combinations are rejected at plan creation. All pricing models (`per_unit`, `tiered`, `package`, `overage`, `cap`) are supported.
</Warning>

***

## Wallet auto-creation

Real-time billing debits a prepaid wallet, so the customer needs one funded in the plan's currency. As with prepaid plans, Monigo creates the wallet automatically when the customer subscribes if one doesn't already exist.

Let the customer fund it inline with the `<WalletWidget>` component (React, Svelte, or Vue), which shows the live balance and opens the provider's checkout on **Top up**. See [Wallet Management](/guides/wallet-management) and [Embedding the Portal](/guides/embedding-the-portal).

<Warning>
  The payment provider's webhook is the source of truth for crediting — **never credit a wallet from the browser**. Monigo credits it automatically when the provider confirms the top-up.
</Warning>

***

## The reconcile engine

Each flush cycle does not price individual events. Instead it **reconciles**: it recomputes the cost of *all* usage so far this period and debits only the difference since the last charge.

```
target   = Σ price(cumulative usage) across all metrics
marginal = target − charged_so_far
debit the wallet for `marginal`, then persist charged_so_far = target
```

This reconcile approach is what makes every pricing model behave correctly in real time:

* **Tiered, package, and overage** pricing stay exact across the whole period, because the cost is always recomputed from the cumulative quantity — never summed from per-event slices that would land in the wrong tier.
* **`cap`** pricing charges its flat fee exactly once: the first reconcile debits the base price, and every subsequent reconcile computes a marginal of zero.

A few properties worth knowing:

* **\~5 second latency.** Charging trails ingestion by roughly the flush interval. It's asynchronous, so it never blocks event ingestion.
* **Crash-safe and idempotent.** Each debit carries a deterministic idempotency key derived from the charge sequence, so a retry after a crash can never double-charge.
* **Bounded free usage.** Because charging trails ingestion by a few seconds, a small amount of usage can be metered in the window between the balance hitting zero and the pause taking effect. This is bounded to roughly one charge interval.

***

## Handling insufficient balance

When the wallet can't cover the next marginal charge, Monigo:

1. **Pauses the subscription** and blocks further usage events for that customer (so usage can't run up unbilled while the balance is empty).
2. Fires a `subscription.prepaid_balance_insufficient` webhook.

```json subscription.prepaid_balance_insufficient theme={null}
{
  "subscription_id": "01924f1e-...",
  "customer_id": "01924f1e-...",
  "amount_due": "120.000000",
  "currency": "NGN",
  "reason": "insufficient_balance"
}
```

Use this webhook to prompt the customer to top up — surface the wallet widget or a "fund wallet" call-to-action.

***

## Auto-resume on top-up

When you credit a wallet belonging to a customer with a paused real-time subscription, Monigo automatically:

1. Reactivates the subscription
2. Charges any usage that accrued but went unbilled while the balance was empty (the residual)
3. Unblocks further events and resumes continuous debiting

This is fully automatic — exactly the same top-up flow as prepaid billing. The provider's top-up webhook credits the wallet; Monigo handles the resume.

<CodeGroup>
  ```bash cURL theme={null}
  # Top up the wallet — Monigo auto-resumes the subscription once the credit lands
  curl -X POST https://api.monigo.co/v1/wallets/{wallet_id}/credit \
    -H "Authorization: Bearer mk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "amount": "5000.00",
      "description": "Manual top-up",
      "idempotency_key": "topup_abc123"
    }'
  ```

  ```go Go theme={null}
  entry, err := client.Wallets.Credit(ctx, walletID, monigo.CreditWalletParams{
      Amount:         "5000.00",
      Description:    "Manual top-up",
      IdempotencyKey: "topup_abc123",
  })
  // Once the balance covers the residual, the subscription auto-resumes.
  ```

  ```ts TypeScript theme={null}
  const entry = await client.wallets.credit(walletId, {
    amount: "5000.00",
    description: "Manual top-up",
    idempotency_key: "topup_abc123",
  });
  // Once the balance covers the residual, the subscription auto-resumes.
  ```
</CodeGroup>

<Tip>
  Always provide an `idempotency_key` when crediting wallets so a retried top-up never double-credits. See [Idempotency](/guides/idempotency).
</Tip>

***

## What happens at period end

The money has already been debited continuously, so the period close is just bookkeeping. At month end Monigo emits **one paid summary invoice** — per-metric line items, total equal to what was actually debited — and **no additional charge is made**. The invoice exists for the customer's records, then the period advances.

This is the key difference from prepaid: prepaid does all its work *at* period end (one debit, one invoice), while real-time has done the debiting throughout and uses period end only to issue the summary.

***

## Webhook events

| Event                                       | When fired                                                    |
| ------------------------------------------- | ------------------------------------------------------------- |
| `subscription.prepaid_balance_insufficient` | Wallet can't cover the next charge; subscription paused       |
| `customer.wallet.topped_up`                 | Wallet was credited (auto-resume follows automatically)       |
| `invoice.paid`                              | Monthly summary invoice issued (already paid from the wallet) |

Register a webhook endpoint in the [Webhooks guide](/integrations/webhooks) to receive these events.

***

## Customer portal

In the customer portal, a real-time subscription shows the customer their **live wallet balance** drawing down as usage accrues, alongside a **Top up wallet →** action. The monthly summary invoice appears under their invoices once the period closes. This gives customers continuous visibility into exactly what they're spending.

***

## Comparing the billing modes

|                  | Postpaid (default)         | Prepaid                      | Real-time                        |
| ---------------- | -------------------------- | ---------------------------- | -------------------------------- |
| `billing_mode`   | `"postpaid"`               | `"prepaid"`                  | `"realtime"`                     |
| When charged     | At period end, in arrears  | At period end, from wallet   | Continuously (\~5s), from wallet |
| Invoice created  | As `draft`, then finalized | Directly as `paid`           | One `paid` summary at period end |
| Plan constraints | Any period                 | Collection plans             | Collection + monthly only        |
| Failed/empty     | Dunning retries → suspend  | Subscription paused          | Subscription paused              |
| Recovery         | Settle invoice → resume    | Top up → auto-resume         | Top up → auto-resume             |
| Best for         | SaaS with card-on-file     | APIs with credit/token packs | AI agents, pay-as-you-go usage   |

***

## Related

* [AI Prepaid Wallet](/guides/ai-prepaid-wallet) — full end-to-end integration walkthrough
* [Prepaid Billing](/guides/prepaid-billing) — wallet debited once at period end
* [Postpaid Billing](/guides/postpaid-billing) — the default, collected via payment provider
* [Wallet Management](/guides/wallet-management) — wallet operations and the `<WalletWidget>`
* [Pricing Models](/guides/pricing-models) — tiered, package, overage, and cap pricing
* [Webhooks](/integrations/webhooks) — receiving billing events
