Bulk SMS API Kenya: Complete Integration Guide for Developers
Integrate bulk SMS into your application with our Kenya SMS API. RESTful endpoints, code samples in PHP, Python and Node.js, webhook callbacks and delivery reports — everything you need to start sending programmatically.
Why Use a Bulk SMS API?
If you are building an application for the Kenyan market — whether it is an e-commerce platform, a fintech app, a school management system, or a SACCO portal — you will need to send SMS. Transactional messages like OTP codes, payment confirmations, and appointment reminders cannot wait for someone to log into a web dashboard. They need to fire automatically, instantly, and reliably.
The KenyaSMS API gives developers a clean, RESTful interface to send single and bulk SMS, check delivery status, query account balances, and receive real-time webhook callbacks. We deliver to all Kenyan networks — Safaricom, Airtel, and Telkom — via direct SMPP routes with a 99.5% delivery rate.
Getting Started: Authentication
All API requests are authenticated using an API key passed in the Authorization header:
Authorization: Bearer your_api_key_here
Generate your API key from the KenyaSMS dashboard under Settings > API Keys. You can create multiple keys for different environments (staging, production) and revoke them independently.
Core Endpoints
Send a Single SMS
POST /api/v1/sms/send
Send a single message to one recipient. Ideal for OTPs, transaction confirmations, and personalised notifications.
- to (string, required) — recipient phone number in international format (e.g., 254712345678)
- message (string, required) — the SMS body, up to 918 characters (6 concatenated SMS parts)
- sender_id (string, optional) — your registered sender ID (e.g., "MYSHOP")
- callback_url (string, optional) — URL to receive delivery report webhooks
Send Bulk SMS
POST /api/v1/sms/bulk
Send the same message or personalised messages to multiple recipients in a single API call. Supports up to 10,000 recipients per request.
- messages (array, required) — array of objects each containing
toand optionallymessage - default_message (string, optional) — message to use when individual message is not specified
- sender_id (string, optional) — your registered sender ID
- callback_url (string, optional) — URL for delivery report webhooks
Check Balance
GET /api/v1/account/balance
Returns your current SMS credit balance. Useful for monitoring and alerting before credits run out mid-campaign.
Delivery Reports
GET /api/v1/sms/status/{message_id}
Query the delivery status of a specific message. Returns statuses like queued, sent, delivered, failed, or rejected.
Code Sample: PHP
Here is a quick PHP example using cURL to send a single SMS:
$ch = curl_init('https://app.kenyasms.com/api/v1/sms/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'to' => '254712345678',
'message' => 'Your OTP is 4829. Valid for 5 minutes.',
'sender_id' => 'MYAPP',
]));
$response = curl_exec($ch);
Code Sample: Python
Using the popular requests library:
import requests
response = requests.post(
'https://app.kenyasms.com/api/v1/sms/send',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'to': '254712345678',
'message': 'Your order #1234 has been shipped.',
'sender_id': 'DUKAMART',
}
)
Code Sample: Node.js
Using axios:
const axios = require('axios');
await axios.post('https://app.kenyasms.com/api/v1/sms/send', {
to: '254712345678',
message: 'Hi Jane, your appointment is tomorrow at 10 AM.',
sender_id: 'CLINICKE',
}, {
headers: { Authorization: 'Bearer YOUR_API_KEY' }
});
Rate Limits
To ensure platform stability, the API enforces the following rate limits:
| Plan | Requests/minute | Messages/request |
|---|---|---|
| Standard | 60 | 1,000 |
| Business | 300 | 5,000 |
| Enterprise | 1,000 | 10,000 |
If you exceed the rate limit, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
Webhook Callbacks for Delivery Reports
Instead of polling the status endpoint, configure a callback URL to receive real-time delivery reports. When a message status changes, we POST a JSON payload to your URL:
- message_id — the unique message identifier
- status — delivered, failed, or rejected
- timestamp — when the status was reported by the network
- network — Safaricom, Airtel, or Telkom
This is particularly powerful when combined with M-Pesa STK push integration. Imagine this flow for a Kenyan e-commerce app: customer pays via M-Pesa, your server receives the payment callback, triggers an SMS confirmation via the KenyaSMS API, and then receives the delivery webhook to confirm the customer got the message. End-to-end automation.
Error Handling
The API uses standard HTTP status codes. Common errors include:
- 400 — Invalid request (malformed phone number, empty message)
- 401 — Invalid or missing API key
- 402 — Insufficient credits
- 422 — Validation failed (message too long, unregistered sender ID)
- 429 — Rate limit exceeded
- 500 — Server error (retry with exponential backoff)
All error responses include a JSON body with a message field describing the problem and an error_code for programmatic handling.
Start Building Today
Ready to integrate SMS into your Kenyan application? Sign up for a free KenyaSMS account, generate your API key, and send your first test message in minutes. Our API is trusted by over 10,000 Kenyan businesses — from startups in Nairobi's iHub to enterprise banks on Kenyatta Avenue.
Ready to Start Sending SMS?
Join thousands of Kenyan businesses using KenyaSMS. Get 10 free credits on signup.