Wallet & pricing
Check your balance programmatically so a campaign never stalls mid-send.
Credits, not currency
Your balance is held in SMS credits. One credit pays for one segment to one recipient — so a 160-character message to 500 people costs 500 credits, and a 200-character message to the same 500 people costs 1,000, because it occupies two segments.
The segment count is worked out for you and returned as parts on every send. You never have to compute it, but it is worth understanding before you write a message that is 161 characters long.
Balance
https://bulksmsapi.selanim.com/v1/wallet/balancecurl -X GET "https://bulksmsapi.selanim.com/v1/wallet/balance" \
-H "Authorization: Bearer $SBS_API_KEY"Needs: curl, on every machine already.
{
"balance": 12480,
"currency": "TZS"
}Transactions
The ledger is append-only: every credit and every debit, in the order it happened. It is the record to reconcile against, not the balance — the balance is only ever the last row of this.
https://bulksmsapi.selanim.com/v1/wallet/transactions?type=sms_charge&pageSize=50| Query | Type | Description |
|---|---|---|
type | string | One of: topup, sms_charge, refund, adjustment. |
page | integer | Defaults to 1. |
pageSize | integer | Defaults to 25. Maximum 200. |
| Type | Type | Description |
|---|---|---|
topup | string | Credit added — an approved order, or an operator adjustment upwards. |
sms_charge | string | Credit spent on a send. Negative amount. |
refund | string | Credit given back for messages that were paid for but never queued. |
adjustment | string | Anything else, usually a manual correction. |
{
"data": [
{
"id": "0f2c8a11-4d3e-4a91-9c0b-77a2e5d16b40",
"type": "sms_charge",
"amount": -1000,
"balanceAfter": 12480,
"description": "Bulk send to 500 recipients (2 segment(s) each)",
"reference": "term3-fees",
"createdAt": "2026-08-10T09:05:00Z"
}
],
"meta": { "page": 1, "pageSize": 50, "total": 214, "totalPages": 5 }
}Reconciling a send
reference when you send, and it comes back on the ledger row for that batch. That is the shortest path from “what did this campaign cost?” to an answer.Rates
Per-message rates depend on your monthly volume and are agreed with your account manager rather than published here — a rate card in documentation is out of date the week after it is written, and the number that matters is the one on your contract.
What you can rely on programmatically is the credit arithmetic above: a send costs parts × recipients credits, and the exact figure is returned as cost on the send response before you are ever surprised by it.
Running out
A send is all or nothing
402 insufficient_funds. There is no partial send: a campaign that reached 60% of a list and stopped would be worse than one that did not start, because you would have no way to tell which 40% to retry.Subscribe to wallet.low_balance to be told before it happens rather than after.

