Top-Ups & Pricing
How credits work, voucher tier math, mobile-money top-ups, and automating low-balance top-ups.
#Credit fundamentals
- 1 credit = 1 SMS part (GSM-7: 160 chars single / 153 multipart; UCS-2: 70 / 67).
- Tanzania domestic rate: TZS 35 per credit (Tier 1).
- International sends charge
ceil(rate_tzs / 35)credits per part using the country rate card. - Credits are deducted atomically before sending and refunded automatically on gateway rejection.
#Voucher tier math
| Tier | Top-up amount (TZS) | Rate (TZS/credit) | Credits example |
|---|---|---|---|
| 1 | 1,000 – 49,999 | 35 | 10,000 → 285 |
| 2 | 50,000 – 149,999 | 32 | 75,000 → 2,343 |
| 3 | 150,000+ | 30 | 200,000 → 6,666 |
Bigger top-ups buy cheaper credits — Tier 3 is ~14% more credits per shilling than Tier 1. Fetch live numbers from GET /v1/vouchers/rate rather than hardcoding.
#Mobile money
- Verify your phone first (
send-phone-otp+verify-phone) — unverified phones get409 phone_not_verified. - Create the order:
POST /v1/vouchers/with{"amount": 75000, "provider": "snippe", "phone": "0712345678"}. - Approve the USSD prompt pushed to your phone.
- A signed webhook confirms the payment; credits land atomically and a notification fires.
#Automate low-balance top-ups
auto_topup.py
python
THRESHOLD = 500
TOPUP_TZS = 100_000 # Tier 2 rate
def maybe_top_up(client):
balance = client.credits.balance().balance
if balance >= THRESHOLD:
return None
rate = client.payments.rate()
tier_rate = next(
t.rate_tzs_per_credit for t in rate.tiers
if t.max_amount_tzs is None
or TOPUP_TZS <= t.max_amount_tzs
)
est_credits = TOPUP_TZS // tier_rate
payment = client.payments.create(
amount=TOPUP_TZS,
provider="snippe",
phone="0712345678",
)
print(f"Order {payment.id}: ~{est_credits} credits pending USSD approval")
return paymentNotifications do half the work
The platform fires a low-balance notification (deduped to 24 h/account) below LOW_BALANCE_THRESHOLD — poll GET /v1/notifications/unread-count or just subscribe your ops channel to it.