SelanimDocs

Errors

Every failure returns the same JSON shape, with a stable machine-readable code.

json
{
  "error": {
    "code": "sender_id_not_approved",
    "message": "Sender ID MYSCHOOL is pending approval.",
    "field": "senderId",
    "requestId": "REQ-90031",
    "docs": "https://docs.selanim.co.tz/errors#sender_id_not_approved"
  }
}

Branch on error.code, never on the message text — messages are written for humans and may change. Always log requestId: it is the fastest way for support to find your call.

HTTP status codes

StatusMeaningWhen it happens
200OKThe request succeeded.
202AcceptedMessages were queued for dispatch.
400Bad requestMalformed JSON or a failed validation rule.
401UnauthorizedMissing, malformed, revoked or expired API key.
402Payment requiredThe balance cannot cover the send. Nothing was sent.
403ForbiddenValid key, but not permitted — scope, IP allowlist or an unprovisioned account.
404Not foundNo resource with that id on your account.
409ConflictDuplicate idempotency key with a different body.
422UnprocessableSemantically invalid, e.g. an unapproved sender ID.
429Too many requestsRate limit exceeded — back off and retry.
500Server errorOur fault. Safe to retry with the same idempotency key.
503Service unavailableA service behind the API is having a bad minute. Retry shortly.

Error codes

CodeHTTPCauseFix
invalid_api_key401The key is missing, malformed, or has never existed.Check the Authorization header. Keys start with sbs_live_ or sbs_test_.
api_key_revoked401The key was revoked, or replaced by a rotation.Issue a new key in the portal and redeploy.
api_key_expired401The key passed its expiry date.Issue a new one; consider whether it needed an expiry at all.
ip_not_allowed403Caller IP is outside the key's allowlist.Add the address in the portal, or clear the allowlist.
insufficient_scope403Valid key, but it does not hold the scope this endpoint needs.Widen the key's scopes in the portal, or use a key that has them.
invalid_request400Malformed JSON, a missing field, or a field this endpoint does not accept.The message names the field. Unknown fields are refused rather than ignored, so a typo is reported instead of silently dropped.
invalid_phone_number422A number is not a valid Tanzanian MSISDN.Any of 0713111321, +255 713 111 321 or 255713111321 is accepted; anything else is not.
recipients_exceeded400More than 1,000 recipients in one call.Split the request, or import the list into a group.
message_too_long422The body exceeds the 10-segment maximum.Shorten it, or split it deliberately.
sender_id_not_approved422The sender ID is pending, rejected, or not yours.Send under an approved name while the request is reviewed. GET /v1/sender-ids lists them.
not_found404No such resource on your account.Check the id. An id belonging to another account also returns 404, on purpose.
insufficient_funds402The balance cannot cover the whole send.Top up, then retry with the same Idempotency-Key. Nothing was sent.
account_not_provisioned403The key is not linked to a business account.Finish onboarding in the portal; this normally means registration did not complete.
idempotency_key_reused409That Idempotency-Key was used with a different request body.Use a fresh key for a genuinely new request.
idempotency_key_in_flight409The original call with this key is still running.Wait for it to finish. Retrying now would risk a second send.
rate_limited429Too many requests in the window.Honour Retry-After. Sending fewer, larger requests is usually the real fix.
upstream_unavailable503A service this request needed did not answer.Retry with the same Idempotency-Key; it is safe and it is probably transient.
internal_error500We broke.Retry with the same Idempotency-Key, and quote the requestId if it persists.

Retry safely

Pair every retry with the original Idempotency-Key. A replayed key returns the first response instead of sending the message twice.