Back to Home

API Documentation

Comprehensive guide to integrate SMS & WhatsApp messaging

Getting Started

Welcome! This API allows you to send SMS and WhatsApp messages from your application. Get your API key from your account manager and start integrating in minutes.

Base URL

https://crm.pradytecai.com/api

Quick Start

Follow these steps to send your first SMS:

  1. Get your API key - Go to Settings โ†’ Profile in your dashboard
  2. Note your client ID - Usually 1 for the main account
  3. Make your first API call - Use the unified messages endpoint
curl -X POST https://crm.pradytecai.com/api/1/messages/send \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 1,
    "channel": "sms",
    "recipient": "254712345678",
    "sender": "YOUR-SENDER-ID",
    "body": "Hello from our platform!"
  }'

Authentication

All API requests must include your API key in the request header.

API Key Header

X-API-KEY: your-api-key-here
Keep it secret! Never expose your API key in client-side code or public repositories. The header name is case-sensitive: use X-API-KEY (all caps).

Client ID

Your Client ID is part of the API endpoint URL. It identifies your account.

/api/{client_id}/endpoint

SMS Endpoints

๐Ÿ’ก Recommended: Use the Unified Messages API (/messages/send) for simpler integration. It works for SMS, WhatsApp, and Email with consistent parameters.

Send SMS (Unified API - Recommended)

POST /api/{client_id}/messages/send

Send an SMS message using the unified messaging API. This is the simplest and most flexible method.

Request Parameters

Parameter Type Required Description
client_id integer Required Your client ID (usually 1)
channel string Required Message channel: sms, whatsapp, or email
recipient string Required Phone number in international format (e.g., 254712345678)
sender string Required Your approved sender ID (max 11 characters)
body string Required Message content (max 480 characters for concatenated SMS)

Example Request

curl -X POST https://crm.pradytecai.com/api/1/messages/send \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 1,
    "channel": "sms",
    "recipient": "254712345678",
    "sender": "HOSPITAL",
    "body": "Your appointment is tomorrow at 10am"
  }'
$ch = curl_init('https://crm.pradytecai.com/api/1/messages/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-KEY: your-api-key-here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'client_id' => 1,
    'channel' => 'sms',
    'recipient' => '254712345678',
    'sender' => 'HOSPITAL',
    'body' => 'Your appointment is tomorrow at 10am'
]));

$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch);

print_r($result);
import requests

url = 'https://crm.pradytecai.com/api/1/messages/send'
headers = {
    'X-API-KEY': 'your-api-key-here',
    'Content-Type': 'application/json'
}
data = {
    'client_id': 1,
    'channel': 'sms',
    'recipient': '254712345678',
    'sender': 'HOSPITAL',
    'body': 'Your appointment is tomorrow at 10am'
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
const axios = require('axios');

axios.post('https://crm.pradytecai.com/api/1/messages/send', {
  client_id: 1,
  channel: 'sms',
  recipient: '254712345678',
  sender: 'HOSPITAL',
  body: 'Your appointment is tomorrow at 10am'
}, {
  headers: {
    'X-API-KEY': 'your-api-key-here',
    'Content-Type': 'application/json'
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error.response.data);
});

Example Response (Success)

{
  "id": 123,
  "status": "sent",
  "provider_message_id": "MSG-ABC123"
}

Send Bulk SMS (Alternative Method)

POST /api/{client_id}/sms/send

Send SMS to multiple recipients at once. Note: This endpoint uses different parameter names.

โš ๏ธ Important: This endpoint uses recipients (plural, array) not recipient (singular)!

Request Parameters

Parameter Type Required Description
recipients array Required Array of phone numbers (max 1000 per request)
message string Required Message content (max 160 characters per SMS)
sender_id string Optional Sender ID (uses default if not provided)

Example Request

curl -X POST https://crm.pradytecai.com/api/1/sms/send \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": ["254712345678", "254723456789"],
    "message": "Bulk SMS notification",
    "sender_id": "HOSPITAL"
  }'

Example Response

{
  "status": "success",
  "sent": 2,
  "failed": 0,
  "total_cost": 2.00,
  "results": [
    {
      "recipient": "254712345678",
      "status": "sent",
      "message_id": "MSG-123"
    },
    {
      "recipient": "254723456789",
      "status": "sent",
      "message_id": "MSG-124"
    }
  ]
}

Check SMS Status

GET /api/{client_id}/sms/status/{message_id}

Check the delivery status of a sent message.

Example Request

curl -X GET https://crm.pradytecai.com/api/1/sms/status/MSG-123456 \
  -H "X-API-Key: sk_abc123xyz456"

Example Response

{
  "message_id": "MSG-123456",
  "recipient": "254712345678",
  "status": "delivered",
  "sent_at": "2025-10-09T14:30:00Z",
  "delivered_at": "2025-10-09T14:30:15Z"
}

Possible Status Values

  • queued - Message is queued for sending
  • sent - Message has been sent to the provider
  • delivered - Message was delivered to recipient
  • failed - Message delivery failed

Get SMS History

GET /api/{client_id}/sms/history

Retrieve your message history with optional filters.

Query Parameters

Parameter Type Required Description
page integer Optional Page number (default: 1)
per_page integer Optional Results per page (default: 20, max: 100)
status string Optional Filter by status (queued, sent, delivered, failed)

Example Request

curl -X GET "https://crm.pradytecai.com/api/1/sms/history?page=1&per_page=20&status=delivered" \
  -H "X-API-Key: sk_abc123xyz456"

Example Response

{
  "data": [
    {
      "message_id": "MSG-123456",
      "recipient": "254712345678",
      "message": "Your appointment is tomorrow",
      "status": "delivered",
      "cost": 1.00,
      "sent_at": "2025-10-09T14:30:00Z",
      "delivered_at": "2025-10-09T14:30:15Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1250,
    "per_page": 20,
    "last_page": 63
  }
}

Get SMS Statistics

GET /api/{client_id}/sms/statistics

Get summary statistics for your SMS usage.

Example Response

{
  "total_sent": 1250,
  "total_delivered": 1200,
  "total_failed": 50,
  "total_cost": 1250.00,
  "today": {
    "sent": 45,
    "delivered": 43,
    "failed": 2,
    "cost": 45.00
  },
  "this_month": {
    "sent": 890,
    "delivered": 850,
    "failed": 40,
    "cost": 890.00
  }
}

WhatsApp Endpoints

Send WhatsApp Message

POST /api/{client_id}/messages/send

Send a WhatsApp message using the unified messaging endpoint.

Request Parameters

Parameter Type Required Description
channel string Required Must be "whatsapp"
recipient string Required Phone number in international format
body string Required Message content
sender string Optional Your WhatsApp sender ID

Example Request

curl -X POST https://crm.pradytecai.com/api/1/messages/send \
  -H "X-API-Key: sk_abc123xyz456" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "recipient": "254712345678",
    "body": "Your order has been shipped!",
    "sender": "YOUR-BUSINESS"
  }'

Wallet & Top-up Endpoints

Check Balance

GET /api/{client_id}/client/balance

Check your current account balance.

Example Request

curl -X GET https://crm.pradytecai.com/api/1/client/balance \
  -H "X-API-Key: sk_abc123xyz456"

Example Response

{
  "balance": 1049.00,
  "currency": "KES",
  "units": 1049,
  "price_per_unit": 1.00,
  "low_balance": false
}

Initiate Top-up (M-Pesa)

POST /api/{client_id}/wallet/topup
New Feature! This endpoint initiates an M-Pesa STK Push to add credits to your account.

Initiate a top-up request using M-Pesa STK Push.

Request Parameters

Parameter Type Required Description
amount number Required Amount in KES (min: 100, max: 50000)
payment_method string Required Must be "mpesa"
phone_number string Required M-Pesa phone number (254XXXXXXXXX)

Example Request

curl -X POST https://crm.pradytecai.com/api/1/wallet/topup \
  -H "X-API-Key: sk_abc123xyz456" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "payment_method": "mpesa",
    "phone_number": "254712345678"
  }'

Example Response

{
  "status": "pending",
  "message": "Please check your phone for M-Pesa prompt",
  "transaction_id": "TXN-20251009-001",
  "amount": 1000,
  "checkout_request_id": "ws_CO_09012025..."
}

Check Top-up Status

GET /api/{client_id}/wallet/topup/{transaction_id}

Check the status of a top-up request.

Example Request

curl -X GET https://crm.pradytecai.com/api/1/wallet/topup/TXN-20251009-001 \
  -H "X-API-Key: sk_abc123xyz456"

Example Response

{
  "transaction_id": "TXN-20251009-001",
  "status": "completed",
  "amount": 1000.00,
  "payment_method": "mpesa",
  "mpesa_receipt": "PGH7X8Y9Z0",
  "completed_at": "2025-10-09T14:35:00Z"
}

Possible Status Values

  • pending - Waiting for payment
  • processing - Payment is being processed
  • completed - Payment successful, balance updated
  • failed - Payment failed or cancelled

Transaction History

GET /api/{client_id}/wallet/transactions

Get your wallet transaction history.

Query Parameters

Parameter Type Description
from_date date Filter from date (YYYY-MM-DD)
to_date date Filter to date (YYYY-MM-DD)
type string credit, debit, or refund
page integer Page number (default: 1)

Example Response

{
  "data": [
    {
      "id": 123,
      "type": "credit",
      "amount": 1000.00,
      "payment_method": "mpesa",
      "mpesa_receipt": "PGH7X8Y9Z0",
      "status": "completed",
      "created_at": "2025-10-09T14:35:00Z"
    },
    {
      "id": 122,
      "type": "debit",
      "amount": 1.00,
      "description": "SMS to 254712345678",
      "status": "completed",
      "created_at": "2025-10-09T14:30:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 150,
    "per_page": 20
  }
}

Contacts Endpoints

List Contacts

GET /api/{client_id}/contacts

Create Contact

POST /api/{client_id}/contacts

Example Request

{
  "name": "John Doe",
  "phone": "254712345678",
  "email": "john@example.com",
  "department": "Sales"
}

Bulk Import Contacts (CSV)

POST /api/{client_id}/contacts/bulk-import

Upload a CSV file with contacts.

CSV Format

Name,Phone,Email,Department
John Doe,254712345678,john@example.com,Sales
Jane Smith,254723456789,jane@example.com,Marketing

Campaigns Endpoints

Create Campaign

POST /api/{client_id}/campaigns

Example Request

{
  "name": "Monthly Newsletter",
  "message": "Check out our latest offers!",
  "sender": "YOURSTORE",
  "recipients": ["254712345678", "254723456789"]
}

Send Campaign

POST /api/{client_id}/campaigns/{campaign_id}/send

Send a created campaign to all recipients.

Webhooks

Stay updated! Configure a webhook URL to receive real-time notifications about events in your account.

Configure Webhook

Contact your account manager to set up your webhook URL and secret key.

Webhook Events

  • balance.updated - Your balance has changed
  • message.delivered - A message was delivered
  • message.failed - A message failed to deliver
  • topup.completed - A top-up was successful
  • topup.failed - A top-up failed

Webhook Payload Format

POST https://your-system.com/webhook

Headers:
  X-Webhook-Signature: sha256_hmac_signature
  X-Webhook-Event: balance.updated
  Content-Type: application/json

Body:
{
  "event": "balance.updated",
  "client_id": 1,
  "timestamp": "2025-10-09T14:35:00Z",
  "data": {
    "old_balance": 50.00,
    "new_balance": 1050.00,
    "amount_added": 1000.00,
    "transaction_id": "TXN-20251009-001"
  }
}

Verifying Webhook Signatures

$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$payload = file_get_contents('php://input');
$secret = 'your-webhook-secret';

$expectedSignature = hash_hmac('sha256', $payload, $secret);

if (hash_equals($expectedSignature, $signature)) {
    // Signature is valid
    $data = json_decode($payload, true);
    // Process webhook...
} else {
    // Invalid signature
    http_response_code(401);
}
import hmac
import hashlib

signature = request.headers.get('X-Webhook-Signature')
payload = request.get_data()
secret = b'your-webhook-secret'

expected_signature = hmac.new(secret, payload, hashlib.sha256).hexdigest()

if hmac.compare_digest(expected_signature, signature):
    # Signature is valid
    data = request.get_json()
    # Process webhook...
else:
    # Invalid signature
    return 'Unauthorized', 401
const crypto = require('crypto');

const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
const secret = 'your-webhook-secret';

const expectedSignature = crypto
  .createHmac('sha256', secret)
  .update(payload)
  .digest('hex');

if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
    // Signature is valid
    // Process webhook...
} else {
    // Invalid signature
    res.status(401).send('Unauthorized');
}

Error Codes

Status Code Error Code Description
400 INVALID_REQUEST Required parameters are missing or invalid
401 INVALID_API_KEY API key is missing or invalid
402 INSUFFICIENT_BALANCE Your account balance is too low
403 UNAUTHORIZED You don't have permission to access this resource
404 NOT_FOUND The requested resource was not found
429 RATE_LIMIT_EXCEEDED Too many requests, slow down
500 SERVER_ERROR Internal server error, please try again

Error Response Format

{
  "status": "error",
  "error_code": "INSUFFICIENT_BALANCE",
  "message": "Your account balance is too low. Current balance: KES 5.00",
  "balance": 5.00
}

Complete Code Examples

PHP Integration Example

<?php

class BulkSMSClient {
    private $apiKey;
    private $clientId;
    private $baseUrl;
    
    public function __construct($apiKey, $clientId) {
        $this->apiKey = $apiKey;
        $this->clientId = $clientId;
        $this->baseUrl = 'https://crm.pradytecai.com/api/' . $clientId;
    }
    
    public function sendSMS($recipient, $message, $sender) {
        $ch = curl_init($this->baseUrl . '/sms/send');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'recipient' => $recipient,
            'message' => $message,
            'sender' => $sender
        ]));
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        return [
            'status' => $httpCode,
            'data' => json_decode($response, true)
        ];
    }
    
    public function checkBalance() {
        $ch = curl_init($this->baseUrl . '/client/balance');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey
        ]);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
    
    public function topUp($amount, $phoneNumber) {
        $ch = curl_init($this->baseUrl . '/wallet/topup');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'amount' => $amount,
            'payment_method' => 'mpesa',
            'phone_number' => $phoneNumber
        ]));
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
}

// Usage
$client = new BulkSMSClient('sk_abc123xyz456', 1);

// Send SMS
$result = $client->sendSMS('254712345678', 'Hello World', 'YOURAPP');
print_r($result);

// Check balance
$balance = $client->checkBalance();
echo "Balance: KES " . $balance['balance'];

// Top up
$topup = $client->topUp(1000, '254712345678');
print_r($topup);
?>

Python Integration Example

import requests

class BulkSMSClient:
    def __init__(self, api_key, client_id):
        self.api_key = api_key
        self.client_id = client_id
        self.base_url = f'https://crm.pradytecai.com/api/{client_id}'
        self.headers = {
            'X-API-Key': api_key,
            'Content-Type': 'application/json'
        }
    
    def send_sms(self, recipient, message, sender):
        url = f'{self.base_url}/sms/send'
        data = {
            'recipient': recipient,
            'message': message,
            'sender': sender
        }
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()
    
    def check_balance(self):
        url = f'{self.base_url}/client/balance'
        response = requests.get(url, headers=self.headers)
        return response.json()
    
    def topup(self, amount, phone_number):
        url = f'{self.base_url}/wallet/topup'
        data = {
            'amount': amount,
            'payment_method': 'mpesa',
            'phone_number': phone_number
        }
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()

# Usage
client = BulkSMSClient('sk_abc123xyz456', 1)

# Send SMS
result = client.send_sms('254712345678', 'Hello World', 'YOURAPP')
print(result)

# Check balance
balance = client.check_balance()
print(f"Balance: KES {balance['balance']}")

# Top up
topup_result = client.topup(1000, '254712345678')
print(topup_result)

Client Integration Guide

For Organizations Integrating with Our API: This guide provides everything you need to integrate SMS sending into your application using our API.

๐Ÿ“‹ Your API Credentials

You will receive these credentials from your account manager:

API Base URL:  https://crm.pradytecai.com/api
Client ID:     1 (or your assigned ID)
API Key:       Your unique API key
Sender ID:     Your approved sender name
โš ๏ธ Security: Never commit your API key to version control or share it publicly. Store it securely in environment variables.

๐Ÿš€ Quick Start Configuration

Add to your .env file:

# SMS API Configuration
SMS_API_URL=https://crm.pradytecai.com/api
SMS_CLIENT_ID=1
SMS_API_KEY=your_api_key_here
SMS_SENDER_ID=YOUR_SENDER

Complete PHP Integration Class:

<?php

class SMSClient {
    private $apiUrl;
    private $clientId;
    private $apiKey;
    private $senderId;

    public function __construct() {
        $this->apiUrl = getenv('SMS_API_URL') ?: 'https://crm.pradytecai.com/api';
        $this->clientId = getenv('SMS_CLIENT_ID') ?: '1';
        $this->apiKey = getenv('SMS_API_KEY');
        $this->senderId = getenv('SMS_SENDER_ID');
    }

    /**
     * Send SMS message
     */
    public function sendSMS($recipient, $message) {
        $url = "{$this->apiUrl}/{$this->clientId}/messages/send";
        
        $data = [
            'channel' => 'sms',
            'recipient' => $recipient,
            'body' => $message,
            'sender' => $this->senderId
        ];

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey,
            'Content-Type: application/json',
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            return json_decode($response, true);
        } else {
            throw new Exception("SMS Error: " . $response);
        }
    }

    /**
     * Check account balance
     */
    public function checkBalance() {
        $url = "{$this->apiUrl}/{$this->clientId}/client/balance";
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey,
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }

    /**
     * Get SMS history
     */
    public function getHistory($page = 1, $status = 'all') {
        $url = "{$this->apiUrl}/{$this->clientId}/sms/history?page={$page}&status={$status}";
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey,
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }
}

// Usage Example
try {
    $sms = new SMSClient();
    
    // Send SMS
    $result = $sms->sendSMS('254712345678', 'Hello from your app!');
    echo "Message sent! ID: " . $result['data']['id'] . "\n";
    
    // Check Balance
    $balance = $sms->checkBalance();
    echo "Balance: KSH " . $balance['data']['balance'] . "\n";
    
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>

Laravel Service Class (app/Services/SmsService.php):

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class SmsService
{
    private $apiUrl;
    private $clientId;
    private $apiKey;
    private $senderId;

    public function __construct()
    {
        $this->apiUrl = config('services.sms.api_url');
        $this->clientId = config('services.sms.client_id');
        $this->apiKey = config('services.sms.api_key');
        $this->senderId = config('services.sms.sender_id');
    }

    public function send($recipient, $message)
    {
        try {
            $response = Http::withHeaders([
                'X-API-Key' => $this->apiKey,
                'Content-Type' => 'application/json',
            ])->post("{$this->apiUrl}/{$this->clientId}/messages/send", [
                'channel' => 'sms',
                'recipient' => $recipient,
                'body' => $message,
                'sender' => $this->senderId,
            ]);

            if ($response->successful()) {
                return $response->json();
            }

            throw new \Exception('SMS sending failed: ' . $response->body());

        } catch (\Exception $e) {
            Log::error('SMS Error: ' . $e->getMessage());
            throw $e;
        }
    }

    public function checkBalance()
    {
        $response = Http::withHeaders([
            'X-API-Key' => $this->apiKey,
        ])->get("{$this->apiUrl}/{$this->clientId}/client/balance");

        return $response->json();
    }
}
?>

Add to config/services.php:

'sms' => [
    'api_url' => env('SMS_API_URL', 'https://crm.pradytecai.com/api'),
    'client_id' => env('SMS_CLIENT_ID', '1'),
    'api_key' => env('SMS_API_KEY'),
    'sender_id' => env('SMS_SENDER_ID'),
],

Usage in Controller:

use App\Services\SmsService;

class NotificationController extends Controller
{
    protected $sms;

    public function __construct(SmsService $sms)
    {
        $this->sms = $sms;
    }

    public function sendNotification()
    {
        try {
            $result = $this->sms->send('254712345678', 'Your verification code is 1234');
            return response()->json(['success' => true, 'data' => $result]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'error' => $e->getMessage()], 500);
        }
    }
}

Complete Python Integration Class:

import requests
import os
from typing import Dict

class SMSClient:
    def __init__(self):
        self.api_url = os.getenv('SMS_API_URL', 'https://crm.pradytecai.com/api')
        self.client_id = os.getenv('SMS_CLIENT_ID', '1')
        self.api_key = os.getenv('SMS_API_KEY')
        self.sender_id = os.getenv('SMS_SENDER_ID')
        
        self.headers = {
            'X-API-Key': self.api_key,
            'Content-Type': 'application/json'
        }
    
    def send_sms(self, recipient: str, message: str) -> Dict:
        """Send SMS message"""
        url = f'{self.api_url}/{self.client_id}/messages/send'
        
        data = {
            'channel': 'sms',
            'recipient': recipient,
            'body': message,
            'sender': self.sender_id
        }
        
        response = requests.post(url, headers=self.headers, json=data)
        
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"SMS Error: {response.text}")
    
    def check_balance(self) -> Dict:
        """Check account balance"""
        url = f'{self.api_url}/{self.client_id}/client/balance'
        response = requests.get(url, headers=self.headers)
        return response.json()
    
    def get_history(self, page: int = 1, status: str = 'all') -> Dict:
        """Get SMS history"""
        url = f'{self.api_url}/{self.client_id}/sms/history'
        params = {'page': page, 'status': status}
        response = requests.get(url, headers=self.headers, params=params)
        return response.json()

# Usage Example
if __name__ == '__main__':
    sms = SMSClient()
    
    try:
        # Send SMS
        result = sms.send_sms('254712345678', 'Hello from Python!')
        print(f"Message sent! ID: {result['data']['id']}")
        
        # Check Balance
        balance = sms.check_balance()
        print(f"Balance: KSH {balance['data']['balance']}")
        
    except Exception as e:
        print(f"Error: {e}")

Complete Node.js Integration Class:

const axios = require('axios');

class SMSClient {
    constructor() {
        this.apiUrl = process.env.SMS_API_URL || 'https://crm.pradytecai.com/api';
        this.clientId = process.env.SMS_CLIENT_ID || '1';
        this.apiKey = process.env.SMS_API_KEY;
        this.senderId = process.env.SMS_SENDER_ID;
        
        this.headers = {
            'X-API-Key': this.apiKey,
            'Content-Type': 'application/json'
        };
    }

    async sendSMS(recipient, message) {
        try {
            const response = await axios.post(
                `${this.apiUrl}/${this.clientId}/messages/send`,
                {
                    channel: 'sms',
                    recipient: recipient,
                    body: message,
                    sender: this.senderId
                },
                { headers: this.headers }
            );
            
            return response.data;
        } catch (error) {
            throw new Error(`SMS Error: ${error.response?.data || error.message}`);
        }
    }

    async checkBalance() {
        try {
            const response = await axios.get(
                `${this.apiUrl}/${this.clientId}/client/balance`,
                { headers: this.headers }
            );
            return response.data;
        } catch (error) {
            throw new Error(`Balance Check Error: ${error.message}`);
        }
    }

    async getHistory(page = 1, status = 'all') {
        try {
            const response = await axios.get(
                `${this.apiUrl}/${this.clientId}/sms/history`,
                {
                    headers: this.headers,
                    params: { page, status }
                }
            );
            return response.data;
        } catch (error) {
            throw new Error(`History Error: ${error.message}`);
        }
    }
}

// Usage Example
(async () => {
    const sms = new SMSClient();
    
    try {
        // Send SMS
        const result = await sms.sendSMS('254712345678', 'Hello from Node.js!');
        console.log(`Message sent! ID: ${result.data.id}`);
        
        // Check Balance
        const balance = await sms.checkBalance();
        console.log(`Balance: KSH ${balance.data.balance}`);
        
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

module.exports = SMSClient;

๐Ÿ”Œ cURL Quick Test Commands

1. Test API Health (No Auth Required):

curl https://crm.pradytecai.com/api/health

2. Send SMS:

curl -X POST https://crm.pradytecai.com/api/1/messages/send \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "sms",
    "recipient": "254712345678",
    "body": "Hello from API!",
    "sender": "YOUR_SENDER"
  }'

3. Check Balance:

curl -H "X-API-Key: your_api_key_here" \
  https://crm.pradytecai.com/api/1/client/balance

4. Get SMS History:

curl -H "X-API-Key: your_api_key_here" \
  "https://crm.pradytecai.com/api/1/sms/history?page=1&status=sent"

๐Ÿ’ฐ Pricing & Billing

Message Length Units Cost (KSH 1.00/unit)
1-160 characters 1 unit KSH 1.00
161-320 characters 2 units KSH 2.00
321-480 characters 3 units KSH 3.00

๐Ÿ”’ Security Best Practices

  • Environment Variables: Always store API keys in environment variables, never hardcode
  • HTTPS Only: Use https:// not http:// in production
  • Phone Format: Always use international format: 254XXXXXXXXX
  • .gitignore: Add .env to your .gitignore file
  • Error Handling: Implement proper try-catch blocks and logging
  • Rate Limiting: Monitor your API usage and implement backoff strategies

๐Ÿ“Š API Response Format

Success Response:

{
  "status": "success",
  "message": "Message queued for sending",
  "data": {
    "id": 123,
    "channel": "sms",
    "recipient": "254712345678",
    "status": "queued",
    "cost": 1.00
  }
}

Error Response:

{
  "status": "error",
  "message": "Insufficient balance",
  "errors": []
}

๐Ÿงช Testing Checklist

Before going live, test:
  1. โœ… API health check works
  2. โœ… Authentication with your API key works
  3. โœ… Can check your balance
  4. โœ… Can send test SMS successfully
  5. โœ… SMS is actually delivered
  6. โœ… Balance is deducted correctly
  7. โœ… Error handling works (try invalid API key)
  8. โœ… History shows sent messages

โ— Common Issues & Solutions

Issue Solution
"Invalid API key" Verify API key is correct and header name is exactly X-API-Key
"Insufficient balance" Check your balance and contact support to add more units
"Message failed" Verify phone number format (254XXXXXXXXX) and sender ID is active
"Rate limit exceeded" Implement exponential backoff or contact support to upgrade tier

Need Help?

Contact Support:

  • Email: support@yourplatform.com
  • Phone: +254 XXX XXX XXX
  • Hours: Monday - Friday, 8am - 6pm EAT