Minimal send
Request parameters
Recipient phone number in E.164 format (
+ followed by 8–15 digits). We auto-detect the country from the dial code. Invalid numbers return phone_invalid.Sender ID — alphanumeric, ≤ 11 characters. Must be registered in your project. See Sender IDs.
Message body. Required unless
template is provided. Max 1600 characters (concatenated SMS auto-splits into segments).Slug or UUID of a registered SMS template. When set,
body is ignored and rendered from the template using variables. See Templates.Map of variable → value for template interpolation. Only used when
template is set.ISO-3166 alpha-2 code (
NG, GH, KE, CI). Optional — we derive it from to by default. Use this to override for hybrid-numbered SIMs.Schedule delivery for a future time. The message stays in
scheduled state until the scheduled time, then transitions to queued and sends. Max lead time: 30 days.Response
One of:
queued, scheduled, sent, delivered, failed, rejected, cancelled. New messages start as queued (or scheduled if send_at is in the future).Number of SMS segments the body occupies. GSM-7 body: 160/153 chars per segment. UCS-2 (emoji, non-Latin): 70/67.
GSM7 or UCS2. We detect automatically based on body content.Per-segment cost committed for this send.
amount_kobo is the smallest unit of currency (e.g. kobo for NGN, pesewas for GHS).Upstream we initially routed to. The actual winning provider after failover is on
GET /v1/sms/:id in provider_attempts.true when sent with a rb_test_* key. Test messages never touch real carriers.With a template
Scheduled send
POST /v1/sms/:id/cancel. After send_at the message status becomes queued and cancellation becomes a no-op (returns conflict).
With idempotency
Always pair sends with an idempotency key from your business data — see Idempotency:Error cases
| Error | HTTP | Cause |
|---|---|---|
phone_invalid | 400 | to not in E.164 format |
sender_id_invalid | 400 | Sender too long, or rejected by carrier compliance |
validation_error | 400 | Required field missing, body too long |
sms_quota_exceeded | 402 | Monthly quota + wallet both exhausted |
rate_limit_exceeded | 429 | Slow down and retry with backoff |