SMS API documentation for developers

Explore Celcom Africa's SMS, WhatsApp and USSD API docs - REST and SMPP support, PHP, Python and Node.js code samples, and a free sandbox to integrate messaging in under 10 minutes.

Get API key
REST ┬╖ JSON GET & POST No API call fees
99.99%
uptime
50+
Countries
850M+
Vol/Month
<5s
TAT

Introduction

Overview

Integrate your system with Celcom Africa's bulk SMS services using our REST API. The gateway delivers messages to multiple recipients quickly and efficiently - with real-time delivery reports and account balance queries built in.

Before you begin

  1. Register for a free account
  2. Open your dashboard and click GET API KEY & PARTNER ID
  3. Copy a code sample below and send a test message with free credits

API parameters

Reference

All send-SMS requests require the parameters below. Optional fields enable scheduling and encoding options.

ParameterTypeRequiredDescription
apikeystring
Required
Valid API key from your dashboard (GET API KEY & PARTNER ID).
partnerIDstring
Required
Valid Partner ID from your dashboard.
messagestring
Required
URL-encoded text message with valid GSM-7 characters.
shortcodestring
Required
Registered Sender ID or shortcode.
mobilestring
Required
Valid mobile number. Comma-separated for bulk sends.
pass_typestringOptionalPOST only. plain (default) or bm5 (base64-encoded message).
timeToSendstringOptionalSchedule for future delivery - date string or Unix timestamp.

Send SMS

Core endpoint
GET
https://isms.celcomafrica.com/api/services/sendsms/?

Pass all parameters as URL query string values. Bulk recipients can be comma-separated in the mobile field.

GET request - PHP
php
$partnerID = "useraccountpartnerId";
$apikey = "useraccountapikey";
$shortcode = "INFOTEXT";
$mobile = "254712345678"; // comma-separated for bulk
$message = "This is a test message + = # @ _ -";

$finalURL = "https://isms.celcomafrica.com/api/services/sendsms/?"
  . "apikey=" . urlencode($apikey)
  . "&partnerID=" . urlencode($partnerID)
  . "&message=" . urlencode($message)
  . "&shortcode=$shortcode&mobile=$mobile";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $finalURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo "Response: $response";
POST
https://isms.celcomafrica.com/api/services/sendsms/

Send a JSON body with Content-Type: application/json. Use pass_type: "plain" for normal text or bm5 for base64-encoded messages.

POST request - PHP
php
$url = 'https://isms.celcomafrica.com/api/services/sendsms/';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$data = [
  'partnerID' => '00',
  'apikey'    => 'xxxxxxxxxxx',
  'mobile'    => '0712345678',
  'message'   => 'This is a test message',
  'shortcode' => 'INFOTEXT',
  'pass_type' => 'plain', // or bm5 (base64)
];

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($curl);
print_r($response);
POST request - Node.js
node.js
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/sendsms/',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      partnerID: '00',
      apikey: 'xxxxxxxxxxx',
      mobile: '0712345678',
      message: 'This is a test message',
      shortcode: 'INFOTEXT',
      pass_type: 'plain',
    }),
  }
);

const data = await response.json();
console.log(data);
POST request - Python
python
import requests

url = 'https://isms.celcomafrica.com/api/services/sendsms/'
payload = {
    'partnerID': '00',
    'apikey': 'xxxxxxxxxxx',
    'mobile': '0712345678',
    'message': 'This is a test message',
    'shortcode': 'INFOTEXT',
    'pass_type': 'plain',
}

response = requests.post(url, json=payload)
print(response.json())

Send OTP SMS

POST
POST
https://isms.celcomafrica.com/api/services/sendotp/

Dedicated OTP endpoint from the CPaaS API V2 collection. Uses the same credentials and shortcode as Send SMS.

Sample request - cURL
bash
curl --request POST 'https://isms.celcomafrica.com/api/services/sendotp/' \
  --header 'Content-Type: application/json' \
  --data '{
    "apikey": "YOUR_API_KEY",
    "partnerID": "YOUR_PARTNER_ID",
    "mobile": "254712345678",
    "message": "Your OTP is 483920",
    "shortcode": "YOUR_SENDER_ID",
    "pass_type": "plain"
  }'
Sample request - Node.js
javascript
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/sendotp/',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      apikey: 'YOUR_API_KEY',
      partnerID: 'YOUR_PARTNER_ID',
      mobile: '254712345678',
      message: 'Your OTP is 483920',
      shortcode: 'YOUR_SENDER_ID',
      pass_type: 'plain',
    }),
  }
);

console.log(await response.json());

Send Bulk SMS

POST
POST
https://isms.celcomafrica.com/api/services/sendbulk

Send many personalized messages in one call. Provide count and an smslist array.

ParameterTypeRequiredDescription
countnumber
Required
Number of messages in smslist.
smslistarray
Required
Array of per-recipient SMS objects (partnerID, apikey, mobile, message, shortcode, pass_type, clientsmsid).
clientsmsidstringOptionalClient-generated unique ID per message for correlation (inside each smslist item).
Sample request - cURL
bash
curl --request POST 'https://isms.celcomafrica.com/api/services/sendbulk' \
  --header 'Content-Type: application/json' \
  --data '{
    "count": 2,
    "smslist": [
      {
        "partnerID": "YOUR_PARTNER_ID",
        "apikey": "YOUR_API_KEY",
        "pass_type": "plain",
        "clientsmsid": "msg-001",
        "mobile": "254712345678",
        "message": "Order confirmed",
        "shortcode": "YOUR_SENDER_ID"
      }
    ]
  }'
Sample request - Node.js
javascript
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/sendbulk',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      count: 2,
      smslist: [
        {
          partnerID: 'YOUR_PARTNER_ID',
          apikey: 'YOUR_API_KEY',
          pass_type: 'plain',
          clientsmsid: 'msg-001',
          mobile: '254712345678',
          message: 'Order confirmed',
          shortcode: 'YOUR_SENDER_ID',
        },
        {
          partnerID: 'YOUR_PARTNER_ID',
          apikey: 'YOUR_API_KEY',
          pass_type: 'plain',
          clientsmsid: 'msg-002',
          mobile: '254798765432',
          message: 'Order confirmed',
          shortcode: 'YOUR_SENDER_ID',
        },
      ],
    }),
  }
);

console.log(await response.json());

API response

Parsing

A successful send returns a JSON object with a responses array. Save the messageid - you'll need it to query delivery reports.

Sample response
json
{
  "responses": [
    {
      "respose-code": 200,
      "response-description": "Success",
      "mobile": 254713482448,
      "messageid": 8290842,
      "networkid": "1"
    }
  ]
}
respose-code

HTTP-style status (200 = success)

messageid

Use for delivery report queries

networkid

Destination carrier network

Message scheduling

Optional

Schedule messages for future delivery by including the optional timeToSend parameter with a date string or Unix timestamp.

Scheduled send payload
json
{
  "apikey": "123456789",
  "partnerID": "123",
  "message": "this is a test message",
  "shortcode": "SENDERID",
  "mobile": "254712345678",
  "timeToSend": "2019-09-01 18:00"
}

Delivery reports

POST
POST
https://isms.celcomafrica.com/api/services/getdlr/

Query delivery status for a sent message using the messageID from the send response.

Get delivery report - PHP
php
$url = 'https://isms.celcomafrica.com/api/services/getdlr/';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$data = [
  'partnerID' => '00',
  'apikey'    => 'xxxxxxxxxxxxx',
  'messageID' => '123456789',
];

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
print_r(curl_exec($curl));

Get last SMS DLR by mobile

POST
POST
https://isms.celcomafrica.com/api/services/getdlrbymobile/

Look up the latest delivery report for a recipient on a given send date when you do not have the messageID.

ParameterTypeRequiredDescription
apikeystring
Required
API authentication key issued to the partner.
partnerIDstring
Required
Unique partner identifier.
mobilestring
Required
Mobile number to look up (international format).
dateSentstring
Required
Date the message was sent (YYYY-MM-DD).
Sample request - cURL
bash
curl --request POST 'https://isms.celcomafrica.com/api/services/getdlrbymobile/' \
  --header 'Content-Type: application/json' \
  --data '{
    "apikey": "YOUR_API_KEY",
    "partnerID": "YOUR_PARTNER_ID",
    "mobile": "254712345678",
    "dateSent": "2026-06-17"
  }'
Sample request - Node.js
javascript
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/getdlrbymobile/',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      apikey: 'YOUR_API_KEY',
      partnerID: 'YOUR_PARTNER_ID',
      mobile: '254712345678',
      dateSent: '2026-06-17',
    }),
  }
);

console.log(await response.json());

Account balance

POST
POST
https://isms.celcomafrica.com/api/services/getbalance/

Check remaining SMS credits before sending campaigns or integrating balance alerts into your application.

Get account balance - PHP
php
$url = 'https://isms.celcomafrica.com/api/services/getbalance/';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$data = [
  'partnerID' => '00',
  'apikey'    => 'xxxxxxxxxxxxx',
];

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
print_r(curl_exec($curl));

Error codes

Reference

API responses include a numeric code in each response object. Use this table to diagnose failed requests.

CodeDescription
200Successful request
1001Invalid sender ID
1002Network not allowed
1003Invalid mobile number
1004Low bulk credits
1005Failed - system error
1006Invalid credentials
1007Failed - system error
1008No delivery report
1009Unsupported data type
1010Unsupported request type
4090Internal error - retry after 5 minutes
4091No Partner ID set
4092No API key provided
4093Details not found

Frequently asked questions

DEVELOPERS_FAQ

Register for a free account, open your dashboard and click GET API KEY & PARTNER ID to retrieve credentials. Review this documentation, copy a code sample in your language, and test with free SMS credits. Integration typically takes under 10 minutes.

Any language that can make HTTP requests. We provide working examples in PHP, Python, and Node.js. The API uses standard REST principles with JSON responses.

SMS Gateway API is our general-purpose REST API for marketing and notifications. A2P SMS Gateway is enterprise-grade for mission-critical messaging like OTPs and banking alerts, with premium routing and higher SLA. Both use similar endpoints.

Use the Get Delivery Report endpoint with the messageID returned from the send response. You can also view reports in your dashboard or configure webhooks for automatic notifications.

No strict rate limits for standard usage. API access is free - you only pay for SMS credits used, starting from KES 0.25 per SMS with volume discounts. See our SMS pricing for full rate tiers.

Yes. Pass the optional timeToSend parameter with a date string (e.g. 2019-09-01 18:00) or Unix timestamp. The API queues and delivers the message at the specified time.

Introduction

Overview

Send transactional and notification emails through Celcom Africa's Email API. Authenticate with your partner credentials, set from/to addresses, and optionally schedule delivery.

Before you begin

  1. Register for a free account
  2. Open your dashboard and click GET API KEY & PARTNER ID
  3. Use an approved from_address on your account

API parameters

Reference

All send-email requests require the parameters below. Optional fields enable encoding and scheduling.

ParameterTypeRequiredDescription
apikeystring
Required
Valid API key from your dashboard (GET API KEY & PARTNER ID).
partnerIDstring
Required
Partner ID attached to your account.
from_addressstring
Required
Sender email address (approved/registered from-address).
to_addressstring
Required
Destination / receiver email address.
subjectstring
Required
Email subject line.
bodystring
Required
Email message body.
pass_typestringOptionalplain (default) or bm5 (base64-encoded body).
timeToSendstringOptionalOptional. Schedule for future delivery.

Send email

Core endpoint
POST
https://isms.celcomafrica.com/api/services/send-email

Send a JSON body with Content-Type: application/json. Use pass_type: "plain" for normal text or bm5 for a base64-encoded body.

POST request - PHP
php
$url = 'https://isms.celcomafrica.com/api/services/send-email';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$data = [
  'partnerID'    => '00',
  'apikey'       => 'xxxxx',
  'from_address' => 'info@test.com',
  'to_address'   => 'test@gmail.com',
  'subject'      => 'Test Message API',
  'body'         => 'This is a test message',
  'pass_type'    => 'plain', // or bm5 (base64)
];

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($curl);
print_r($response);
POST request - Node.js
node.js
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/send-email',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      partnerID: '00',
      apikey: 'xxxxx',
      from_address: 'info@test.com',
      to_address: 'test@gmail.com',
      subject: 'Test Message API',
      body: 'This is a test message',
      pass_type: 'plain',
    }),
  }
);

const data = await response.json();
console.log(data);
POST request - Python
python
import requests

url = 'https://isms.celcomafrica.com/api/services/send-email'
payload = {
    'partnerID': '00',
    'apikey': 'xxxxx',
    'from_address': 'info@test.com',
    'to_address': 'test@gmail.com',
    'subject': 'Test Message API',
    'body': 'This is a test message',
    'pass_type': 'plain',
}

response = requests.post(url, json=payload)
print(response.json())

API response

Parsing

A successful send returns a JSON object with the recipient, message ID, and credit cost. Save messageid for your records.

Sample response
json
{
  "response-code": 200,
  "response-description": "Success",
  "recipient": "test@gmail.com",
  "messageid": "xxxx",
  "cost": 1
}
response-code

200 = success

messageid

Unique ID for the sent email

cost

Credits charged for the send

Message scheduling

Optional

Schedule emails for future delivery by including the optional timeToSend parameter.

Scheduled send payload
json
{
  "partnerID": "00",
  "apikey": "xxxxx",
  "from_address": "info@test.com",
  "to_address": "test@gmail.com",
  "subject": "Scheduled email",
  "body": "This message will send later",
  "pass_type": "plain",
  "timeToSend": "2019-09-01 18:00"
}

Introduction

Overview

Celcom Africa's WhatsApp APIs cover OTP delivery and template-based media messages. Authenticate with the same partner credentials used for SMS.

Before you begin

  1. Register for a free account
  2. Retrieve your API key and Partner ID
  3. Confirm WhatsApp OTP / template access is enabled on your account

OTP API parameters

Reference

WhatsApp OTP requests use the parameters below (aligned with the CPaaS API V2 collection).

ParameterTypeRequiredDescription
apikeystring
Required
API authentication key issued to the partner (lowercase apikey).
partnerIDstring
Required
Unique partner identifier.
mobilestring
Required
Recipient mobile number in international format. Example: 254712345678.
messagestring
Required
OTP value or OTP message text (e.g. 345344 or Your OTP is 2345).
senderIDstringOptionalOptional. Approved WhatsApp sender number (2547XXXXXXXX) when your account requires an explicit sender.

Phone number format

Important

mobile (and optional senderID) must use international formats without spaces or plus signs:

2547XXXXXXXX

Example: 254712345678

2541XXXXXXXX

Example: 254100123456

Send WhatsApp OTP

Core endpoint
POST
https://isms.celcomafrica.com/api/services/whatsapp/sendotp

POST a JSON body with Content-Type: application/json. Use lowercase apikey (same field name as the SMS and Email APIs). message may be the OTP digits alone.

Sample request - cURL
bash
curl --request POST 'https://isms.celcomafrica.com/api/services/whatsapp/sendotp' \
  --header 'Content-Type: application/json' \
  --data '{
    "apikey": "YOUR_API_KEY",
    "partnerID": "xx",
    "mobile": "254712345678",
    "message": "345344"
  }'
POST request - PHP
php
$url = 'https://isms.celcomafrica.com/api/services/whatsapp/sendotp';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$data = [
  'apikey'    => 'YOUR_API_KEY',
  'partnerID' => 'xx',
  'mobile'    => '254712345678',
  'message'   => '345344',
];

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($curl);
print_r($response);
POST request - Node.js
node.js
const response = await fetch(
  'https://isms.celcomafrica.com/api/services/whatsapp/sendotp',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      apikey: 'YOUR_API_KEY',
      partnerID: 'xx',
      mobile: '254712345678',
      message: '345344',
    }),
  }
);

const data = await response.json();
console.log(data);
POST request - Python
python
import requests

url = 'https://isms.celcomafrica.com/api/services/whatsapp/sendotp'
payload = {
    'apikey': 'YOUR_API_KEY',
    'partnerID': 'xx',
    'mobile': '254712345678',
    'message': '345344',
}

response = requests.post(url, json=payload)
print(response.json())

Send WhatsApp media message

POST
POST
https://isms.celcomafrica.com/api/services/whatsapp/sendmedia

Send a document or image with a Meta-approved WhatsApp template. This endpoint expects multipart/form-data (not JSON).

ParameterTypeRequiredDescription
apikeystring
Required
API authentication key issued to the partner.
partnerIDstring
Required
Unique partner identifier.
filefile
Required
Document or image media file to send (multipart form field).
templateIDstring
Required
Meta-approved WhatsApp message template ID.
messagevariablesstringOptionalRepeat this form field for each template body variable (e.g. first name, invoice number).
mobilestring
Required
Recipient mobile number in international format.
Sample request - cURL
bash
curl --request POST 'https://isms.celcomafrica.com/api/services/whatsapp/sendmedia' \
  --form 'apikey=YOUR_API_KEY' \
  --form 'partnerID=YOUR_PARTNER_ID' \
  --form 'file=@"/path/to/invoice.pdf"' \
  --form 'templateID=YOUR_TEMPLATE_ID' \
  --form 'messagevariables=Jane' \
  --form 'messagevariables=INV-1001' \
  --form 'mobile=254712345678'
Sample request - Node.js
javascript
const form = new FormData();
form.append('apikey', 'YOUR_API_KEY');
form.append('partnerID', 'YOUR_PARTNER_ID');
form.append('file', fileBlob, 'invoice.pdf');
form.append('templateID', 'YOUR_TEMPLATE_ID');
form.append('messagevariables', 'Jane');
form.append('messagevariables', 'INV-1001');
form.append('mobile', '254712345678');

const response = await fetch('https://isms.celcomafrica.com/api/services/whatsapp/sendmedia', {
  method: 'POST',
  body: form,
});

console.log(await response.json());

API response

Parsing

A successful request returns response-code: 200 and a messageid.

Sample success response
json
{
  "response-code": 200,
  "response-description": "success",
  "messageid": "MSG123456789"
}
Sample error response
json
{
  "response-code": 1003,
  "response-description": "Validation Errors. Check errors and try again",
  "errors": "[]"
}

Error codes

Reference

Use this table to diagnose failed WhatsApp OTP requests.

CodeDescription
200OTP accepted successfully
1003Validation errors (e.g. invalid phone number or sender ID)
1006Invalid credentials
402Low balance
500Internal server error

Ready to integrate?

Get your free API key, test with complimentary credits, and go live in minutes. Developer support is available 24/7.