Send SMS to Uganda, Kenya, Tanzania, Rwanda and 40+ Countries From One API — Here's the Code
Most SMS APIs treat Africa as one bucket with one high price. The reality is very different — Kenya's networks have completely different termination costs than Uganda, and Tanzania is different again. Getting this wrong means either overcharging your clients or losing money on every send.
Here is how to do it right with one API that handles all of it automatically.
The Problem With Generic SMS APIs in East Africa
If you use a global SMS provider for Uganda/East Africa:
- They quote you in USD
- They charge the same rate whether you send to MTN Uganda or Safaricom Kenya — usually high
- You cannot pay with Mobile Money
- Support is in a different timezone and has never heard of MTN MoMo
Yoola SMS was built specifically for this region. One account. One top-up via Mobile Money. Automatic per-network credit calculation. Send to Uganda, Kenya, Tanzania, Rwanda, South Sudan, Ethiopia, DR Congo, and 40+ countries internationally.
Supported Countries and Credit Rates
Uganda (All Networks)
MTN Uganda (074x, 075x, 076x, 077x, 078x) → 1 credit/SMS
Airtel Uganda (070x, 072x, 073x, 079x) → 1 credit/SMS
UTL / LycaMobile (0710–0719) → 2 credits/SMS
Hamilton Telecom (0798–0799) → 2 credits/SMS
East Africa
Kenya (+254) — Safaricom, Airtel Kenya, Telkom → 3 credits/SMS
Tanzania (+255) — Vodacom, Airtel, Tigo, Halotel → 3 credits/SMS
Rwanda (+250) — MTN Rwanda, Airtel Rwanda → 4 credits/SMS
South Sudan (+211) — MTN, Zain → 4 credits/SMS
Ethiopia (+251) — Ethio Telecom, Safaricom → 4 credits/SMS
DR Congo (+243) — Vodacom DRC, Airtel, Orange → 5 credits/SMS
International
UAE (+971) → 8 credits/SMS
USA/Canada (+1) → 10 credits/SMS
UK (+44) → 12 credits/SMS
Germany (+49) → 15 credits/SMS
Australia (+61) → 16 credits/SMS
At the Basic rate of UGX 35/credit.
The Code — Works for All Countries
The API is identical regardless of destination country. Just pass the number in international format and credits are calculated automatically.
PHP
<?php
function sendSMS(string $phone, string $message, string $apiKey, string $sender = 'YoolaSMS'): array {
$ch = curl_init('https://yoolasms.com/api/v1/send.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(compact('phone', 'message', 'sender') + ['api_key' => $apiKey]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return $res;
}
$key = 'YOUR_API_KEY';
// Uganda
sendSMS('0704487563', 'Your package has been dispatched.', $key, 'ShopUG');
// Kenya
sendSMS('+254712345678', 'Your package has been dispatched.', $key, 'ShopKE');
// Tanzania
sendSMS('+255756123456', 'Your package has been dispatched.', $key, 'ShopTZ');
// Mix all in one bulk call — auto-calculates credits per country
$allNumbers = '0704487563,+254712345678,+255756123456,+250785432100';
$r = sendSMS($allNumbers, 'Regional campaign: 20% off all products this weekend!', $key, 'RegionalSMS');
echo "Sent to: {$r['recipients']} recipients across Uganda, Kenya, Tanzania, Rwanda\n";
echo "Credits used: {$r['credits_used']}\n";
echo "Balance remaining: {$r['balance']}\n";
Python
import requests
def send_regional_sms(numbers: list[str], message: str, api_key: str, sender: str = "YoolaSMS") -> dict:
"""Send SMS to Uganda, East Africa, or International numbers."""
return requests.post(
"https://yoolasms.com/api/v1/send.php",
json={
"phone": ",".join(numbers),
"message": message,
"api_key": api_key,
"sender": sender,
},
timeout=30,
).json()
api_key = "YOUR_API_KEY"
# Regional NGO notification — Uganda + Kenya + Rwanda
recipients = [
"0704487563", # Uganda MTN
"0772727716", # Uganda MTN
"+254712345678", # Kenya Safaricom
"+254733803035", # Kenya Airtel
"+250785123456", # Rwanda MTN
]
result = send_regional_sms(
recipients,
"Community health clinic: Free malaria testing this Saturday 8AM-2PM at all district offices.",
api_key,
"HealthAlert"
)
print(f"Delivered to {result['recipients']} recipients")
print(f"Covered: Uganda + Kenya + Rwanda in one send")
print(f"Credits used: {result['credits_used']}")
Node.js
const sendRegional = async (numbers, message, apiKey, sender = 'YoolaSMS') => {
const res = await fetch('https://yoolasms.com/api/v1/send.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
phone: Array.isArray(numbers) ? numbers.join(',') : numbers,
message, sender,
api_key: apiKey,
}),
});
return res.json();
};
const apiKey = 'YOUR_API_KEY';
// E-commerce: notify buyers across East Africa
const orders = [
{ phone: '0704487563', name: 'James', country: 'Uganda' },
{ phone: '+254712345678', name: 'Mary', country: 'Kenya' },
{ phone: '+255756123456', name: 'Patrick', country: 'Tanzania' },
];
// Send personalised messages individually
for (const order of orders) {
const result = await sendRegional(
order.phone,
`Hi ${order.name}, your order from ${order.country} has been confirmed. Delivery in 3-5 days.`,
apiKey,
'EastAfricaShop'
);
console.log(`${order.country}: ${result.status} | ${result.credits_used} credit(s) used`);
}
Real Use Case: NGO Regional Campaign Manager
<?php
// ngos often need to reach communities across multiple East African countries
// This class handles it cleanly
class YoolaSMSRegional {
private string $apiKey;
private string $baseUrl = 'https://yoolasms.com/api/v1/';
public function __construct(string $apiKey) {
$this->apiKey = $apiKey;
}
public function send(array|string $phones, string $message, string $sender = 'NGOAlert'): array {
$phone = is_array($phones) ? implode(',', $phones) : $phones;
$ch = curl_init($this->baseUrl . 'send.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['phone'=>$phone,'message'=>$message,'api_key'=>$this->apiKey,'sender'=>$sender]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$r = json_decode(curl_exec($ch), true);
curl_close($ch);
return $r;
}
public function balance(): int {
$r = json_decode(file_get_contents($this->baseUrl . 'balance.php?api_key=' . $this->apiKey), true);
return (int)($r['balance'] ?? 0);
}
public function schedule(array|string $phones, string $message, string $datetime, string $sender = 'NGOAlert'): array {
$phone = is_array($phones) ? implode(',', $phones) : $phones;
$ch = curl_init($this->baseUrl . 'schedule_sms.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['phone'=>$phone,'message'=>$message,'api_key'=>$this->apiKey,'sender'=>$sender,'schedule_time'=>$datetime]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$r = json_decode(curl_exec($ch), true);
curl_close($ch);
return $r;
}
}
// Usage
$sms = new YoolaSMSRegional('YOUR_API_KEY');
echo "Credits available: " . $sms->balance() . "\n";
// Immediate send across East Africa
$result = $sms->send(
['0704487563', '+254712345678', '+255756123456', '+250785123456', '+211912345678'],
'Community meeting: Monday 7th July, 2PM. Venue: District Hall. All members required.',
'NGOAlert'
);
echo "Sent to {$result['recipients']} people across 5 countries\n";
// Schedule a reminder for the morning of the event
$sms->schedule(
['0704487563', '+254712345678', '+255756123456'],
'REMINDER: Community meeting TODAY at 2PM. District Hall. Do not miss.',
'2026-07-07 08:00:00'
);
echo "Morning reminder scheduled.\n";
Coverage Map
✅ Uganda — all networks
✅ Kenya · Tanzania · Rwanda · South Sudan · Ethiopia · DR Congo
✅ Nigeria · Ghana · South Africa · Malawi · Zambia + 20 more African countries
✅ UK · USA · UAE · Australia · Germany · France · India · China + 20 more
Full list at yoolasms.com/coverage
Get Started
🔗 Free account — 3 SMS included
💳 Top up with: MTN MoMo · Airtel Money · Visa/Mastercard (via Flutterwave) — all in UGX
📖 API docs
🌍 Coverage & credit rates
💬 Community Q&A
Built in Uganda 🇺🇬 for East Africa and the world.
Building something that spans multiple African countries? Share it in the comments — genuinely curious what people are working on.
Top comments (0)