Billing — prepaid, pay-as-you-go
bZapper has no fixed plans or subscriptions. You fund a wallet (prepaid) and usage is debited from it as it happens — pay only for what you use. Each account has one wallet and one currency.
Every account starts with a free-forever allowance, no card required:
- 200 messages / month
- 2 numbers
- 100 MB of storage
- 1 project
Each pillar has its own allowance — only the overage is charged. You only need to top up when you go past one of these allowances.
Wallet (balance)
The wallet balance is the sum of:
- Paid — real money you topped up (top-up or auto top-up);
- Bonus — courtesy granted by the platform (may have an expiry).
When charging, we debit the bonus first. Check the balance and the ledger:
GET /billing/wallet
# { "balance_cents": 12345, "ledger": [ … ] } ← cents (paid + bonus)
GET /me/entitlements
# effective limits + rate card + wallet (paid_cents, bonus_cents) + caps + usage
All monetary values are in cents (the smallest whole unit of the currency). A sub-cent message price is represented in millicents (1/1000 of a cent).
Currency by region
The currency is set at signup, based on the region, and locks on the first top-up. There are 3 currencies (no exchange between them — the price is set independently in each one):
| Region | Currency |
|---|---|
| Brazil | BRL |
| Rest of the Americas | USD |
| Rest of the world | EUR |
Rate card (price table)
Prices come from a per-currency rate card, configurable by the platform — the values below are the BRL defaults and vary by currency:
| Pillar | Price (BRL, default) | Free allowance |
|---|---|---|
| Message | R$ 0.01 each | 200 / month |
| Number | R$ 9.90 / month | 2 numbers |
| Storage | R$ 9.90 / GB·month | 100 MB |
| Project | R$ 9.90 / month | 1st project free |
Only what goes past the allowance is charged. Numbers and storage are recurring: we charge the daily fraction of the monthly price, debiting it from the wallet.
What counts as a "message"
A message = sent + received. But a received message is only charged when it's monitored — that is, when there's an active webhook receiving it. If you don't listen to inbound messages, they don't count.
- OTP (
POST /messages/otp) is 1 send (even though it goes out as 2 WhatsApp messages — text + the code bubble).
Top-up
You add balance by creating a payment (Stripe Elements on the front end):
POST /billing/checkout
{ "amount_cents": 2000 } # min. 500 cents
# → { "client_secret": "...", "charge_id": "...", "amount_cents": 2000 }
The minimum top-up amount is 500 cents (e.g. R$ 5.00). The balance is credited when the Stripe webhook confirms the payment.
Auto top-up
To never run out of balance, set up auto top-up: when the paid balance falls below a threshold, the API charges a fixed amount to the saved card and credits the wallet.
GET /me/autorecharge
PATCH /me/autorecharge
{ "enabled": true, "threshold_cents": 1000, "amount_cents": 5000, "pm_id": "pm_..." }
To enable it, provide an amount (amount_cents > 0) and a card (pm_id).
There's a daily limit on automatic top-ups (max_per_day) and a pause after
consecutive failures.
Spending caps (self-protection)
You set spending caps per period — daily, weekly, and monthly — to protect
yourself from surprises. When a cap is reached, new chargeable sends respond
402 spend_cap_reached until the period rolls over (or you raise the cap).
PATCH /me/spend-caps
{ "daily_cap_cents": 5000, "weekly_cap_cents": 20000, "monthly_cap_cents": 50000 }
# 0 = no cap for that period
Welcome bonus
The platform may grant a welcome bonus when you open the account. The amount is configurable per currency (and may have an expiry) — there's no guaranteed fixed amount; by default it's off until the platform configures it.
Billing codes you may see
| Code | HTTP | Meaning |
|---|---|---|
payment_required | 402 | Insufficient balance (past the allowance and out of balance) — top up. |
spend_cap_reached | 402 | The period's spending cap was reached. |
quota_exceeded | 402 | A resource limit (e.g. projects/numbers) was reached. |
invalid_amount | 400 | Top-up below the minimum (500 cents). |
billing_disabled | 501 | Billing not configured (no Stripe). |
Related webhook events: usage.threshold, wallet.low,
billing.past_due, billing.recovered — see Webhooks.
The prices, allowances, and bonuses shown here are defaults and configurable
by the platform — and they vary by currency. Always check GET /me/entitlements
for your account's effective values.