I Built Uganda's Most Affordable SMS API — Here's How to Integrate It in 5 Minutes (PHP, Python, JS)
TL;DR: Yoola SMS is a bulk SMS platform built for Uganda and East Africa. API starts at UGX 20/SMS (~$0.005). Supports MTN, Airtel, Kenya, Tanzania, UK, USA and 40+ countries. Top up with Mobile Money. Free account + 3 SMS to test. No credit card needed.
If you've ever tried to add SMS to a Ugandan app, you know the pain:
- International SMS APIs charge in USD — your Ugandan client can't pay with a VISA card
- Local options are expensive, undocumented, or both
- You spend more time fighting the integration than building your actual product
I built Yoola SMS to fix exactly that. It's a REST API that works like Twilio — but designed for Uganda, priced in UGX, and topped up with MTN Mobile Money or Airtel Money.
Here's everything you need to integrate it today.
What You Can Build With It
- 🏫 School fee reminders — send to 500 parents in 10 seconds
- 🏦 SACCO loan alerts — notify members of approvals, due dates, savings updates
- 🛒 E-commerce order confirmations — automated OTPs and delivery alerts
- 📊 Any app that needs SMS — authentication, notifications, marketing campaigns
- 🌍 Cross-border campaigns — Uganda, Kenya, Tanzania, Rwanda, UK, UAE, and 40+ more
Pricing (Real Numbers, No Surprises)
| Volume | Price per SMS |
|---|---|
| Up to 999 SMS | UGX 35/SMS |
| 1,000 – 9,999 | UGX 30/SMS |
| 10,000 – 59,999 | UGX 25/SMS |
| 60,000+ | UGX 20/SMS |
East Africa: Kenya & Tanzania = 3 credits/SMS · Rwanda = 4 credits/SMS
International: UK, USA, UAE, Australia = 8–16 credits/SMS
Top up: MTN MoMo or Airtel Money — instant, no bank needed
The API — 3 Endpoints You Actually Need
Base URL
https://yoolasms.com/api/v1/
Authentication
Every request needs your api_key. Get it from your dashboard under My API Key.
1. Send SMS
Endpoint: POST /send.php
Content-Type: application/json
Request body:
{
"phone": "0704487563",
"message": "Hello from Yoola SMS!",
"api_key": "YOUR_API_KEY",
"sender": "YoolaBiz"
}
Bulk send — just comma-separate the numbers:
{
"phone": "0704487563,0772727716,0756123456",
"message": "Your order has been confirmed. Thank you!",
"api_key": "YOUR_API_KEY"
}
Success response:
{
"status": "success",
"code": 200,
"recipients": 3,
"credits_used": 3,
"balance": 282,
"message_parts": 1
}
PHP Integration (Copy-Paste Ready)
<?php
function sendSMS($phone, $message, $apiKey, $sender = 'YoolaSMS') {
$url = 'https://yoolasms.com/api/v1/send.php';
$data = [
'phone' => $phone,
'message' => $message,
'api_key' => $apiKey,
'sender' => $sender,
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
return $response;
}
// ── Single SMS ──
$result = sendSMS('0704487563', 'Your OTP is 847291. Expires in 5 minutes.', 'YOUR_API_KEY');
echo "Status: " . $result['status'] . "\n";
echo "Credits used: " . $result['credits_used'] . "\n";
echo "Balance: " . $result['balance'] . "\n";
// ── Bulk SMS ──
$phones = implode(',', ['0704487563', '0772727716', '0756111222', '0701333444']);
$message = "Dear customer, Term 2 fees are due by 5th July. Pay to A/C 00123456. Thank you.";
$result = sendSMS($phones, $message, 'YOUR_API_KEY', 'SchoolSMS');
echo "Sent to: " . $result['recipients'] . " recipients\n";
echo "Total credits used: " . $result['credits_used'] . "\n";
Python Integration
import requests
def send_sms(phone, message, api_key, sender="YoolaSMS"):
url = "https://yoolasms.com/api/v1/send.php"
payload = {
"phone": phone,
"message": message,
"api_key": api_key,
"sender": sender,
}
response = requests.post(url, json=payload, timeout=30)
return response.json()
# Single SMS
result = send_sms("0704487563", "Your payment of UGX 50,000 was received. Thank you!", "YOUR_API_KEY")
print(f"Status: {result['status']}")
print(f"Credits used: {result['credits_used']}")
print(f"Remaining balance: {result['balance']}")
# Bulk to Uganda + Kenya in one call
phones = "0704487563,0772727716,+254712345678"
result = send_sms(phones, "Flash sale! 30% off all items today only. Visit our store.", "YOUR_API_KEY", "ShopAlert")
print(f"Sent to {result['recipients']} recipients across Uganda and Kenya")
JavaScript / Node.js Integration
const axios = require('axios');
async function sendSMS(phone, message, apiKey, sender = 'YoolaSMS') {
const response = await axios.post('https://yoolasms.com/api/v1/send.php', {
phone, message, api_key: apiKey, sender
}, {
headers: { 'Content-Type': 'application/json' },
timeout: 30000,
});
return response.data;
}
// Usage
(async () => {
// OTP / transactional
const otp = Math.floor(100000 + Math.random() * 900000);
const result = await sendSMS(
'0704487563',
`Your verification code is ${otp}. Do not share it. Expires in 5 minutes.`,
'YOUR_API_KEY',
'MyApp'
);
console.log('OTP sent:', result.status, '| Credits:', result.credits_used);
// Bulk marketing
const customers = ['0701111111', '0772222222', '0756333333'].join(',');
const bulk = await sendSMS(
customers,
'New arrivals are here! Visit yoolasms.com to shop. Reply STOP to unsubscribe.',
'YOUR_API_KEY',
'ShopAlert'
);
console.log(`Bulk sent to ${bulk.recipients} customers`);
})();
2. Check Balance
GET https://yoolasms.com/api/v1/balance.php?api_key=YOUR_KEY
{
"status": "success",
"balance": 1247,
"amount": 43645
}
3. Schedule an SMS
POST https://yoolasms.com/api/v1/schedule_sms.php
{
"phone": "0704487563,0772727716",
"message": "Reminder: SACCO meeting tomorrow at 10AM at our Kampala office.",
"api_key": "YOUR_API_KEY",
"schedule_time": "2026-07-04 09:00:00"
}
Perfect for fee reminders, appointment confirmations, or any time-sensitive campaign.
Sending to East Africa and International Numbers
Just use the international format — the API detects the country automatically:
// Uganda
sendSMS('0704487563', $message, $apiKey); // 1 credit
// Kenya (Safaricom, Airtel Kenya)
sendSMS('+254712345678', $message, $apiKey); // 3 credits
// Tanzania (Vodacom, Airtel)
sendSMS('+255756123456', $message, $apiKey); // 3 credits
// Rwanda
sendSMS('+250785123456', $message, $apiKey); // 4 credits
// UK
sendSMS('+447384014597', $message, $apiKey); // 12 credits
// UAE
sendSMS('+971557396056', $message, $apiKey); // 8 credits
Mix Uganda and international numbers in one bulk call — credits are calculated per number automatically.
Error Handling
Always check status in the response:
$result = sendSMS($phone, $message, $apiKey);
switch ($result['status']) {
case 'success':
// Deduct credits, log the send, notify user
logSMSSent($result['recipients'], $result['credits_used']);
break;
case 'insufficient_fund':
// Trigger a top-up alert to the account owner
notifyLowBalance($result['balance']);
break;
case 'invalidkey':
// API key is wrong or revoked
throw new Exception('Invalid Yoola SMS API key');
case 'missing':
// Required field missing in your request
throw new Exception('Missing phone, message, or api_key');
default:
// Network error or AT gateway issue — retry with backoff
retryAfterDelay();
}
Real World Example: School Fee Reminder System
Here's a complete mini-system that reads students from a database and sends fee reminders:
<?php
// school_fee_reminders.php — run daily via cron
$api_key = 'YOUR_YOOLA_API_KEY';
$due_date = date('j F Y', strtotime('+7 days'));
// Get students with outstanding fees
$students = $pdo->query("
SELECT s.parent_phone, s.student_name, f.amount_due
FROM students s
JOIN fees f ON s.id = f.student_id
WHERE f.paid = 0 AND f.due_date <= DATE_ADD(NOW(), INTERVAL 7 DAY)
")->fetchAll(PDO::FETCH_ASSOC);
$sent = 0;
$failed = 0;
foreach ($students as $student) {
$message = "Dear Parent, {$student['student_name']}'s fees of UGX "
. number_format($student['amount_due'])
. " are due by {$due_date}. Pay via MTN MoMo to 256704484563. "
. "Questions? Call +256 704 484 563.";
$result = sendSMS($student['parent_phone'], $message, $api_key, 'SchoolSMS');
if ($result['status'] === 'success') {
$sent++;
} else {
$failed++;
error_log("SMS failed for {$student['parent_phone']}: {$result['message']}");
}
// Small delay to avoid overwhelming the API
usleep(100000); // 0.1 second between sends
}
echo "Done. Sent: $sent | Failed: $failed\n";
Run this as a cron job every Monday morning and your school never misses a fee reminder again.
Get Started in 3 Steps
- Create a free account — takes 60 seconds, no credit card
- Top up via MTN MoMo or Airtel Money (dial the prompt on your phone)
- Copy your API key and paste it into the code above — you're live
3 free SMS are included with every new account so you can test delivery before loading credits.
What's Available in the API
| Endpoint | Description |
|---|---|
POST /send.php |
Send single or bulk SMS |
GET /balance.php |
Check credit balance |
POST /schedule_sms.php |
Schedule for future delivery |
GET /inbox.php |
Read inbound SMS |
GET /delivery_report.php |
Check delivery status |
POST /airtime-send.php |
Send airtime to any number (coming soon) |
Full docs: yoolasms.com/api-integration
Why Developers Choose Yoola SMS
✅ Pay with Mobile Money — no VISA card, no USD, no forex headaches
✅ Credits never expire — load once, use anytime
✅ Same API for Uganda + East Africa + International — one integration, 40+ countries
✅ Real-time delivery reports — know exactly who received your message
✅ Webhook support — get callbacks when messages are delivered or fail
✅ Kampala-based support — WhatsApp us on +256 704 484 563 in your timezone
Community & Support
Got questions about the integration? Post in our Community Q&A — our team responds within a few hours, and your question helps the next developer too.
Built in Uganda 🇺🇬 · Serving East Africa and beyond · yoolasms.com
Tags: #Uganda #Africa #SMS #API #PHP #Python #JavaScript #Developer #EastAfrica #MobileFirst





















