Bulk SMS API
Send SMS from your website, app or accounting system. The API uses JSON over HTTPS and your own API key. Messages use the same credits, sender names and daily limit as your account.
1. Get a key
Sign in, open API, press Create key and copy it. We show it only once. Keep it secret: anyone with the key can spend your credits. If it leaks, revoke it in the same place and create a new one.
2. Authenticate
Send the key in the Authorization header (or X-API-Key). Use it from your server only, never inside a public web page or mobile app.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Base URL: https://bulksms.smartforelending.com/api/bulk/v1
Send SMS
POST /sms
| Field | Required | Description |
|---|---|---|
| to | yes | One number or a list of up to 1,000 numbers, like "0971234567" or ["0971234567","260961234567"]. |
| sender_id | yes | One of your approved sender names (see Balance). |
| message | yes | The text. 160 plain characters per credit (70 with special characters). |
| schedule_at | no | Lusaka time, format 2026-12-01 08:00. Leave out to send now. |
| reference | no | Your own label, up to 60 characters. |
curl -X POST https://bulksms.smartforelending.com/api/bulk/v1/sms \
-H "Authorization: Bearer sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"to":["0971234567","0961234567"],"sender_id":"YOURSHOP","message":"Your order is ready","reference":"order-17"}'
Response 202 Accepted:
{"ok":true,"send_id":184,"accepted":2,"skipped":0,"credits_used":2,"scheduled":false,"balance":4998}
accepted is how many valid numbers were queued. skipped counts wrong numbers and duplicates. Messages are queued and go out within a minute.
Balance and sender names
GET /balance
{"ok":true,"balance":4998,"sender_ids":["YOURSHOP"]}
Check a send
GET /sends/{send_id}
{"ok":true,"send_id":184,"status":"done","accepted":2,"sent":2,"failed":0,"scheduled_for":null}
Note: sent means the network accepted the message for delivery. Handset delivery receipts are not available.
Cancel a scheduled send
POST /sends/{send_id}/cancel returns the credits for messages that have not gone out yet.
{"ok":true,"credits_refunded":2,"balance":5000}
Errors
Errors return {"ok":false,"error":"code","message":"What went wrong"}.
| HTTP | Meaning |
|---|---|
| 401 | Missing, wrong or revoked key. |
| 402 | Not enough credits. Buy more in your account. |
| 403 | Account suspended. |
| 404 | No such send on your account. |
| 422 | Invalid request, for example a sender name that is not approved or no valid numbers. |
| 429 | Daily sending limit reached, or too many requests (120 per minute). |
Example in PHP
$ch = curl_init('https://bulksms.smartforelending.com/api/bulk/v1/sms');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('BULKSMS_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['to' => '0971234567', 'sender_id' => 'YOURSHOP', 'message' => 'Hello from my app']),
]);
$result = json_decode(curl_exec($ch), true);
Example in JavaScript (Node)
const r = await fetch('https://bulksms.smartforelending.com/api/bulk/v1/sms', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.BULKSMS_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '0971234567', sender_id: 'YOURSHOP', message: 'Hello from my app' })
});
console.log(await r.json());
Need help connecting? Call or WhatsApp 0571 814 620 or email info@smartforelending.com.