Why your app needs SMS

If you're building an app or website in Uganda, SMS is probably one of the highest-impact features you can add. Use cases:

Yoola SMS gives you a free REST API to send SMS from any programming language. Here's how to integrate it.

Step 1: Get your API key

  1. Sign up for a free Yoola SMS account at yoolasms.com/register
  2. Log in and click "My API Key" in the sidebar
  3. Copy your unique API key (looks like: a3b8c9d2e1f0...)
  4. Top up your account with at least UGX 2,500 via Mobile Money

Step 2: Understand the API

The Yoola SMS API has a single endpoint for sending SMS:

POST https://yoolasms.com/api/v1/send.php

Body (JSON):
{
  "api_key": "YOUR_API_KEY",
  "phone": "256712345678",
  "message": "Your OTP is 123456",
  "sender": "ATInfo"
}

Response (JSON):
{
  "status": "success",
  "message_id": "abc123",
  "sender_used": "ATInfo",
  "credit_remaining": 285
}

Multiple recipients

Send to multiple numbers in one request by passing a comma-separated list:

"phone": "256712345678,256772123456,256755987654"

Code samples in 5 languages

PHP

<?php
$apiKey = "YOUR_API_KEY";
$data = [
    "api_key" => $apiKey,
    "phone"   => "256712345678",
    "message" => "Hello from your app!",
    "sender"  => "ATInfo"
];

$ch = curl_init("https://yoolasms.com/api/v1/send.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>

Python

import requests

api_key = "YOUR_API_KEY"

response = requests.post(
    "https://yoolasms.com/api/v1/send.php",
    json={
        "api_key": api_key,
        "phone":   "256712345678",
        "message": "Hello from your Python app!",
        "sender":  "ATInfo"
    }
)

print(response.json())

JavaScript (Node.js)

const fetch = require('node-fetch');

const apiKey = 'YOUR_API_KEY';

async function sendSMS() {
    const response = await fetch('https://yoolasms.com/api/v1/send.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            api_key: apiKey,
            phone:   '256712345678',
            message: 'Hello from Node.js!',
            sender:  'ATInfo'
        })
    });
    const data = await response.json();
    console.log(data);
}

sendSMS();

Python Django (in a view)

import requests
from django.http import JsonResponse

def send_otp(request):
    phone = request.POST.get('phone')
    otp = generate_otp()  # your function
    
    requests.post(
        'https://yoolasms.com/api/v1/send.php',
        json={
            'api_key': settings.YOOLA_API_KEY,
            'phone':   phone,
            'message': f'Your OTP is {otp}. Valid for 5 minutes.',
            'sender':  'ATInfo'
        }
    )
    
    return JsonResponse({'sent': True})

Laravel (PHP)

use IlluminateSupportFacadesHttp;

$response = Http::post('https://yoolasms.com/api/v1/send.php', [
    'api_key' => config('services.yoola.key'),
    'phone'   => $user->phone,
    'message' => "Welcome to MyApp, {$user->name}!",
    'sender'  => 'MYAPP'
]);

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

OTP implementation example

Here's a complete OTP flow in PHP:

<?php
// 1. Generate OTP
$otp = rand(100000, 999999);

// 2. Save to database with expiry
$stmt = $pdo->prepare(
    "INSERT INTO otps (phone, otp, expires_at) VALUES (?, ?, NOW() + INTERVAL 5 MINUTE)"
);
$stmt->execute([$phone, password_hash($otp, PASSWORD_DEFAULT)]);

// 3. Send via Yoola SMS
$ch = curl_init("https://yoolasms.com/api/v1/send.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "api_key" => YOOLA_API_KEY,
    "phone"   => $phone,
    "message" => "Your verification code is {$otp}. Valid for 5 minutes. Do not share.",
    "sender"  => "MYAPPOTP"  // use a transactional sender ID for OTPs
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

if($result['status'] === 'success'){
    echo "OTP sent. Check your phone.";
}
?>

Best practices for production

1. Use environment variables for your API key

Never hardcode your API key in source files committed to Git. Use .env files:

YOOLA_API_KEY=a3b8c9d2e1f0...

2. Implement retry logic

If a send fails due to network issues, retry once with exponential backoff:

for ($attempt = 1; $attempt <= 3; $attempt++) {
    $result = sendSMS($phone, $message);
    if ($result['status'] === 'success') break;
    sleep($attempt * 2);  // 2s, 4s, 6s between retries
}

3. Validate phone numbers before sending

Save SMS credits by rejecting invalid numbers before the API call:

function isValidUgandaNumber($phone) {
    $phone = preg_replace('/[^0-9]/', '', $phone);
    return preg_match('/^(256|0)(7|3)[0-9]{8}$/', $phone);
}

4. Log every SMS sent

Maintain your own log table for audit, debugging, and disputes:

CREATE TABLE sms_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    phone VARCHAR(20),
    message TEXT,
    status VARCHAR(20),
    response JSON,
    sent_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

5. Handle credit-low scenarios

Yoola SMS returns your remaining credit balance on every send. Alert your admin when it gets low:

if ($result['credit_remaining'] < 100) {
    // email admin to top up
    mail($adminEmail, 'SMS credits low', 'Only ' . $result['credit_remaining'] . ' credits left.');
}

Common API integration questions

What's the rate limit?

For regular accounts: 100 SMS/second. For high-volume reseller accounts: custom limits. If you exceed the rate, requests queue automatically.

How do I send to multiple countries?

Just include the destination country code in the phone number: 254... for Kenya, 255... for Tanzania, 250... for Rwanda. Rates vary by country — see Coverage page.

How do I get delivery status?

The API returns the initial send status. For final delivery status, poll the message_id endpoint or set up a webhook URL in your dashboard.

Is there a sandbox environment?

The free 3 SMS on signup is your sandbox — test there. Or use a "test" sender that won't charge but logs the request.

Ready to integrate?

Get your free API key in 60 seconds. Yoola SMS API is free to use — you only pay for the SMS sent through it.

Get your free API key →

Or read the full API documentation