Internal Services

Bulk SMS Gateway API

Integrate the fastest Bulk SMS API gateway in Kenya. Send transactional SMS, OTP alerts, and marketing campaigns reliably with instant delivery reports (DLR).

Statum's Bulk SMS Gateway API provides developers and businesses in Kenya with a secure, high-throughput channel to deliver transactional alerts, OTPs, and promotional messages globally. By connecting directly to major local carriers (Safaricom, Airtel, Telkom), our API ensures near-zero latency, high delivery success rates, and transparent reporting.

Integrate our RESTful API endpoint to automate your messaging workflows. All requests require authentication and are transmitted securely via HTTPS.

POST
https://api.statum.co.ke/api/v2/sms

SMS Gateway API Features

Statum's SMS gateway is engineered to support critical messaging channels with the following capabilities:

High-Speed Throughput

Process and dispatch thousands of messages per second. Ideal for one-time passwords (OTPs) and time-sensitive security alerts.

Real-time Delivery Reports

Receive granular carrier callbacks (DLRs) directly. Track when messages hit Safaricom, Airtel, or Telkom networks.

Full Unicode Support

Send messages in any language, including localized Kiswahili texts, custom special characters, and emoji elements.

Secure Authentication

Authenticate API requests using standard HTTP Basic Authentication with credentials safely stored as environment variables.

Sender ID Registration in Kenya

In compliance with the Communications Authority of Kenya (CA) regulations, Sender IDs must be registered before you can send custom-branded messages. Statum manages this process on your behalf:

  • Requirements: Letter of authorization to Safaricom, Airtel, and Telkom, and a copy of your Business Registration Certificate or Certificate of Incorporation.
  • Timeline: Registration takes approximately 2 to 3 business days to resolve across all mobile operators.
  • Fallback: While your custom Sender ID is being approved, you can utilize our default fallback ID to test your integration.

SMS Character Limits & Concatenation

Standard SMS messages are billed in units of 160 characters. Understanding character constraints helps you manage messaging costs:

  • Single SMS: Up to 160 characters for standard 7-bit GSM encoding.
  • Concatenated (Multi-part) SMS: Messages longer than 160 characters are automatically split and rejoined on the receiver's phone. These split parts are capped at 153 characters each due to concatenation header overhead (UDH).
  • Unicode Encoding: Messages containing non-GSM characters (e.g., emojis or specialized symbols) use 16-bit UCS-2 encoding and are limited to 70 characters per message part.

SMS API Request Parameters

Send a POST request containing a JSON body with the following parameters:

Parameter Type Required Description Example
phone_number String Yes Recipient phone number in international format without the leading plus sign. 254721553678
message String Yes The message body text to deliver. Keep within GSM character standards. Your verification code is 8847.
sender_id String Yes The registered custom Sender ID or short code. Statum

Request Implementation Example

Send Bulk SMS
curl -X POST https://api.statum.co.ke/api/v2/sms \
  -H "Authorization: Basic MmJlOTg5ZD...==" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "254721553678",
    "sender_id": "Statum",
    "message": "This is a test message through our API."
  }'
$consumerKey = "YOUR_CONSUMER_KEY";
$consumerSecret = "YOUR_CONSUMER_SECRET";
$auth = base64_encode($consumerKey . ":" . $consumerSecret);

$client = new \GuzzleHttp\Client();
$response = $client->post('https://api.statum.co.ke/api/v2/sms', [
    'headers' => [
        'Authorization' => 'Basic ' . $auth,
        'Content-Type'  => 'application/json'
    ],
    'json' => [
        'phone_number' => '254721553678',
        'sender_id'    => 'Statum',
        'message'      => 'This is a test message through our API.'
    ]
]);

$result = json_decode($response->getBody()->getContents(), true);
const axios = require('axios');
const auth = Buffer.from('YOUR_CONSUMER_KEY:YOUR_CONSUMER_SECRET').toString('base64');

axios.post('https://api.statum.co.ke/api/v2/sms', {
    phone_number: '254721553678',
    sender_id: 'Statum',
    message: 'This is a test message through our API.'
}, {
    headers: {
        'Authorization': `Basic ${auth}`,
        'Content-Type': 'application/json'
    }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

SMS Gateway API Response Format

Upon receiving your POST request, the Statum gateway immediately processes and returns a synchronous JSON response containing the status of your request:

Parameter Type Description Example
status_code Number Standard response code (200 = Success, 401 = Unauthorized, etc.) 200
description String Human-readable response message. Operation successful.
request_id String A unique 32-character transaction ID used to map webhook callbacks. 35235f08c981474abd388755ed43a427

Sample Response Payload

Success Response
{
    "status_code": 200,
    "description": "Operation successful.",
    "request_id": "35235f08c981474abd388755ed43a427"
}

Delivery Reports & Webhook Setup

After queuing, the message is sent to the target mobile operator. To receive real-time updates (Delivery Reports), register a callback URL. The gateway will send an asynchronous HTTP POST webhook containing the final status:

Parameter Type Description Example
request_id String The reference ID returned from the initial POST request. 35235f08c981474abd388755ed43a427
charge Decimal The actual financial charge deducted from your wallet for this SMS. 50
account_balance Decimal Your available wallet balance after the charge deduction. 950.25
result_code String Status code representing transaction outcome (200 = Delivered). 200
result_desc String The description detailing status (e.g. Delivered, Rejected, Failed). Message delivered successfully

Sample Webhook Payload

When a message is dispatched to the carrier (Safaricom, Airtel, or Telkom), its delivery state updates asynchronously. Statum's server pushes a POST request containing a JSON payload to your registered callback URL. This payload matches the original request using the request_id and provides the final carrier resolution code.

Callback Notification
{
    "request_id": "35235f08c981474abd388755ed43a427",
    "charge": 50,
    "account_balance": 950.25,
    "result_code": "200",
    "result_desc": "Message delivered successfully"
}

Sample Callback Handler Implementation

To process updates programmatically, configure an endpoint on your server that accepts POST requests with a Content-Type: application/json header. Your handler must extract the parameters, update your internal logs, and respond with an HTTP 200 OK status within 3 seconds to avoid retry attempts.

PHP Callback Handler
<?php
// Route target: https://yourdomain.com/api/sms/callback
$input = file_get_contents('php://input');
$payload = json_decode($input, true);

if (!$payload) {
    http_response_code(400);
    exit();
}

$requestId = $payload['request_id'];
$resultCode = $payload['result_code'];

if ($resultCode === '200') {
    // SMS was successfully delivered to the device. Update database order/alert status.
    updateSmsStatus($requestId, 'delivered');
} else {
    // Delivery failed (e.g., number out of service, subscriber absent, etc.)
    updateSmsStatus($requestId, 'failed', $payload['result_desc']);
}

// Return 200 to acknowledge receipt of webhook
http_response_code(200);
echo json_encode(['status' => 'acknowledged']);
?>