API ReferenceSMS API
Send SMS
POST /api/messages/send - Send a single SMS message.
Endpoint
POST https://sms.esmsafrica.io/api/messages/sendAuthentication
All requests use a Bearer token - your API key from the dashboard. Live keys
start with esms_live_; test keys start with esms_test_ and simulate delivery
without charging your wallet or sending a real message.
Authorization: Bearer esms_live_your_api_keyRequest body
{
"to": "+254712345678",
"text": "Your OTP is 123456",
"sender_id": "MyApp"
}| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Recipient in international format (e.g. +254712345678). |
text | string | Yes | Message content. 160 chars = 1 segment (GSM-7), or 70 chars (Unicode); longer messages are split and billed per segment. |
sender_id | string | No | Approved sender ID. Falls back to the route default if omitted or not approved. |
route | string | No | Public route code (e.g. ESMS_UG). Auto-detected from to when omitted. |
schedule_mode | string | No | now (default) or scheduled. |
scheduled_at | string | No | ISO 8601 UTC time, required when schedule_mode is scheduled (5 min - 7 days ahead). |
Response
Success (200)
{
"id": "msg_abc123",
"status": "sent",
"segments": 1,
"encoding": "GSM7",
"recipients": 1,
"price_per_sms": 1.2,
"cost": 0.0096,
"cost_currency": "USD",
"route_cost": 1.2,
"route_currency": "KES",
"route": "ESMS_KE",
"balance_after": 12.34,
"scheduled_at": null
}cost/cost_currency is what your wallet is charged; route_cost/route_currency
is the price in the route's own currency. encoding is GSM7 or UCS2.
balance_after is your remaining wallet balance.
Errors
| Status | Description |
|---|---|
400 | Invalid phone number, unroutable country, or missing fields. |
401 | Invalid or missing API key. |
402 | Insufficient wallet balance (body includes required, available, cost). |
409 | Duplicate - identical message to the same number within 5 minutes. |
Example
curl -X POST https://sms.esmsafrica.io/api/messages/send \
-H "Authorization: Bearer esms_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "+254712345678",
"text": "Your OTP is 123456",
"sender_id": "MyApp"
}'Tips
- Call Check price first to preview the segment count and cost, and Validate numbers to drop invalid or non-mobile numbers before you spend.
- Use a
esms_test_key while integrating - responses are identical but nothing is charged or delivered.