API Documentation

Integrate JX-SMS into your application. Send SMS, check delivery, manage contacts — all via simple REST API.

PHP SDK Python SDK Node.js SDK

Getting Started

The JX-SMS API lets you send SMS messages, check delivery status, manage contacts, and query your account balance programmatically. All endpoints return JSON.

Quick Start
  1. Create a free account
  2. Go to Developer > API Keys in your dashboard
  3. Generate an API key pair (key + secret)
  4. Use the key pair to authenticate API requests
Base URL
https://jxsms.co/api/v1/

All API endpoints are relative to this base URL. Use HTTPS in production.


Authentication

All API requests require your API key and secret. Pass them as HTTP headers:

HeaderValue
X-API-KeyYour 32-character API key
X-API-SecretYour 48-character API secret

Alternatively, pass as POST/GET parameters api_key and api_secret.

Example Headers
X-API-Key: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
X-API-Secret: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6
Security
Never expose your API secret in client-side code (JavaScript, mobile apps). Always make API calls from your server.

Error Handling

All errors return a JSON object with error: true and a human-readable message.

HTTP CodeMeaning
200Success
400Bad request — missing or invalid parameters
401Authentication failed — invalid API key/secret
402Insufficient balance
404Resource not found
429Rate limit exceeded
Error Response Example
{"error": true, "message": "Insufficient balance", "balance": 500, "required": 1200}

Rate Limits

Default: 100 requests per minute per API key. If exceeded, you'll receive a 429 response. Contact support for higher limits.


Endpoints

POST
Send SMS
POST https://jxsms.co/api/v1/send

Send a single SMS message to one recipient. The cost is automatically deducted from your balance.

Parameters
ParameterTypeRequiredDescription
phone_numberstringRequiredRecipient phone number. Formats: 256770123456, 0770123456, 770123456
messagestringRequiredSMS text (max 320 chars). Messages over 160 chars count as 2 SMS.
sender_idstringOptionalSender name (max 11 chars). Default: JX-SMS
Success Response
{
    "success": true,
    "message_id": "abc123def456",
    "phone": "256770123456",
    "telecom": "MTN",
    "status": "SENT",
    "sms_count": 1,
    "cost": 35,
    "balance": 49965
}
POST
Send Bulk SMS
POST https://jxsms.co/api/v1/send-bulk

Send the same message to multiple recipients. Batches over 50 are queued for background delivery.

Parameters
ParameterTypeRequiredDescription
phone_numbersstring or arrayRequiredComma-separated list or JSON array of phone numbers
messagestringRequiredSMS text (max 320 chars)
sender_idstringOptionalSender name (max 11 chars). Default: JX-SMS
Success Response
{
    "success": true,
    "campaign_id": "api_6612f4a3b2c1e",
    "total": 150,
    "sent": 50,
    "queued": 100,
    "cost": 5250,
    "balance": 44750
}

Blacklisted numbers are automatically filtered out. Duplicate numbers are removed.

GET
Check Balance
GET https://jxsms.co/api/v1/balance

Returns your current account balance in UGX.

{"success": true, "balance": 49965, "currency": "UGX"}
GET
Delivery Status
GET https://jxsms.co/api/v1/status?message_id=abc123

Check the delivery status of a previously sent message using the message_id from the send response.

ParameterTypeRequiredDescription
message_idstringRequiredThe message_id returned from the send endpoint
{
    "success": true,
    "phone": "256770123456",
    "status": "DELIVERED",
    "telecom": "MTN",
    "cost": 35,
    "sent_at": "2026-03-30 14:22:01",
    "delivered_at": "2026-03-30 14:22:03"
}
Possible Statuses
StatusDescription
SENTMessage accepted by the gateway
DELIVEREDConfirmed delivered to handset
FAILEDDelivery failed (invalid number, network error, etc.)
PENDINGMessage is in the queue awaiting delivery
EXPIREDMessage expired before delivery
REJECTEDMessage rejected by the network
GET
Contacts & Groups
GET https://jxsms.co/api/v1/contacts

List your contact groups, or get contacts within a specific group.

ParameterTypeRequiredDescription
group_idintegerOptionalIf provided, returns contacts in that group. Otherwise returns all groups.
List Groups Response
{"success": true, "groups": [{"group_id": 1, "group_name": "VIP Customers", "contact_count": 245}]}
List Contacts Response
{"success": true, "group_id": 1, "contacts": [{"phone_number": "256770123456", "contact_name": "John"}]}
GET
Pricing
GET https://jxsms.co/api/v1/pricing

Returns your SMS pricing per network operator.

{
    "success": true,
    "pricing": [
        {"prefix": "25677", "telecom": "MTN", "price_per_sms": 35, "currency": "UGX"},
        {"prefix": "25670", "telecom": "Airtel", "price_per_sms": 35, "currency": "UGX"},
        {"prefix": "25679", "telecom": "Africell", "price_per_sms": 35, "currency": "UGX"}
    ]
}

SDKs & Downloads

Download our official SDKs — single-file, zero-config libraries for instant integration.

PHP SDK

PHP 7.0+ • cURL • Zero dependencies

JxSms.php
require_once 'JxSms.php';
Python SDK

Python 3.6+ • requests library

jxsms.py
from jxsms import JxSms
Node.js SDK

Node 18+ • Zero dependencies (fetch)

jxsms.js
const JxSms = require('./jxsms');
SDK Quick Start
PHP — send SMS in 3 lines
require_once 'JxSms.php';

$sms = new JxSms('YOUR_API_KEY', 'YOUR_API_SECRET');

// Send single SMS
$result = $sms->send('0770123456', 'Hello from JX-SMS!');
echo "Cost: UGX " . $result['cost'];

// Send bulk
$result = $sms->sendBulk(['0770123456', '0780654321'], 'Promo offer!');

// Check balance
$balance = $sms->balance();
echo "Balance: UGX " . $balance['balance'];

// Error handling
try {
    $sms->send('0770123456', 'Hello!');
} catch (JxSmsException $e) {
    echo "Error: " . $e->getMessage();  // "Insufficient balance"
    print_r($e->getResponse());         // Full API response
}
Python
from jxsms import JxSms, JxSmsError

sms = JxSms('YOUR_API_KEY', 'YOUR_API_SECRET')

# Send single SMS
result = sms.send('0770123456', 'Hello from JX-SMS!')
print(f"Cost: UGX {result['cost']}")

# Send bulk
result = sms.send_bulk(['0770123456', '0780654321'], 'Promo offer!')

# Error handling
try:
    sms.send('0770123456', 'Hello!')
except JxSmsError as e:
    print(f"Error: {e}")
    print(e.response)  # Full API response dict
Node.js
const JxSms = require('./jxsms');

const sms = new JxSms('YOUR_API_KEY', 'YOUR_API_SECRET');

// Send single SMS
const result = await sms.send('0770123456', 'Hello from JX-SMS!');
console.log(`Cost: UGX ${result.cost}`);

// Send bulk
const bulk = await sms.sendBulk(['0770123456', '0780654321'], 'Promo!');

// Error handling
try {
    await sms.send('0770123456', 'Hello!');
} catch (err) {
    console.error(err.message);   // "Insufficient balance"
    console.error(err.response);  // Full API response
}

cURL Examples

If you prefer raw HTTP calls without an SDK:

cURL
Terminal
# Send single SMS
curl -X POST https://jxsms.co/api/v1/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -d "phone_number=256770123456" \
  -d "message=Hello from JX-SMS!" \
  -d "sender_id=MyBrand"

# Send bulk SMS
curl -X POST https://jxsms.co/api/v1/send-bulk \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -d "phone_numbers=256770123456,256780654321,256750111222" \
  -d "message=Bulk hello!"

# Check balance
curl -H "X-API-Key: YOUR_API_KEY" \
     -H "X-API-Secret: YOUR_API_SECRET" \
     https://jxsms.co/api/v1/balance
# Check delivery status
curl -H "X-API-Key: YOUR_API_KEY" \
     -H "X-API-Secret: YOUR_API_SECRET" \
     "https://jxsms.co/api/v1/status?message_id=abc123"

Webhooks

Coming Soon
Delivery report webhooks are in development. You'll be able to receive real-time push notifications when message status changes (DELIVERED, FAILED, etc.).

Need Help?

Our team is ready to help you integrate.

JX-SMS Support
Online | Typically replies instantly