API v2 Documentation

Recommended

Version 2 uses API key authentication with enhanced security and features.

Overview

Base URL
https://ugsms.com/api/v2
Features
  • API Key Authentication - Secure token-based authentication
  • Rate Limiting - 60 requests per minute per API key
  • Bulk SMS Support - Send personalized messages in bulk
  • Usage Statistics - Track your API usage
  • Balance Check - Real-time balance inquiry
  • Improved Security - No password transmission
Response Format
{
    "success": true,
    "message": "Operation successful",
    "data": {
        // Response data
    }
}

Authentication

All v2 endpoints require API key authentication. You can provide the API key in three ways:

1. HTTP Header (Recommended)
X-API-Key: your_api_key_here
2. Query Parameter
GET https://ugsms.com/api/v2/account/balance?api_key=your_api_key_here
3. Request Body
{
    "api_key": "your_api_key_here",
    "numbers": "0702913454",
    "message_body": "Hello"
}
Get Your API Key: Log into your UGSMS dashboard → Settings → API Settings → Generate API Key

Send SMS

POST /api/v2/sms/send (GET also supported)

Send SMS to one or multiple Ugandan mobile numbers.

Request Parameters
Parameter Type Required Description Example
numbers String Yes Comma-separated phone numbers 0702913454,0776913451
message_body String Yes SMS message content (max 160 chars per segment) Hello from UGSMS
sender_id String No Sender ID (max 11 characters) UGSMS
api_key String No* API key (if not using X-API-Key header) abc123...

* API key is required but can be provided via header instead.

Example Request
curl -X POST "https://ugsms.com/api/v2/sms/send" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "numbers": "0702913454,0776913451",
    "message_body": "Hello from UGSMS API v2",
    "sender_id": "UGSMS"
  }'
fetch('https://ugsms.com/api/v2/sms/send', {
    method: 'POST',
    headers: {
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        numbers: '0702913454,0776913451',
        message_body: 'Hello from UGSMS API v2',
        sender_id: 'UGSMS'
    })
})
.then(response => response.json())
.then(data => console.log(data));
$apiKey = 'YOUR_API_KEY';
$data = [
    'numbers' => '0702913454,0776913451',
    'message_body' => 'Hello from UGSMS API v2',
    'sender_id' => 'UGSMS'
];

$ch = curl_init('https://ugsms.com/api/v2/sms/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'X-API-Key: ' . $apiKey
]);

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

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = "https://ugsms.com/api/v2/sms/send"
api_key = "YOUR_API_KEY"
data = {
    "numbers": "0702913454,0776913451",
    "message_body": "Hello from UGSMS API v2",
    "sender_id": "UGSMS"
}

headers = {
    "X-API-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()
print(result)
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>

struct MemoryStruct {
    char *memory;
    size_t size;
};

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;

    char *ptr = realloc(mem->memory, mem->size + realsize + 1);
    if(!ptr) {
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize;
}

int main(void) {
    CURL *curl;
    CURLcode res;

    char *api_key = "YOUR_API_KEY";
    char *url = "https://ugsms.com/api/v2/sms/send";

    struct MemoryStruct chunk;
    chunk.memory = malloc(1);
    chunk.size = 0;

    curl = curl_easy_init();
    if(curl) {
        struct curl_slist *headers = NULL;
        char auth_header[100];
        sprintf(auth_header, "X-API-Key: %s", api_key);

        headers = curl_slist_append(headers, auth_header);
        headers = curl_slist_append(headers, "Content-Type: application/json");

        char *json_data = "{\"numbers\":\"0702913454,0776913451\",\"message_body\":\"Hello from UGSMS API v2\",\"sender_id\":\"UGSMS\"}";

        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

        res = curl_easy_perform(curl);

        if(res == CURLE_OK) {
            printf("%s\n", chunk.memory);
        } else {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }

        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        free(chunk.memory);
    }

    return 0;
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var apiKey = "YOUR_API_KEY";
        var url = "https://ugsms.com/api/v2/sms/send";

        var data = new
        {
            numbers = "0702913454,0776913451",
            message_body = "Hello from UGSMS API v2",
            sender_id = "UGSMS"
        };

        var json = JsonSerializer.Serialize(data);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("X-API-Key", apiKey);

            var response = await client.PostAsync(url, content);
            var responseString = await response.Content.ReadAsStringAsync();

            Console.WriteLine(responseString);
        }
    }
}
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    apiKey := "YOUR_API_KEY"
    url := "https://ugsms.com/api/v2/sms/send"

    data := map[string]string{
        "numbers":      "0702913454,0776913451",
        "message_body": "Hello from UGSMS API v2",
        "sender_id":    "UGSMS",
    }

    jsonData, err := json.Marshal(data)
    if err != nil {
        fmt.Println("Error marshaling JSON:", err)
        return
    }

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    if err != nil {
        fmt.Println("Error creating request:", err)
        return
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", apiKey)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Error sending request:", err)
        return
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)

    fmt.Println(result)
}
import 'dart:convert';
import 'package:http/http.dart' as http;

void main() async {
  final apiKey = 'YOUR_API_KEY';
  final url = 'https://ugsms.com/api/v2/sms/send';

  final data = {
    'numbers': '0702913454,0776913451',
    'message_body': 'Hello from UGSMS API v2',
    'sender_id': 'UGSMS',
  };

  final response = await http.post(
    Uri.parse(url),
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': apiKey,
    },
    body: jsonEncode(data),
  );

  final result = jsonDecode(response.body);
  print(result);
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;

public class SendSMS {
    public static void main(String[] args) {
        String apiKey = "YOUR_API_KEY";
        String url = "https://ugsms.com/api/v2/sms/send";

        SMSData data = new SMSData();
        data.numbers = "0702913454,0776913451";
        data.message_body = "Hello from UGSMS API v2";
        data.sender_id = "UGSMS";

        Gson gson = new Gson();
        String jsonData = gson.toJson(data);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .header("X-API-Key", apiKey)
                .POST(HttpRequest.BodyPublishers.ofString(jsonData))
                .build();

        try {
            HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class SMSData {
    public String numbers;
    public String message_body;
    public String sender_id;
}
require 'net/http'
require 'json'

api_key = 'YOUR_API_KEY'
url = URI('https://ugsms.com/api/v2/sms/send')

data = {
  numbers: '0702913454,0776913451',
  message_body: 'Hello from UGSMS API v2',
  sender_id: 'UGSMS'
}

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')

request = Net::HTTP::Post.new(url)
request['Content-Type'] = 'application/json'
request['X-API-Key'] = api_key
request.body = data.to_json

response = http.request(request)
puts response.body
Example Response
{
    "success": true,
    "message": "Message sent successfully",
    "data": {
        "recipients": 2,
        "message_segments": 1,
        "estimated_cost": 20.0,
        "remaining_balance": 980.0,
        "api_version": "v2",
        "status": "pending",
        "timestamp": "2024-01-01T12:00:00Z"
    }
}
SMS Cost Calculation

SMS cost is calculated as:

Total Cost = (Number of Recipients) × (Message Segments) × (Price per Segment)

Message Segments = ceil(Message Length / 160)
Price per Segment = Your account rate (check your dashboard)

Send Bulk SMS

POST /api/v2/sms/send/bulk Batch personalized messages

Send personalized SMS messages to multiple recipients in a single request. Each message can have different content for each recipient.

Request Parameters
Parameter Type Required Description Example
messages Array Yes Array of message objects [{"number": "070...", "message_body": "..."}]
sender_id String No Sender ID (max 11 characters) UGSMS
reference String No Custom reference for tracking ORDER-123
api_key String No* API key (if not using X-API-Key header) abc123...

* API key is required but can be provided via header instead.

Message Object Format
{
    "number": "0702913454",           // Required: Recipient phone number
    "message_body": "Dear John..."    // Required: Personalized message content
}
Example Request
curl -X POST "https://ugsms.com/api/v2/sms/send/bulk" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
        {
            "number": "0702913454",
            "message_body": "Dear John, your appointment is at 2 PM today."
        },
        {
            "number": "0776913451",
            "message_body": "Dear Jane, your payment of UGX 50,000 was received."
        },
        {
            "number": "0755913452",
            "message_body": "Dear Robert, your order #12345 is ready for pickup."
        }
    ],
    "sender_id": "UGSMS",
    "reference": "NOTIFICATIONS-2024"
}'
fetch('https://ugsms.com/api/v2/sms/send/bulk', {
    method: 'POST',
    headers: {
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        messages: [
            {
                number: '0702913454',
                message_body: 'Dear John, your appointment is at 2 PM today.'
            },
            {
                number: '0776913451',
                message_body: 'Dear Jane, your payment of UGX 50,000 was received.'
            },
            {
                number: '0755913452',
                message_body: 'Dear Robert, your order #12345 is ready for pickup.'
            }
        ],
        sender_id: 'UGSMS',
        reference: 'NOTIFICATIONS-2024'
    })
})
.then(response => response.json())
.then(data => console.log(data));
$apiKey = 'YOUR_API_KEY';
$url = 'https://ugsms.com/api/v2/sms/send/bulk';

$messages = [
    [
        'number' => '0702913454',
        'message_body' => 'Dear John, your appointment is at 2 PM today.'
    ],
    [
        'number' => '0776913451',
        'message_body' => 'Dear Jane, your payment of UGX 50,000 was received.'
    ],
    [
        'number' => '0755913452',
        'message_body' => 'Dear Robert, your order #12345 is ready for pickup.'
    ]
];

$data = [
    'messages' => $messages,
    'sender_id' => 'UGSMS',
    'reference' => 'NOTIFICATIONS-2024'
];

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

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

$result = json_decode($response, true);
echo json_encode($result, JSON_PRETTY_PRINT);
import requests
import json

api_key = "YOUR_API_KEY"
url = "https://ugsms.com/api/v2/sms/send/bulk"

messages = [
    {"number": "0702913454", "message_body": "Dear John, your appointment is at 2 PM today."},
    {"number": "0776913451", "message_body": "Dear Jane, your payment of UGX 50,000 was received."},
    {"number": "0755913452", "message_body": "Dear Robert, your order #12345 is ready for pickup."}
]

data = {
    "messages": messages,
    "sender_id": "UGSMS",
    "reference": "NOTIFICATIONS-2024"
}

headers = {
    "X-API-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()
print(json.dumps(result, indent=2))
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var apiKey = "YOUR_API_KEY";
        var url = "https://ugsms.com/api/v2/sms/send/bulk";

        var data = new
        {
            messages = new[]
            {
                new { number = "0702913454", message_body = "Dear John, your appointment is at 2 PM today." },
                new { number = "0776913451", message_body = "Dear Jane, your payment of UGX 50,000 was received." },
                new { number = "0755913452", message_body = "Dear Robert, your order #12345 is ready for pickup." }
            },
            sender_id = "UGSMS",
            reference = "NOTIFICATIONS-2024"
        };

        var json = JsonSerializer.Serialize(data);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("X-API-Key", apiKey);

            var response = await client.PostAsync(url, content);
            var responseString = await response.Content.ReadAsStringAsync();

            Console.WriteLine(responseString);
        }
    }
}
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    apiKey := "YOUR_API_KEY"
    url := "https://ugsms.com/api/v2/sms/send/bulk"

    messages := []map[string]string{
        {"number": "0702913454", "message_body": "Dear John, your appointment is at 2 PM today."},
        {"number": "0776913451", "message_body": "Dear Jane, your payment of UGX 50,000 was received."},
        {"number": "0755913452", "message_body": "Dear Robert, your order #12345 is ready for pickup."},
    }

    data := map[string]interface{}{
        "messages":  messages,
        "sender_id": "UGSMS",
        "reference": "NOTIFICATIONS-2024",
    }

    jsonData, err := json.Marshal(data)
    if err != nil {
        fmt.Println("Error marshaling JSON:", err)
        return
    }

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    if err != nil {
        fmt.Println("Error creating request:", err)
        return
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", apiKey)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Error sending request:", err)
        return
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)

    fmt.Println(result)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import java.util.List;
import java.util.ArrayList;

public class SendBulkSMS {
    public static void main(String[] args) {
        String apiKey = "YOUR_API_KEY";
        String url = "https://ugsms.com/api/v2/sms/send/bulk";

        List<SMSMessage> messages = new ArrayList<>();
        messages.add(new SMSMessage("0702913454", "Dear John, your appointment is at 2 PM today."));
        messages.add(new SMSMessage("0776913451", "Dear Jane, your payment of UGX 50,000 was received."));
        messages.add(new SMSMessage("0755913452", "Dear Robert, your order #12345 is ready for pickup."));

        BulkSMSData data = new BulkSMSData();
        data.messages = messages;
        data.sender_id = "UGSMS";
        data.reference = "NOTIFICATIONS-2024";

        Gson gson = new Gson();
        String jsonData = gson.toJson(data);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .header("X-API-Key", apiKey)
                .POST(HttpRequest.BodyPublishers.ofString(jsonData))
                .build();

        try {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class BulkSMSData {
    public List<SMSMessage> messages;
    public String sender_id;
    public String reference;
}

class SMSMessage {
    public String number;
    public String message_body;

    public SMSMessage(String number, String message_body) {
        this.number = number;
        this.message_body = message_body;
    }
}
require 'net/http'
require 'json'

api_key = 'YOUR_API_KEY'
url = URI('https://ugsms.com/api/v2/sms/send/bulk')

messages = [
  { number: '0702913454', message_body: 'Dear John, your appointment is at 2 PM today.' },
  { number: '0776913451', message_body: 'Dear Jane, your payment of UGX 50,000 was received.' },
  { number: '0755913452', message_body: 'Dear Robert, your order #12345 is ready for pickup.' }
]

data = {
  messages: messages,
  sender_id: 'UGSMS',
  reference: 'NOTIFICATIONS-2024'
}

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')

request = Net::HTTP::Post.new(url)
request['Content-Type'] = 'application/json'
request['X-API-Key'] = api_key
request.body = data.to_json

response = http.request(request)
puts response.body
Example Response
{
    "success": true,
    "message": "Bulk messages processed successfully",
    "data": {
        "summary": {
            "total_messages": 3,
            "successful": 3,
            "failed": 0,
            "total_contacts": 3,
            "total_messages": 4,
            "total_cost": 140.0,
            "current_balance": 1860.0,
            "api_version": "v2",
            "timestamp": "2024-01-01T12:00:00Z"
        },
        "successful_messages": [
            {
                "index": 0,
                "number": "0702913454",
                "number_of_messages": 1,
                "cost": 35.0
            },
            {
                "index": 1,
                "number": "0776913451",
                "number_of_messages": 2,
                "cost": 70.0
            },
            {
                "index": 2,
                "number": "0755913452",
                "number_of_messages": 1,
                "cost": 35.0
            }
        ],
        "failed_messages": null
    }
}
Error Response Example
{
    "success": false,
    "message": "Bulk message processing failed",
    "data": {
        "summary": {
            "total_messages": 3,
            "successful": 2,
            "failed": 1,
            "total_contacts": 2,
            "total_messages": 3,
            "total_cost": 105.0,
            "current_balance": 895.0,
            "api_version": "v2",
            "timestamp": "2024-01-01T12:00:00Z"
        },
        "successful_messages": [
            {
                "index": 0,
                "number": "0702913454",
                "number_of_messages": 1,
                "cost": 35.0
            },
            {
                "index": 2,
                "number": "0755913452",
                "number_of_messages": 2,
                "cost": 70.0
            }
        ],
        "failed_messages": [
            {
                "index": 1,
                "number": "0776913451",
                "error": "Invalid phone number format"
            }
        ]
    }
}
Tip: Use the bulk endpoint for personalized messages. Use the regular send endpoint for broadcast messages (same message to multiple recipients).
Note: Balance is deducted when messages are actually sent (in the background job), not when the API request is made. The balance check in the response shows your current balance before deduction.

Account Endpoints

GET /api/v2/account/balance

Get current account balance and API key information.

Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
  "https://ugsms.com/api/v2/account/balance"
Example Response
{
    "success": true,
    "data": {
        "balance": 1000.50,
        "currency": "UGX",
        "api_key": "abcd1234...xyz9",
        "api_key_expires": "2024-12-31T23:59:59Z",
        "last_api_used": "2024-01-01T12:30:45Z"
    }
}
GET /api/v2/account/usage

Get API usage statistics and account information.

Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
  "https://ugsms.com/api/v2/account/usage"
Example Response
{
    "success": true,
    "data": {
        "user_id": 12345,
        "account_balance": 1860.0,
        "message_price_per_segment": 35.0,
        "api_version": "v2",
        "timestamp": "2024-01-01T12:35:20Z"
    }
}

Best Practices

Security
  • Store API keys in environment variables
  • Use HTTPS for all API requests
  • Rotate API keys periodically (every 90 days)
  • Never commit API keys to version control
  • Use different API keys for different environments
Performance
  • Use bulk endpoint for personalized messages
  • Implement retry logic with exponential backoff
  • Cache balance information when possible
  • Monitor rate limits (60 requests/minute)
  • Batch messages when possible
Messaging Tips
  • Keep messages under 160 characters to avoid extra segments
  • Include a clear sender ID for brand recognition
  • Personalize messages when using bulk endpoint
  • Test with small batches first
  • Include opt-out instructions for marketing messages
Common Issues
Issue Causes Solutions
401 Unauthorized Invalid, missing, or expired API key Generate new API key in dashboard
400 Invalid Format Wrong phone number format or missing required fields Use format: 0702913454 or +256702913454
402 Insufficient Balance Not enough balance to send SMS Top up your account in the dashboard
429 Too Many Requests Rate limit exceeded (60 requests/minute) Wait 1 minute or implement rate limiting
400 Bulk Validation Invalid messages array format in bulk endpoint Ensure messages is an array of objects with number and message_body
Partial Success Some messages in bulk request failed Check failed_messages array in response for details
Ready to start? Generate your API key from the dashboard and check out the Quick Start guide.
Advanced Bulk SMS Examples

Practical examples for common scenarios:

Bulk Notifications from Database (PHP)
// Example: Send personalized notifications from database
$apiKey = 'YOUR_API_KEY';
$url = 'https://ugsms.com/api/v2/sms/send/bulk';

// Fetch customers from database
$customers = [
    ['phone' => '0702913454', 'name' => 'John', 'appointment_time' => '2 PM'],
    ['phone' => '0776913451', 'name' => 'Jane', 'appointment_time' => '3 PM'],
    ['phone' => '0755913452', 'name' => 'Robert', 'appointment_time' => '4 PM']
];

// Prepare messages array
$messages = [];
foreach ($customers as $customer) {
    $messages[] = [
        'number' => $customer['phone'],
        'message_body' => "Dear {$customer['name']}, your appointment is at {$customer['appointment_time']} today. Please arrive 15 minutes early."
    ];
}

// Send bulk SMS
$data = ['messages' => $messages, 'sender_id' => 'CLINIC'];

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

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

if ($result['success']) {
    echo "Sent " . count($result['data']['successful_messages']) . " messages successfully!";
} else {
    echo "Some messages failed. Check failed_messages array.";
}
Payment Receipts (Python)
import requests
import json

api_key = "YOUR_API_KEY"
url = "https://ugsms.com/api/v2/sms/send/bulk"

# Simulated payment data
payments = [
    {"phone": "0702913454", "name": "John Doe", "amount": 50000, "invoice": "INV-001"},
    {"phone": "0776913451", "name": "Jane Smith", "amount": 75000, "invoice": "INV-002"},
    {"phone": "0755913452", "name": "Robert Johnson", "amount": 120000, "invoice": "INV-003"}
]

messages = []
for payment in payments:
    message = f"Dear {payment['name']}, payment of UGX {payment['amount']:,} for invoice {payment['invoice']} received. Thank you!"
    messages.append({
        "number": payment["phone"],
        "message_body": message
    })

data = {
    "messages": messages,
    "sender_id": "PAYMENTS",
    "reference": "RECEIPTS-Q1-2024"
}

headers = {
    "X-API-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()

if result.get('success'):
    print(f"✅ Successfully sent {len(result['data']['successful_messages'])} receipts")
    if result['data'].get('failed_messages'):
        print(f"⚠️ {len(result['data']['failed_messages'])} failed. Check failed_messages.")
else:
    print("❌ Request failed:", result.get('message', 'Unknown error'))