# Wallet, pricing and billing

Source: https://docs.usetone.ai/billing

> Everything is prepaid, in paise, and the ledger is the source of truth.

Tone is prepaid. Calls, number purchases, monthly rentals and compliance verdicts
all debit one wallet, and everything is in **paise** (₹1 = 100 paise) because
money in floating point is money lost.

```bash
curl "$TONE_API/v1/wallet"              -H "Authorization: Bearer $TONE_KEY"
curl "$TONE_API/v1/wallet/transactions" -H "Authorization: Bearer $TONE_KEY"
curl "$TONE_API/v1/wallet/usage?period=30d" -H "Authorization: Bearer $TONE_KEY"
```

## What a call costs

| | Rate | What you get |
|---|---|---|
| Full stack | **₹6.00/min** | Telephony + compliance + the agent |
| Bring your own voice | **₹2.50/min** | Telephony + compliance |
| Compliance only | per verdict | The gate, the ledger and the evidence |

Plus the monthly rental on each number.

The full-stack rate itemises as agent ₹3.50 + telephony ₹0.50 + platform ₹2.00.
⚠️ **That breakdown is display, not a billing model** — a call produces exactly
one wallet debit at the blended rate, not three.

🔴 A BYO call bills the telephony-plus-platform subset and **ignores a negotiated
full-stack rate**. A negotiated rate is a discount on the whole stack; applying it
to a call whose agent half we never ran would charge a discounted customer *more*
than list.

## Test mode is free by environment

A `tone_test_` key produces calls with `billedPaise: 0`. It is the **environment**
that makes a call free, never the channel — so a sandbox call is priced through
the same path and simply reports zero.

## The ledger is the truth

`GET /v1/wallet/transactions` is not a report derived from a balance; it is what
the balance is computed from. It is append-only: a correction is a new
compensating row, never an edit. If a balance and its ledger ever disagreed, the
ledger would be right.

| Entry type | |
|---|---|
| `topup`, `topup_reversal` | Money in |
| `call_usage` | One row per call |
| `number_purchase`, `number_rental`, and their reversals | Numbers |
| `compliance_usage` | Verdicts |
| `adjustment` | Anything we corrected by hand |

## Adding money

Funding runs through Razorpay Checkout **in a browser**, from the dashboard.
There is deliberately no programmatic money-in path: a card flow needs a human
and a redirect, and an API that pretended otherwise would only fail in more
places.

## Running out

Subscribe to `wallet.balance.low` rather than polling. It fires once per
crossing, not repeatedly, and emails owners and admins.

What happens at zero depends on what you were doing:

- **A call** fails rather than being placed.
- **A campaign** with `autoPauseBelowPaise` pauses itself with
  `pausedReason: "low_balance"` and emits `campaign.paused`. Top up and resume.
- **A number rental** starts a grace period, then suspends the number — which
  **keeps** your claim on it and reverses itself once you top up. See
  [Phone numbers](/phone-numbers).
