Integrate SMS capabilities directly into your applications with our robust, well-documented API. Build powerful communication workflows with just a few lines of code.
The SMSALES API allows you to send SMS messages, check your account balance, and receive delivery reports programmatically. Our API follows REST principles and returns JSON responses.
The SMSALES API only accepts Content-Type: application/json and Accept:
application/json headers for all requests.
All API requests should be made to:
https://api.smsales.co.ke/api/v1/
SMSALES API uses OAuth 2.0 Authorization Grant Type with Basic Authentication to generate access tokens.
/token
| Header | Value | Description |
|---|---|---|
| Authorization | Basic YOUR_ACCOUNT_API_TOKEN | Base64 encoded account API token |
| Content-Type | application/json | Required for all requests |
| Accept | application/json | Required for all requests |
curl -X GET "https://api.smsales.co.ke/api/v1/token" \
-H "Authorization: Basic YOUR_ACCOUNT_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://api.smsales.co.ke/api/v1/token',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Basic YOUR_ACCOUNT_API_TOKEN'
}
};
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.smsales.co.ke/api/v1/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Basic YOUR_ACCOUNT_API_TOKEN'
),
));
?>
{
"data": {
"Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"TokenType": "Bearer",
"Expires": 3600
}
}
Send SMS messages to one or multiple recipients, check balances, and view sent messages.
/sms/send
| Header | Value | Description |
|---|---|---|
| Authorization | Bearer YOUR_ACCESS_TOKEN | Access token from /token endpoint |
| Content-Type | application/json | Required for all requests |
| Accept | application/json | Required for all requests |
| Parameter | Type | Required | Description |
|---|---|---|---|
| api_sender | String | Yes | Your registered API Sender ID (check your sender ID list) |
| message | String | Yes | The SMS message content |
| phone_numbers | Array | Yes | Array of phone numbers in format ["2547XXXXXXXX","2540XXXXXXXX"] |
| scheduled_at | String | No | Scheduled time in format "Y-m-d H:i:s" |
| callback_url | String | No | URL to receive delivery reports (POST request) |
curl -X POST "https://api.smsales.co.ke/api/v1/sms/send" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"api_sender": "smsales",
"message": "Hello from SMSALES!",
"phone_numbers": ["2547XXXXXXXX","2540XXXXXXXX"],
"callback_url": "https://yourdomain.com/sms-callback"
}'
const axios = require('axios');
const options = {
method: 'POST',
url: 'https://api.smsales.co.ke/api/v1/sms/send',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
},
data: {
"api_sender": "smsales",
"message": "Hello from SMSALES!",
"phone_numbers": ["2547XXXXXXXX","2540XXXXXXXX"]
}
};
<?php
$curl = curl_init();
$data = array(
'api_sender' => 'smsales',
'message' => 'Hello from SMSALES!',
'phone_numbers' => array('2547XXXXXXXX', '2540XXXXXXXX')
);
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.smsales.co.ke/api/v1/sms/send',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Bearer YOUR_ACCESS_TOKEN'
),
));
?>
{
"data": {
"batch": "1DIIPJGDP4",
"message": "Accepted for dispatch..."
}
}
/sms
| Header | Value | Description |
|---|---|---|
| Authorization | Bearer YOUR_ACCESS_TOKEN | Access token from /token endpoint |
| Content-Type | application/json | Required for all requests |
| Accept | application/json | Required for all requests |
/sms/balance/account
| Header | Value | Description |
|---|---|---|
| Authorization | Bearer YOUR_ACCESS_TOKEN | Access token from /token endpoint |
| Content-Type | application/json | Required for all requests |
| Accept | application/json | Required for all requests |
{
"data": {
"smsBalance": "57839",
"smsUsage": "47577"
}
}
/sms/balance/sender
| Header | Value | Description |
|---|---|---|
| Authorization | Bearer YOUR_ACCESS_TOKEN | Access token from /token endpoint |
| Content-Type | application/json | Required for all requests |
| Accept | application/json | Required for all requests |
{
"data": [
{
"sender": "SENDER01",
"slug": "sender01",
"unitPrice": "0.8",
"smsUsage": 14507,
"isActive": true
},
{
"sender": "SENDER02",
"slug": "sender02",
"unitPrice": "0.8",
"smsUsage": 21755,
"isActive": true
},
{
"sender": "SENDER03",
"slug": "sender03",
"unitPrice": "0.4",
"smsUsage": 9422,
"isActive": true
}
]
}
Receive real-time delivery reports via webhooks. Configure a callback URL when sending SMS messages to receive delivery status updates.
For each phone number in your batch, we'll send a separate POST request to your callback URL with the following payload once the message has been processed by the gateway:
{
"messageID": c7740da8-ce30-4a09-a2bd-31af64b3ecea,
"sent": true,
"status": "delivered",
"code": 1,
"sender": "SMSALES",
"apiSender": "smsales",
"phoneNumbers": [
"254XXXXXXXXX"
],
"batch": "1DIIPJGDP4",
"queued_at": "2026-07-14T10:15:30+00:00",
"received_at": "2026-07-14T10:15:45+00:00",
"error": null,
"account": {
"smsBalance": "663",
"smsUsage": "24"
}
}
If the gateway rejects the message, the payload is sent with sent: false,
status: "failed", code: 0, and an error message describing the
failure reason, for example "Gateway rejected message". The error field is
null for successful deliveries.
| Field | Type | Description |
|---|---|---|
| messageID | String | Unique identifier of the individual SMS record this callback refers to |
| sent | Boolean | Indicates if the SMS was successfully delivered |
| status | String | Delivery status of the message: delivered or failed |
| code | Integer | Numeric status code: 1 for delivered, 0 for failed |
| sender | String | The sender name |
| apiSender | String | The API sender ID used |
| phoneNumbers | Array | The phone number this callback refers to, returned as a single-item array |
| batch | String | Unique batch identifier for the SMS |
| queued_at | String | ISO 8601 timestamp of when the message was queued for sending |
| received_at | String | ISO 8601 timestamp of when the delivery report was received from the gateway |
| error | String or null | Error message describing the failure reason if sent is false, otherwise null |
| account.smsBalance | String | Remaining SMS balance on the account |
| account.smsUsage | String | Total SMS units used on the account |
The API uses standard HTTP status codes and returns error details in the response body.
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | invalid_request | The request was malformed or missing required parameters |
| 401 | unauthorized | Invalid or missing Authorization header |
| 403 | forbidden | Invalid or expired token |
| 422 | unprocessable_entity | The request was well-formed but was unable to be followed due to semantic errors |
| 429 | rate_limit | Too many requests, rate limit exceeded |
| 500 | server_error | Internal server error |
Official SMSALES SDKs for popular programming languages. These libraries simplify integration by handling authentication, error handling, and API calls for you.
Official PHP library for SMSALES API integration. Supports Laravel, Symfony, and standalone PHP applications.
Node.js and browser JavaScript library. Includes TypeScript definitions and Promise-based API.
Python library for Django, Flask, and standalone scripts. Async support with asyncio.
Start integrating SMS capabilities into your applications today. Get your API token and send your first SMS in minutes.
Get API Token View Documentation