Errors
Stable customer-facing codes and HTTP status mapping.
Error responses are JSON. Validation failures typically use 400. Auth failures use 401. Business rules such as wallet balance use dedicated codes.
Response shape
{
"code": "INSUFFICIENT_BALANCE",
"message": "Insufficient wallet balance. Need 25 TZS, have 0"
}HTTP status
| Status | Meaning |
|---|---|
400 | Invalid request, missing Sender ID, M-Pesa unavailable, or bad input |
401 | Missing or invalid Bearer token / API key |
402 | Insufficient prepaid balance |
403 | Forbidden (e.g. manual wallet top-up disabled) |
404 | Resource not found (e.g. message id) |
502 | Payment could not be started (retry or try another number/network) |
202 | SMS accepted and queued (success for send) |
201 | Created (register, deposits, webhooks, etc.) |
Application codes
| Code | When |
|---|---|
VALIDATION_ERROR | Request body failed schema validation |
MISSING_SENDER_ID | No senderId provided and no org/platform default available |
WALLET_MISSING | Organisation wallet could not be found |
INSUFFICIENT_BALANCE | Wallet balance lower than the send charge |
MPESA_UNAVAILABLE | Deposit/Buy SMS attempted with a Vodacom M-Pesa number — use another network for now |
MANUAL_TOPUP_DISABLED | POST /v1/wallet/top-up is disabled; use mobile money instead |
PAYMENT_PROVIDER_ERROR | Mobile money payment could not be started (customer-safe message) |
INVALID_PHONE | Phone number is missing or not a valid MSISDN |
INVALID_AMOUNT | Deposit amount below the minimum (100 TZS) |
NOT_FOUND | Message, deposit, or resource id does not exist |
MESSAGE_PROVIDER_ERROR | Customer-safe stand-in when delivery fails for infrastructure reasons |
Provider noise is strippedFailed messages and payments expose Netnaunse codes and messages only. Upstream provider names and raw payloads are never returned on customer APIs.