Top-up API Documentation

Want to use the Top-up API?It is switched on for approved accounts. Send a short request and we reply within 1 to 2 working days.
Request access

Overview

The Top-up API lets your own app, website or system add credits to your Yoola SMS account without logging in to Yoola SMS. Your system asks us to start a Mobile Money payment on a phone, the person approves it with their PIN, and the credits are added to your account automatically.

1. Your servercalls POST /topup with the amount and the paying phone.
2. The phonegets an MTN or Airtel prompt and the person approves it.
3. Yoola SMSconfirms the payment with the mobile money network and adds the credits.
4. Your servercalls GET /topup-status and sees successful.

Base URL: https://yoolasms.com/api/v1. Works for Uganda (UGX) accounts with MTN and Airtel Mobile Money.

Getting access

The Top-up API is switched on for approved accounts only. Send a request with your account email and a few details about your business. We review it and email you the decision, usually within 1 to 2 working days. Until it is switched on, the API replies topup_api_not_enabled.

Your API key is the same key you already use to send SMS. Find it on the API page of your account.

Safety rules

  • Call the API from your server only. Never put your api_key inside a mobile app, a web page or any JavaScript that people can open.
  • Always send a client_ref, your own unique reference for the payment (for example your invoice number). If your system retries, the same client_ref never sends a second prompt.
  • Do not act until the status is successful. A prompt being sent does not mean the person paid.
  • The payer pays the amount plus 0.5% (the mobile money fee). amount is what is added to your balance. Sending 50,000 charges the phone 50,252.

Start a payment: POST /topup

https://yoolasms.com/api/v1/topup — send JSON (Content-Type: application/json) or normal form fields.

FieldRequiredDescription
api_keyYesYour Yoola SMS API key.
amountYesWhole UGX to add to your balance. Minimum 2,500. Maximum 2,000,000 per payment unless we set a different limit for you.
phoneYesMTN or Airtel number that will pay, for example 0771234567. The forms +256771234567 and 256771234567 also work.
client_refRecommendedYour reference, up to 40 characters: letters, numbers and - _ .
curl -X POST https://yoolasms.com/api/v1/topup \
  -H "Content-Type: application/json" \
  -d '{"api_key":"YOUR_KEY","amount":50000,"phone":"0771234567","client_ref":"INV-1001"}'

Success (HTTP 200):

{
  "status": "success",
  "message": "Payment prompt sent to 0771***567. Approve it on the phone to receive the credits. Check /topup-status for the result.",
  "ref": "YOOLA-1762345678-4821",
  "payment_status": "pending",
  "amount": 50000,
  "currency": "UGX",
  "charge_amount": 50252,
  "fee": 252,
  "client_ref": "INV-1001",
  "created_at": "2026-11-05T09:30:12+00:00",
  "code": 200
}

Keep ref (ours) and your client_ref. Either one works with /topup-status. If you send a client_ref you already used, nothing new is sent: you get the original payment back with "duplicate": true.

HTTP 202 unconfirmed: we could not confirm the prompt was sent. Do not send it again. Check /topup-status after a minute: if the person received and approved a prompt, it still credits.

Check a payment: GET or POST /topup-status

https://yoolasms.com/api/v1/topup-status — send your api_key and one of ref or client_ref.

curl "https://yoolasms.com/api/v1/topup-status?api_key=YOUR_KEY&client_ref=INV-1001"
{
  "status": "success",
  "message": "OK",
  "ref": "YOOLA-1762345678-4821",
  "payment_status": "successful",
  "amount": 50000,
  "currency": "UGX",
  "client_ref": "INV-1001",
  "created_at": "2026-11-05T09:30:12+00:00",
  "credits_balance": 2778,
  "money_balance": 50000,
  "code": 200
}
payment_statusMeaning
pendingWaiting for the person to approve on their phone.
successfulPaid, and the credits are added.
failedDeclined, cancelled, or not enough money. Start a new payment with a new client_ref.
expiredNobody approved within 30 minutes. If it is approved later it still credits and changes to successful.

With no ref or client_ref you get your most recent API top-ups (default 10; add limit=1 to 20). created_at is in UTC.

How often to check: every 5 to 10 seconds for about 2 minutes after you start the payment, then every few minutes, with a final check at 30 minutes. Do not check faster.

Error codes

Every reply has status, message and code. Read the status word in your code, and show the message to a person if you need to.

HTTPstatusWhat to do
200successDone. If "duplicate": true, this client_ref was used before.
202unconfirmedDo not resend. Check /topup-status after a minute.
400missingapi_key is missing.
403invalidkeyWrong API key.
403not_activeThe account is not active. Contact support.
403topup_api_not_enabledThe Top-up API is not switched on for your account. Request access.
403not_availableOnly Uganda (UGX) accounts can use it.
404not_foundNo top-up with that reference on your account.
405method_not_allowedUse POST for /topup.
409duplicate_in_progressThat client_ref is being processed right now. Wait a few seconds and check /topup-status.
422invalid_amount, amount_too_low, amount_too_high, invalid_phone, invalid_client_refFix the input. min or max is returned where it applies.
429rate_limit, too_many_pending, phone_busyToo many requests, too many unanswered prompts, or that phone was just prompted. Wait, then try again.
500errorWe could not record the payment, so nothing was sent. Safe to retry.
502provider_errorThe mobile money network refused the prompt (for example a wrong number). Safe to retry with the same client_ref.
503not_configuredNot ready. Contact support.

Limits

These protect your account and ours.

LimitValue
Amount per paymentUGX 2,500 to 2,000,000 (your own maximum may differ)
Calls to /topup10 per minute
Payment prompts started6 per hour and 20 per day
Prompts waiting for approval at once2
Same phone prompted againafter 2 minutes
Calls to /topup-status30 per minute

Need to add a very large amount? Ask us for a bank transfer instead. It avoids mobile money limits and fees.

Code examples

PHP

$ch = curl_init('https://yoolasms.com/api/v1/topup');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'api_key'    => getenv('YOOLA_KEY'),
        'amount'     => 50000,
        'phone'      => '0771234567',
        'client_ref' => 'INV-1001',
    ]),
]);
$res = json_decode(curl_exec($ch), true);
if (($res['status'] ?? '') === 'success') {
    // save $res['ref'], then poll /topup-status until payment_status is successful
}

Node.js (18 or newer)

const r = await fetch('https://yoolasms.com/api/v1/topup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    api_key: process.env.YOOLA_KEY,
    amount: 50000,
    phone: '0771234567',
    client_ref: 'INV-1001',
  }),
});
const data = await r.json();
if (data.status === 'success') { /* poll /topup-status */ }

Python

import os, requests

r = requests.post('https://yoolasms.com/api/v1/topup', json={
    'api_key': os.environ['YOOLA_KEY'],
    'amount': 50000,
    'phone': '0771234567',
    'client_ref': 'INV-1001',
})
print(r.json())

Waiting for the result (Node.js)

async function waitForPayment(clientRef) {
  for (let i = 0; i < 20; i++) {                    // about 2 minutes
    await new Promise(ok => setTimeout(ok, 6000));
    const u = `https://yoolasms.com/api/v1/topup-status?api_key=${process.env.YOOLA_KEY}&client_ref=${clientRef}`;
    const d = await (await fetch(u)).json();
    if (d.payment_status === 'successful') return true;
    if (d.payment_status === 'failed')     return false;
  }
  return null;   // still pending: check again later
}

FAQ

How fast are the credits added?

Within seconds of the person approving the prompt, once the mobile money network confirms it.

The person says they paid but my status is still pending.

Wait a minute and check again. If it is still pending after a few minutes, email support@yoolasms.com with the ref and we will check it with the mobile money network.

Can I use my own phone number or my customers' numbers?

Any MTN or Airtel Mobile Money number can pay into your account. Make sure the person agrees to the amount before you send the prompt.

Does it work for other countries?

Not yet. It is for Uganda (UGX) accounts.

Can I add UGX 15,000,000 at once?

Mobile money has per-payment and daily limits and a 0.5% fee. For very large amounts, ask us for a bank transfer instead.

I need help.

Write to support@yoolasms.com or call +256 704 487 563. Don't have access yet? Request it here.

Ready to top up automatically?Tell us about your business and we will review your request.
Request access