curl --request POST \
--url https://api.nomba.com/v2/bill/topup \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'accountId: <accountid>' \
--data '
{
"amount": 200,
"phoneNumber": "08055441122",
"network": "GLO",
"merchantTxRef": "3bvwhibh38220dsjakTwvb",
"senderName": "John Doe"
}
'import requests
url = "https://api.nomba.com/v2/bill/topup"
payload = {
"amount": 200,
"phoneNumber": "08055441122",
"network": "GLO",
"merchantTxRef": "3bvwhibh38220dsjakTwvb",
"senderName": "John Doe"
}
headers = {
"accountId": "<accountid>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
accountId: '<accountid>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 200,
phoneNumber: '08055441122',
network: 'GLO',
merchantTxRef: '3bvwhibh38220dsjakTwvb',
senderName: 'John Doe'
})
};
fetch('https://api.nomba.com/v2/bill/topup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nomba.com/v2/bill/topup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 200,
'phoneNumber' => '08055441122',
'network' => 'GLO',
'merchantTxRef' => '3bvwhibh38220dsjakTwvb',
'senderName' => 'John Doe'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"accountId: <accountid>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nomba.com/v2/bill/topup"
payload := strings.NewReader("{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("accountId", "<accountid>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nomba.com/v2/bill/topup")
.header("accountId", "<accountid>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nomba.com/v2/bill/topup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accountId"] = '<accountid>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}"
response = http.request(request)
puts response.read_body{
"code": "200",
"description": "SUCCESS",
"message": "Transaction completed Successfully",
"status": true,
"data": {
"id": "API-TOPUP-A6950-8c060b7c-4155-4e33-a846-101b49229c33",
"status": "SUCCESS",
"type": "topup",
"amount": 100,
"source": "api",
"sourceUserId": null,
"customerBillerId": "08123456788",
"productId": "62130",
"meta": {
"api_rrn": "260926204701",
"rrn": "260926204701",
"api_account_id": "0167288-d989-460a-bbde-9842f2b4320f",
"api_client_id": "2167288-d989-460a-bbde-9842f2b4320f",
"user_id": "0167288-d989-460a-bbde-9842f2b4320f",
"merchantTxRef": "REF-29-07-2026-12",
"allowDuplicate": true,
"sender_name": "John Doe",
"idempotentKey": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"pos_withdrawal_id": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"userName": "John Doe",
"isCorporate": "true",
"currency": "NGN",
"hooksEligible": "true",
"isSubscribedToSavingsService": false,
"isSubscribedToLoanService": false,
"txnAlertEligible": true,
"banking_entity_id": 189585760,
"banking_entity_user_id": 188595905,
"banking_entity_type": "CORPORATE",
"transactionCategory": "Bills & Utility",
"network": "mtn",
"subscriberNumber": "08123456788",
"amount_charged": "100.0",
"wallet_balance": "610.55",
"wallet_currency": "NGN",
"agent_commission": "2.0",
"gatewayMessage": "Success",
"billingServiceTransactionId": "6ab821352669ea6eac2bb2ba",
"billingServiceResponse": "SUCCESS",
"income": "0.5",
"paymentFee": 0,
"tx_revenue": "2.5",
"phoneNumber": "08123456788"
},
"userId": null,
"timeCreated": "2026-09-26T19:47:01.514+00:00"
}
}{
"code": "201",
"description": "PROCESSING",
"message": "Success",
"status": true,
"data": {
"id": "API-TOPUP-A6950-8c060b7c-4155-4e33-a846-101b49229c33",
"status": "PROCESSING",
"type": "topup",
"amount": 100,
"source": "api",
"sourceUserId": null,
"customerBillerId": "08123456788",
"productId": "62130",
"meta": {
"api_rrn": "260926204701",
"rrn": "260926204701",
"api_account_id": "0167288-d989-460a-bbde-9842f2b4320f",
"api_client_id": "2167288-d989-460a-bbde-9842f2b4320f",
"user_id": "0167288-d989-460a-bbde-9842f2b4320f",
"merchantTxRef": "REF-29-07-2026-12",
"allowDuplicate": true,
"sender_name": "John Doe",
"idempotentKey": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"pos_withdrawal_id": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"userName": "John Doe",
"isCorporate": "true",
"currency": "NGN",
"hooksEligible": "true",
"isSubscribedToSavingsService": false,
"isSubscribedToLoanService": false,
"txnAlertEligible": true,
"banking_entity_id": 189585760,
"banking_entity_user_id": 188595905,
"banking_entity_type": "CORPORATE",
"transactionCategory": "Bills & Utility",
"network": "mtn",
"subscriberNumber": "08123456788",
"amount_charged": "100.0",
"wallet_balance": "610.55",
"wallet_currency": "NGN",
"phoneNumber": "08123456788"
},
"userId": null,
"timeCreated": "2026-09-26T19:47:01.514+00:00"
}
}{
"code": "400",
"description": "Request failed."
}{
"code": "401",
"description": "Unauthorized"
}{
"code": "403",
"description": "Forbidden"
}{
"code": "404",
"description": "Record not found"
}{
"code": "429",
"description": "Too many requests"
}{
"code": "500",
"description": "Server error"
}{
"code": "400",
"description": "Request failed."
}Make airtime purchases via parent account (v2)
You can use this endpoint to make airtime purchases via parent account.
curl --request POST \
--url https://api.nomba.com/v2/bill/topup \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'accountId: <accountid>' \
--data '
{
"amount": 200,
"phoneNumber": "08055441122",
"network": "GLO",
"merchantTxRef": "3bvwhibh38220dsjakTwvb",
"senderName": "John Doe"
}
'import requests
url = "https://api.nomba.com/v2/bill/topup"
payload = {
"amount": 200,
"phoneNumber": "08055441122",
"network": "GLO",
"merchantTxRef": "3bvwhibh38220dsjakTwvb",
"senderName": "John Doe"
}
headers = {
"accountId": "<accountid>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
accountId: '<accountid>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 200,
phoneNumber: '08055441122',
network: 'GLO',
merchantTxRef: '3bvwhibh38220dsjakTwvb',
senderName: 'John Doe'
})
};
fetch('https://api.nomba.com/v2/bill/topup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nomba.com/v2/bill/topup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 200,
'phoneNumber' => '08055441122',
'network' => 'GLO',
'merchantTxRef' => '3bvwhibh38220dsjakTwvb',
'senderName' => 'John Doe'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"accountId: <accountid>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nomba.com/v2/bill/topup"
payload := strings.NewReader("{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("accountId", "<accountid>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nomba.com/v2/bill/topup")
.header("accountId", "<accountid>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nomba.com/v2/bill/topup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accountId"] = '<accountid>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 200,\n \"phoneNumber\": \"08055441122\",\n \"network\": \"GLO\",\n \"merchantTxRef\": \"3bvwhibh38220dsjakTwvb\",\n \"senderName\": \"John Doe\"\n}"
response = http.request(request)
puts response.read_body{
"code": "200",
"description": "SUCCESS",
"message": "Transaction completed Successfully",
"status": true,
"data": {
"id": "API-TOPUP-A6950-8c060b7c-4155-4e33-a846-101b49229c33",
"status": "SUCCESS",
"type": "topup",
"amount": 100,
"source": "api",
"sourceUserId": null,
"customerBillerId": "08123456788",
"productId": "62130",
"meta": {
"api_rrn": "260926204701",
"rrn": "260926204701",
"api_account_id": "0167288-d989-460a-bbde-9842f2b4320f",
"api_client_id": "2167288-d989-460a-bbde-9842f2b4320f",
"user_id": "0167288-d989-460a-bbde-9842f2b4320f",
"merchantTxRef": "REF-29-07-2026-12",
"allowDuplicate": true,
"sender_name": "John Doe",
"idempotentKey": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"pos_withdrawal_id": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"userName": "John Doe",
"isCorporate": "true",
"currency": "NGN",
"hooksEligible": "true",
"isSubscribedToSavingsService": false,
"isSubscribedToLoanService": false,
"txnAlertEligible": true,
"banking_entity_id": 189585760,
"banking_entity_user_id": 188595905,
"banking_entity_type": "CORPORATE",
"transactionCategory": "Bills & Utility",
"network": "mtn",
"subscriberNumber": "08123456788",
"amount_charged": "100.0",
"wallet_balance": "610.55",
"wallet_currency": "NGN",
"agent_commission": "2.0",
"gatewayMessage": "Success",
"billingServiceTransactionId": "6ab821352669ea6eac2bb2ba",
"billingServiceResponse": "SUCCESS",
"income": "0.5",
"paymentFee": 0,
"tx_revenue": "2.5",
"phoneNumber": "08123456788"
},
"userId": null,
"timeCreated": "2026-09-26T19:47:01.514+00:00"
}
}{
"code": "201",
"description": "PROCESSING",
"message": "Success",
"status": true,
"data": {
"id": "API-TOPUP-A6950-8c060b7c-4155-4e33-a846-101b49229c33",
"status": "PROCESSING",
"type": "topup",
"amount": 100,
"source": "api",
"sourceUserId": null,
"customerBillerId": "08123456788",
"productId": "62130",
"meta": {
"api_rrn": "260926204701",
"rrn": "260926204701",
"api_account_id": "0167288-d989-460a-bbde-9842f2b4320f",
"api_client_id": "2167288-d989-460a-bbde-9842f2b4320f",
"user_id": "0167288-d989-460a-bbde-9842f2b4320f",
"merchantTxRef": "REF-29-07-2026-12",
"allowDuplicate": true,
"sender_name": "John Doe",
"idempotentKey": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"pos_withdrawal_id": "0167288-d989-460a-bbde-9842f2b4320f_REF-29-07-2026-12",
"userName": "John Doe",
"isCorporate": "true",
"currency": "NGN",
"hooksEligible": "true",
"isSubscribedToSavingsService": false,
"isSubscribedToLoanService": false,
"txnAlertEligible": true,
"banking_entity_id": 189585760,
"banking_entity_user_id": 188595905,
"banking_entity_type": "CORPORATE",
"transactionCategory": "Bills & Utility",
"network": "mtn",
"subscriberNumber": "08123456788",
"amount_charged": "100.0",
"wallet_balance": "610.55",
"wallet_currency": "NGN",
"phoneNumber": "08123456788"
},
"userId": null,
"timeCreated": "2026-09-26T19:47:01.514+00:00"
}
}{
"code": "400",
"description": "Request failed."
}{
"code": "401",
"description": "Unauthorized"
}{
"code": "403",
"description": "Forbidden"
}{
"code": "404",
"description": "Record not found"
}{
"code": "429",
"description": "Too many requests"
}{
"code": "500",
"description": "Server error"
}{
"code": "400",
"description": "Request failed."
}code field in the response reflects the HTTP status code of the response. For example, 200 means the request completed successfully, and 201 means it was accepted and is still being processed.Authorizations
Nomba authenticates API calls with OAuth2 HTTP bearer tokens. There are two methods of authentication; Client-Credentials method and PKCE (Proof Key for Code Exchange) method. In each of the methods, You will get an ACCESS_TOKEN. You need to use an "Authorization" HTTP header to provide your ACCESS_TOKEN. For example: Authorization: {ACCESS_TOKEN}.
Headers
The parent accountId of the business.
"890022ce-bae0-45c1-9b9d-ee7872e6ca27"
Body
The request payload required to make airtime purchases
The airtime amount to be purchased
200
Recipient phone number
11 - 13"08055441122"
Recipient network (telco). It can also come as lowercased values e.g. glo, mtn etc.
GLO, MTN, 9MOBILE, AIRTEL 3"GLO"
Merchant Transaction Identifier reference (Unique to merchant)
This is an idempotency key and must be unique per transaction.
"3bvwhibh38220dsjakTwvb"
A name to describe the sender of the airtime
"John Doe"
Response
OK - your request was successful.
Response code. This reflects the HTTP status code of the response, e.g. 200 when the request completed successfully and 201 when it was accepted and is still being processed.
200, 201, 400, 401, 403, 429, 500 "200"
Response description
"SUCCESS"
Show child attributes
Show child attributes
Response message
"Transaction completed Successfully"
Whether the request was successful
true