Contents

1. Introduction to Airtime API

2. Request Parameters

3. Response Parameters

4. Send Airtime

5. Receive airtime Callback Notification

This allows you to send airtime to one or more recipients at a go. Sozuri Airtime API responds with a unique identifier for each airtime transaction request named "requestId". You can use this to correlate when you receive a status callback. The Sozuri Airtime API platform then asynchronously targets your project's airtime callback URL with status updates.

Airtime limitations:-

You can only send to a maximum of 1000 recipients at a go.

Min amount is 10KES and the maximum per recipient is 5000.

The base URL for all Airtime API call strings is: https://sozuri.net/api/v1/airtime/topup

Send Airtime: Request headers

POST /api/v1/airtime/topup  HTTP/1.1
Host: sozuri.net
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer Your_Project_API_KEY

Request parameters to the Sozuri Airtime API

Parameter Name Mandatory Type Description
project Yes String The name of the project that owns the apiKey making this request.
recipients Yes String A url encoded json list of Recipients, the format of this string is: [{"number":"+254711XXXYYY","amount":"KES 200"}] recipients is a Map with the following parameters:


    number(String) : This is the recipient’s phone number
    amount(String) : Value of airtime in KES. The value of airtime to send together with the currency code. The format of this string is: (3-digit Currency Code)(space)(Decimal Value) e.g KES 100.50<
apiKey - String The Project API Key. NB: Instead of having the apiKey in the body, it can alternatively be added as the Value of an Authorization header Bearer token instead. See its use in the Request header HERE

Response FROM Sozuri OmniChannel API (synchronous)

The body of the response will be a JSON object containing the following fields:
Parameter Name Type Description
recipientsCount String The number of airtime top up requests made to the carrier
totalAmount String Total Airtime value formatted as (3 digit currency code)(space)(Decimal value) eg. KES 200
totalDiscount String Total Airtime value formatted as (3 digit currency code)(space)(Decimal value) eg. KES 200
responses String A list with multiple Entries each matching a single airtime transaction result. Each entry has the following parameters:
    number(String) : This is the recipient’s phone number
    amount(String) : Value of airtime in KES. The value of airtime to send together with the currency code. The format of this string is: (3-digit Currency Code)(space)(Decimal Value) e.g KES 100.50<
    discount(String) :Total discount value for sending to this number formatted as (3 digit currency code)(space)(Decimal value) eg. KES 200.00
    status(String) : escription of the status of the airtime transaction. It is either "accepted" or "failed". This is not indicative of the delivery status of the message.
    requestId(String) : A unique id for the request associated to this phone number. This can be correlated with requestId in airtime delivery status callback sent to your webhook if you have set one.
    errorMessage(String) : The error message for the request associated to this phone number or "none" if no error was encountered.
Send Airtime

POST Request


POST /api/v1/airtime/topup HTTP/1.1
Host: sozuri.net
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 246

project=Law&recipients=%5B%7B%22number%22%3A%22%2B254725164293%22%2C%22amount%22%3A%22KES%2010%22%7D%2C%7B%22number%22%3A%220725164293%22%2C%22amount%22%3A%22KES%2011%22%7D%5D%20&apiKey=YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://sozuri.net/api/v1/airtime/topup',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => 'project=Law&recipients=%5B%7B%22number%22%3A%22%2B254725164293%22%2C%22amount%22%3A%22KES%2010%22%7D%2C%7B%22number%22%3A%220725164293%22%2C%22amount%22%3A%22KES%2011%22%7D%5D%20&apiKey=YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Content-Type: application/x-www-form-urlencoded'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;



//Javascript - Fetch                                                            
var myHeaders = new Headers();
myHeaders.append("Accept", "application/json");
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("project", "Law");
urlencoded.append("recipients", "[{\"number\":\"+254725164293\",\"amount\":\"KES 10\"},{\"number\":\"0725164293\",\"amount\":\"KES 11\"}] ");
urlencoded.append("apiKey", "YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: urlencoded,
  redirect: 'follow'
};

fetch("https://sozuri.net/api/v1/airtime/topup", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));


require "uri"
require "net/http"

url = URI("https://sozuri.net/api/v1/airtime/topup")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Content-Type"] = "application/x-www-form-urlencoded"
request.body = "project=Law&recipients=%5B%7B%22number%22%3A%22%2B254725164293%22%2C%22amount%22%3A%22KES%2010%22%7D%2C%7B%22number%22%3A%220725164293%22%2C%22amount%22%3A%22KES%2011%22%7D%5D%20&apiKey=YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE"

response = http.request(request)
puts response.read_body


import http.client
conn = http.client.HTTPSConnection("sozuri.net")
payload = 'project=Law&recipients=%5B%7B%22number%22%3A%22%2B254725164293%22%2C%22amount%22%3A%22KES%2010%22%7D%2C%7B%22number%22%3A%220725164293%22%2C%22amount%22%3A%22KES%2011%22%7D%5D%20&apiKey=YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE'
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/x-www-form-urlencoded'
}
conn.request("POST", "/api/v1/airtime/topup", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))


Unirest.setTimeouts(0, 0);
HttpResponse response = Unirest.post("https://sozuri.net/api/v1/airtime/topup")
  .header("Accept", "application/json")
  .header("Content-Type", "application/x-www-form-urlencoded")
  .field("project", "Law")
  .field("recipients", "[{\"number\":\"+254725164293\",\"amount\":\"KES 10\"},{\"number\":\"0725164293\",\"amount\":\"KES 11\"}] ")
  .field("apiKey", "YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE")
  .asString();


var client = new RestClient("https://sozuri.net/api/v1/airtime/topup");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("project", "Law");
request.AddParameter("recipients", "[{\"number\":\"+254725164293\",\"amount\":\"KES 10\"},{\"number\":\"0725164293\",\"amount\":\"KES 11\"}] ");
request.AddParameter("apiKey", "YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);


curl --location --request POST 'https://sozuri.net/api/v1/airtime/topup' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'project=Law' \
--data-urlencode 'recipients=[{"number":"+254725164293","amount":"KES 10"},{"number":"0725164293","amount":"KES 11"}] ' \
--data-urlencode 'apiKey=YI1uKEDbI6SOtzPX4W4VHICRP2oCuL1BmCJmTeKQrEKEYy5NuNI30l7L86LE'

Syncronous JSON Response



{
    "recipientsCount": 2,
    "totalAmount": 21,
    "totalDiscount": "KES 0.00",
    "responses": [
        {
            "number": "254725164293",
            "amount": "KES 10",
            "discount": "KES 0.00",
            "status": "accepted",
            "requestId": 4971724,
            "errorMessage": "none"
        },
        {
            "number": "254725164293",
            "amount": "KES 11",
            "discount": "KES 0.00",
            "status": "accepted",
            "requestId": 5015342,
            "errorMessage": "none"
        }
    ]
}
See an example Airtime Request from the Postman Collection:

Receive Airtime status callback to your webhook

To set up a webhook for Airtime status updates, Login to your Sozuri account. Open your project and go the the Manage API > Callbacks URL's menu. Set up a default Callback URL for Airtime status updates.

Sozuri will asynchronously send a callback to your application with the details of airtime transaction when the status changes at the provider provider .

Note that the sequence in which airtime transaction status callbacks are received is not guaranteed to be the original sequence in which these airtime transactions were initiated. The callback will have a timestamp generated upon receiving them in the Sozuri API. The exact implementation of this timestamp could vary from channel to channel.

Below is a standard callback sample when the airtime status has been received from the provider by Sozuri:

Receive Airtime Callback to your webhook.

{
    "number":"254725164293",
    "amount": "KES 1000.00",
    "requestId":"5015342",
    "discount": "KES 0.00",
    "status": "success",
    "type": "airtimeDelivery",
    "description": "success",
    "timestamp": "1603713484"
}