Bulk SMS API
Send transactional SMS and OTPs to single or multiple recipients, schedule sends and receive delivery reports.
RESTBearer keyIP whitelist
Download the docs (PDF)Documentation, quickstarts and integration guides for every Eudor product. Your API key and API host are shared with you during integration.
Send transactional SMS and OTPs to single or multiple recipients, schedule sends and receive delivery reports.
Manage products, receive subscription, renewal and keyword webhooks, and handle USSD menu requests.
Serve dynamic USSD screens from your own systems.
Use the API key and API host we share with you during integration. Requests must come from a whitelisted IP.
curl -X POST https://YOUR_API_HOST/v1/sms/send \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ref_id": "REQ001",
"sender_id": "BANKXYZ",
"recipient": "+2348012345678",
"message": "Your OTP is 482915"
}'Base URL: https://YOUR_API_HOST — shared with you during integration. All requests and responses are JSON over HTTPS.
| Method | Endpoint | What it does |
|---|---|---|
| POST | /v1/sms/send | Transactional SMS or OTP to one recipient. Reaches DND numbers. |
| POST | /v1/sms/bulk | The same transactional message to many recipients in one request. |
| POST | /v1/sms/promotional | Offers and marketing. Not delivered to DND numbers; 08:00–20:00 WAT. |
| GET | /v1/sms/report/{request_id} | Delivery status for every recipient of a request. |
| GET | /v1/sms/status/{request_id}/{recipient} | Delivery status for one recipient. |
| GET | /v1/account/balance | Your wallet balance in SMS units. |
| GET | /v1/account/rate | Your current price per page, by network and route. |
| Field | Type | Required | Notes |
|---|---|---|---|
| ref_id | String | Yes | Your unique reference, max 15 characters. Re-using one returns 409, so retries never double-send. |
| sender_id | String | Yes | An approved sender ID on your account. |
| recipient / recipients | String / Array | Yes | Numbers in international format, e.g. +2348012345678 (the + is optional). |
| message | String | Yes | Up to 160 characters per page (70 with unicode). Write NGN rather than ₦. |
| telco | String | No | MTN, Airtel, Glo or 9mobile. Optional — leave it out and the platform determines the network. |
| unicode | Boolean | No | Set true for messages with emoji or non-Latin characters. |
| schedule | String | No | ISO 8601 time to send later, e.g. 2026-11-02T09:00:00+01:00. |
| delivery_report | Boolean | No | Set false to turn off delivery reports for this request. Default true. |
{
"ref_id": "REQ001",
"request_id": "sms-5f4g3d2s2c",
"status": "success",
"message_count": 1,
"recipient_count": 1,
"units": 1.0
}{
"request_id": "sms-5f4g3d2s1a",
"recipient": "+2348012345678",
"status": "delivered",
"error_code": null,
"timestamp": "2026-11-02T09:00:04+01:00"
}Status moves queued → sent → delivered, failed or expired. Reply 200 OK; we retry twice if you don't.
| 400 | Bad request — a missing or invalid parameter. |
| 401 | Invalid or missing API key, or the request came from an IP that isn't whitelisted. |
| 409 | Duplicate request — this ref_id has already been used. |
| 429 | Rate limit exceeded. Limits are set per client; see the X-RateLimit headers. |
| 500 | Server error. Retry later or contact support. |