Skip to Content

Credits

SMS on SendAfrica is prepaid: you top up with TZS, which converts to SMS credits on your account balance, and every SMS part you send consumes one credit.

Balance

GET /v1/credits/balance
curl https://api.sendafrica.online/v1/credits/balance \ -H "X-API-Key: $SENDAFRICA_API_KEY"
{ "success": true, "data": { "account_id": "f3b1c2d4-...", "balance": 1240 }, "request_id": "dfffa252-4781-43ff-8e1a-bf01a754d66a" }

History

GET /v1/credits/history?page=1&per_page=25

Returns a paginated ledger of credit transactions: type (purchase, send, refund, adjustment), amount, balance_after, description, and created_at. Useful for reconciling spend and auditing bulk-send refunds.

How billing works

  • You are charged one credit per SMS part, not per message.
  • GSM-7 messages fit 160 septets in one part, or 153 septets per part when concatenated.
  • Unicode messages (emoji, Arabic, Chinese, some accented characters) fit 70 UTF-16 code units in one part, or 67 per part when concatenated.
  • The exact billed amount is on the send response: credits_used.

A single emoji can force a message into Unicode and change credits_used. Always read credits_used from the response rather than assuming one message equals one credit.

Avoid surprises

  • Use the SDK helpers to analyze a message before sending — for example sms.analyze(message) in Python, getSmsPartInfo() in TypeScript, and client.SMS.Analyze in Go.
  • Watch balance and webhook sms.failed statistics together: failed sends are refunded, so balance drops less than your send count suggests.
  • Top up before you run dry — Payments. Send calls against an empty balance fail with 402 insufficient_credits and raise typed SDK errors (InsufficientCreditsError in Python, .isInsufficientCredits in TypeScript, IsInsufficientCredits() in Go).
Last updated on