Contents Guide Introduction Quick start Authentication Sandbox Responses & errors Webhooks Older URLs Account GET Wallet balance and profileAirtime & data POST Buy airtimeGET Data plansPOST Buy dataCable TV GET ProvidersGET Plans (bouquets)POST Check a smartcard / IUCPOST Pay a subscriptionElectricity GET Distribution companiesPOST Check a meterPOST Buy a token / pay a billExam PINs GET ServicesGET Plans and pricesPOST Check a JAMB profilePOST Buy exam PINsBank transfers GET Bank listPOST Look up an account namePOST Send a transferVirtual accounts POST Open an account numberData & airtime PINs POST Take data PINsPOST Take airtime PINsUSSD app users POST List usersPOST Register a userPOST One userPOST Credit or debit a walletPOST Activate or suspendPOST A user's transactionsSandbox tools POST Simulate a depositNo match.
Introduction
The UnityBills API is a JSON REST API. You call it from your server with your API key; we pay from your wallet and answer straight away with the result.
Live base URL https://unitybills.ng
Send Content-Type: application/json and Accept: application/json. Bodies and answers are JSON.
Amounts are in naira. Phone numbers are Nigerian numbers such as 08031234567.
Networks: 1 MTN, 2 GLO, 3 9MOBILE, 4 AIRTEL.
Every purchase is paid from your wallet. If it fails it is refunded at once; if the provider is still processing it, it is completed or refunded automatically.
Quick start
Create an account and complete your business verification (KYB).
Once your KYC is approved, sign the Service Agreement in your dashboard (Account → Service Agreement). That unlocks merchant and API access.
Copy your API key from Dashboard → API and build against the sandbox : it answers exactly like live, with test money.
Fund your live wallet and switch to the live base URL and key.
Your first call Copy
curl -X GET 'https://unitybills.ng/user' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
Authentication
Send your API key in the Authorization header of every request, as Token YOUR_API_KEY. Keep the key on your server: never put it in a mobile app, web page or public repository. You can generate a new key on Dashboard → API at any time (the old one stops working).
A missing or wrong key is answered with HTTP 401, for example:
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Invalid API key"
}
Sandbox
The sandbox is a separate copy of UnityBills where nothing real happens: no airtime, data, subscription, token or bank transfer is delivered and no real money moves. Everything else is the live system: the same validation, wallet debits and refunds, receipts, webhooks and exactly the same responses. Answers carry the header X-UnityBills-Mode: sandbox.
Register on the sandbox with the same steps as live (KYB and the Service Agreement), then sign in and add test money on Fund wallet → Add test funds .
Use the sandbox API key (Dashboard → API) with the sandbox base URL.
Use the values below to get each outcome; anything else succeeds.
To test deposits into your customers' account numbers, use Simulate a deposit : your wallet is credited and the signed webhook is sent, as for a real bank transfer.
Responses & errors
Check the HTTP status and the status field ("success"; Status repeats it as "successful"). Errors carry the reason in error (some endpoints use message). Keep the reference or transaction_id of every purchase: it is on the receipt in your dashboard.
Never send the same purchase twice because an answer was slow: use a long timeout (90 seconds) and, for transfers, your own unique reference.
Webhooks
For every deposit into one of your customers' account numbers (see Virtual accounts ) we credit your wallet, less 1.2% (at most ₦350), and POST this JSON to that account's webhook_url:
{
"virtualAccount" : "9912345678" ,
"amountReceived" : "20000" ,
"sessionId" : "100004261017103000123456789012" ,
"sourceAccountName" : "ADA OBI" ,
"reference" : "pay_8c2f7a1d0b" ,
"sourceBankName" : "Guaranty Trust Bank" ,
"status" : "successful"
}
Verify every delivery before crediting anyone. x-api-signature is the HMAC-SHA512 of the raw body, keyed with your API key. For replay protection also check x-signature-v2: HMAC-SHA512 of "{x-webhook-timestamp}.{x-webhook-nonce}.{body}", and reject timestamps older than 5 minutes or a nonce you have seen.
Verify a webhook PHP Node.js
$body = file_get_contents('php://input');
$expected = hash_hmac('sha512', $body, getenv('UNITYBILLS_API_KEY'));
if (!hash_equals($expected, $_SERVER['HTTP_X_API_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);
// Credit once per sessionId, then answer 200.
http_response_code(200);
const crypto = require('crypto');
// Use the raw request body (e.g. express.raw({ type: 'application/json' })).
const expected = crypto.createHmac('sha512', process.env.UNITYBILLS_API_KEY).update(rawBody).digest('hex');
const given = req.get('x-api-signature') || '';
if (given.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
return res.sendStatus(401);
}
// Credit once per sessionId, then answer 200.
res.sendStatus(200);
Answer with a 2xx within 15 seconds. Otherwise we retry 4 more times (after 1, 5, 15 and 60 minutes). Process each sessionId only once.
Older URLs
These keep working for integrations built on them, with the same answers as before. New integrations should use the endpoints below.
URL Same as
/api/data, /api/wp-json/v1/api/data, /api/wp-json/v2/api/data, /api/wp-json/max/v1/api/data, /api/wp-json/max/v2/api/dataBuy data
/api/topupBuy airtime
GET /api/validatemeter, POST /api/billpayment (MSORG style: disconame/disco_name 1–11, MeterType 1 prepaid, 2 postpaid)Check a meter , Buy a token
/api/v1/fetch-data-pins (by reference_id), /api/v1/fetch-data-pins/topupmateTake data PINs
/api/v1/corporate/virtual-accountRetired: answers 400. Use Open an account number .
Account
GET
/api/v1/user
Copy URL
Wallet balance and profile
Your profile and current wallet balance. Use it to check your key works and to show your balance.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/user' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/user');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/user', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/user',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"user" : {
"id" : 1348 ,
"email" : "ada@adastores.ng" ,
"FirstName" : "Ada" ,
"Phone" : "08031234567" ,
"Account_Balance" : "50000.00000000" ,
"wallet_balance" : "50000.00"
}
}
Airtime & data
Networks: 1 MTN, 2 GLO, 3 9MOBILE, 4 AIRTEL. A purchase that fails is refunded to your wallet at once; when the network declines it, reason says why. If the network does not answer in time you get 202 pending: do not retry; it is confirmed or refunded.
POST
/api/v1/airtime
Copy URL
Buy airtime
Top up any Nigerian number. Merchants pay the discounted rate set on their account; the service discount is credited to the discount wallet.
Success
200
Declined by the network
400
Validation error
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/airtime' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"amount":200,"mobile_number":"08031234567","airtime_type":"VTU","Ported_number":true}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/airtime', [
'network' => 1,
'amount' => 200,
'mobile_number' => '08031234567',
'airtime_type' => 'VTU',
'Ported_number' => true,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/airtime', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"amount": 200,
"mobile_number": "08031234567",
"airtime_type": "VTU",
"Ported_number": true
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/airtime',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"amount": 200,
"mobile_number": "08031234567",
"airtime_type": "VTU",
"Ported_number": True
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Airtime purchase completed successfully" ,
"transaction_details" : {
"status" : "successful" ,
"message" : "Airtime purchase completed successfully" ,
"transaction_id" : "API-TRX75612411300594031B100D" ,
"network" : 1 ,
"amount" : 200 ,
"phone_number" : "08031234567"
},
"reference" : "API-TRX75612411300594031B100D" ,
"discount" : null
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/airtime' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"amount":200,"mobile_number":"08000000000","airtime_type":"VTU","Ported_number":true}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/airtime', [
'network' => 1,
'amount' => 200,
'mobile_number' => '08000000000',
'airtime_type' => 'VTU',
'Ported_number' => true,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/airtime', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"amount": 200,
"mobile_number": "08000000000",
"airtime_type": "VTU",
"Ported_number": true
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/airtime',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"amount": 200,
"mobile_number": "08000000000",
"airtime_type": "VTU",
"Ported_number": True
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"message" : "Transaction failed. Please try again later or contact support." ,
"error" : "Unable to complete airtime purchase at this time" ,
"reason" : "Invalid phone number for this network"
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/airtime' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"amount":20,"mobile_number":"08031234567","airtime_type":"VTU"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/airtime', [
'network' => 1,
'amount' => 20,
'mobile_number' => '08031234567',
'airtime_type' => 'VTU',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/airtime', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"amount": 20,
"mobile_number": "08031234567",
"airtime_type": "VTU"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/airtime',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"amount": 20,
"mobile_number": "08031234567",
"airtime_type": "VTU"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "The amount must be at least 50."
}
GET
/api/v1/data/plans
Copy URL
Data plans
The data plans on sale with the price you are charged. Filter by network and/or type, or send neither for every plan. `plan` is the id to buy with.
All plans
200
MTN SME only
200
Unknown network
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/data/plans' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/data/plans');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data/plans', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/data/plans',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Data plans retrieved successfully" ,
"data" : [
{
"plan" : 101 ,
"network" : 1 ,
"network_name" : "MTN" ,
"type" : "SME" ,
"name" : "1GB SME" ,
"validity_days" : 30 ,
"amount" : 260
},
{
"plan" : 102 ,
"network" : 1 ,
"network_name" : "MTN" ,
"type" : "SME" ,
"name" : "2GB SME" ,
"validity_days" : 7 ,
"amount" : 515
},
{
"plan" : 103 ,
"network" : 4 ,
"network_name" : "AIRTEL" ,
"type" : "GIFTING" ,
"name" : "Airtel 1.5GB Gifting" ,
"validity_days" : 30 ,
"amount" : 1020
}
]
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/data/plans?network=1&type=sme' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/data/plans?network=1&type=sme');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data/plans?network=1&type=sme', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/data/plans?network=1&type=sme',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Data plans retrieved successfully" ,
"data" : [
{
"plan" : 101 ,
"network" : 1 ,
"network_name" : "MTN" ,
"type" : "SME" ,
"name" : "1GB SME" ,
"validity_days" : 30 ,
"amount" : 260
},
{
"plan" : 102 ,
"network" : 1 ,
"network_name" : "MTN" ,
"type" : "SME" ,
"name" : "2GB SME" ,
"validity_days" : 7 ,
"amount" : 515
}
]
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/data/plans?network=vodafone' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/data/plans?network=vodafone');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data/plans?network=vodafone', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/data/plans?network=vodafone',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Unknown network. Use 1 (MTN), 2 (GLO), 3 (9MOBILE) or 4 (AIRTEL), or the name."
}
POST
/api/v1/data
Copy URL
Buy data
Buy a data plan. Get plan ids and your prices from GET /data/plans; the plan decides the network and size.
Success
200
Declined by the network
400
Unknown plan
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/data' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"plan":101,"mobile_number":"08031234567","Ported_number":true}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/data', [
'network' => 1,
'plan' => 101,
'mobile_number' => '08031234567',
'Ported_number' => true,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"plan": 101,
"mobile_number": "08031234567",
"Ported_number": true
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/data',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"plan": 101,
"mobile_number": "08031234567",
"Ported_number": True
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"true_response" : "Data purchase successful" ,
"transaction_details" : {
"id" : 2384 ,
"network" : 1 ,
"mobile_number" : "08031234567" ,
"Status" : "successful" ,
"api_response" : "Dear Customer, You have successfully shared 1GB SME Data to 2348031234567." ,
"plan_network" : "MTN" ,
"plan_name" : "1GB SME" ,
"create_date" : "2026-10-17T10:46:00+01:00" ,
"Ported_number" : true
},
"reference" : "API-TRX85648114132853DB7981DE" ,
"discount_applied" : "none" ,
"merchant_price_applied" : "yes" ,
"amount_debited" : "260.00" ,
"discount" : null
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/data' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"plan":101,"mobile_number":"08000000000","Ported_number":true}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/data', [
'network' => 1,
'plan' => 101,
'mobile_number' => '08000000000',
'Ported_number' => true,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"plan": 101,
"mobile_number": "08000000000",
"Ported_number": true
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/data',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"plan": 101,
"mobile_number": "08000000000",
"Ported_number": True
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Failed to process your transaction, please try again later or contact our support team." ,
"full_response" : "Failed to process your transaction, please try again later" ,
"reason" : "Invalid phone number for this network"
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/data' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":1,"plan":999999,"mobile_number":"08031234567"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/data', [
'network' => 1,
'plan' => 999999,
'mobile_number' => '08031234567',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/data', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": 1,
"plan": 999999,
"mobile_number": "08031234567"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/data',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": 1,
"plan": 999999,
"mobile_number": "08031234567"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "The selected plan is invalid."
}
Cable TV
DSTV, GOTV, Startimes and Showmax. Check the smartcard first, then pay. A bouquet change, Startimes and Showmax are charged at the plan price; a DSTV/GOTV renewal at the amount you send (the renewal amount).
GET
/api/v1/cable/providers
Copy URL
Providers
The cable TV services you can pay.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/cable/providers' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/cable/providers');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/providers', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/cable/providers',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Cable providers retrieved successfully" ,
"data" : [
{
"code" : "dstv" ,
"name" : "DSTV" ,
"image" : "http://localhost/assets/images/brands/dstv.png"
},
{
"code" : "gotv" ,
"name" : "GOTV" ,
"image" : "http://localhost/assets/images/brands/gotv.png"
},
{
"code" : "startimes" ,
"name" : "Startimes" ,
"image" : "http://localhost/assets/images/brands/startimes.png"
},
{
"code" : "showmax" ,
"name" : "Showmax" ,
"image" : "http://localhost/assets/images/brands/showmax.png"
}
]
}
GET
/api/v1/cable/plans
Copy URL
Plans (bouquets)
Bouquets and current prices for a provider.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/cable/plans?service_id=gotv' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/cable/plans?service_id=gotv');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/plans?service_id=gotv', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/cable/plans?service_id=gotv',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Cable plans retrieved successfully" ,
"data" : [
{
"variation_code" : "gotv-smallie" ,
"name" : "GOtv Smallie N1,900" ,
"amount" : "1900.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "gotv-jinja" ,
"name" : "GOtv Jinja N3,900" ,
"amount" : "3900.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "gotv-jolli" ,
"name" : "GOtv Jolli N5,800" ,
"amount" : "5800.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "gotv-max" ,
"name" : "GOtv Max N8,500" ,
"amount" : "8500.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "gotv-supa" ,
"name" : "GOtv Supa N11,400" ,
"amount" : "11400.00" ,
"fixedPrice" : "Yes"
}
]
}
POST
/api/v1/cable/validate
Copy URL
Check a smartcard / IUC
The customer name, status and due date for a smartcard number.
Valid
200
Not valid
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/validate' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"dstv","smart_card_number":"7032054653"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/validate', [
'service_id' => 'dstv',
'smart_card_number' => '7032054653',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/validate', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "dstv",
"smart_card_number": "7032054653"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/validate',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "dstv",
"smart_card_number": "7032054653"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Customer validated successfully" ,
"data" : {
"customer_name" : "SANDBOX CUSTOMER" ,
"customer_number" : "032054653" ,
"customer_type" : "DSTV" ,
"status" : "ACTIVE" ,
"due_date" : "2026-10-29T00:00:00" ,
"smart_card_number" : "7032054653" ,
"service_id" : "dstv"
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/validate' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"dstv","smart_card_number":"0000000000"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/validate', [
'service_id' => 'dstv',
'smart_card_number' => '0000000000',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/validate', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "dstv",
"smart_card_number": "0000000000"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/validate',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "dstv",
"smart_card_number": "0000000000"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Invalid smart card number"
}
POST
/api/v1/cable/purchase
Copy URL
Pay a subscription
Renew the current bouquet or change to another.
Success
200
Processing (202)
202
Failed (refunded)
400
Amount below the plan price
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"gotv","smart_card_number":"7032054653","variation_code":"gotv-max","amount":8500,"phone":"08031234567","subscription_type":"change"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/purchase', [
'service_id' => 'gotv',
'smart_card_number' => '7032054653',
'variation_code' => 'gotv-max',
'amount' => 8500,
'phone' => '08031234567',
'subscription_type' => 'change',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "gotv",
"smart_card_number": "7032054653",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "gotv",
"smart_card_number": "7032054653",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Cable TV subscription purchased successfully" ,
"data" : {
"transaction_id" : "753389301442d19c75ee" ,
"smart_card_number" : "7032054653" ,
"service_id" : "gotv" ,
"variation_code" : "gotv-max" ,
"subscription_type" : "change" ,
"amount" : 8500 ,
"balance_before" : "49540.00000000" ,
"balance_after" : 41040
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"gotv","smart_card_number":"201000000000","variation_code":"gotv-max","amount":8500,"phone":"08031234567","subscription_type":"change"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/purchase', [
'service_id' => 'gotv',
'smart_card_number' => '201000000000',
'variation_code' => 'gotv-max',
'amount' => 8500,
'phone' => '08031234567',
'subscription_type' => 'change',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "gotv",
"smart_card_number": "201000000000",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "gotv",
"smart_card_number": "201000000000",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
},
timeout=90,
)
data = response.json()
Response · 202 Accepted Copy
{
"status" : "pending" ,
"Status" : "processing" ,
"message" : "Transaction is processing. If it fails, the amount is refunded to your wallet automatically." ,
"data" : {
"transaction_id" : "04983797438442a69ba7" ,
"smart_card_number" : "201000000000" ,
"service_id" : "gotv" ,
"variation_code" : "gotv-max" ,
"subscription_type" : "change" ,
"amount" : 8500 ,
"balance_before" : "41040.00000000" ,
"balance_after" : 32540
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"gotv","smart_card_number":"400000000000","variation_code":"gotv-max","amount":8500,"phone":"08031234567","subscription_type":"change"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/purchase', [
'service_id' => 'gotv',
'smart_card_number' => '400000000000',
'variation_code' => 'gotv-max',
'amount' => 8500,
'phone' => '08031234567',
'subscription_type' => 'change',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "gotv",
"smart_card_number": "400000000000",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "gotv",
"smart_card_number": "400000000000",
"variation_code": "gotv-max",
"amount": 8500,
"phone": "08031234567",
"subscription_type": "change"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "TRANSACTION FAILED"
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/cable/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"gotv","smart_card_number":"7032054653","variation_code":"gotv-max","amount":100,"phone":"08031234567","subscription_type":"change"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/cable/purchase', [
'service_id' => 'gotv',
'smart_card_number' => '7032054653',
'variation_code' => 'gotv-max',
'amount' => 100,
'phone' => '08031234567',
'subscription_type' => 'change',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/cable/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "gotv",
"smart_card_number": "7032054653",
"variation_code": "gotv-max",
"amount": 100,
"phone": "08031234567",
"subscription_type": "change"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/cable/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "gotv",
"smart_card_number": "7032054653",
"variation_code": "gotv-max",
"amount": 100,
"phone": "08031234567",
"subscription_type": "change"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "The amount is below the price of this plan (8,500.00)"
}
Electricity
Prepaid tokens and postpaid bills for every distribution company. Check the meter first, then pay.
GET
/api/v1/utility/providers
Copy URL
Distribution companies
The service_id of each DisCo.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/utility/providers' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/utility/providers');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/providers', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/utility/providers',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Utility providers retrieved successfully" ,
"data" : [
{
"code" : "ikeja-electric" ,
"name" : "Ikeja Electric Payment - IKEDC" ,
"type" : "electricity"
},
{
"code" : "eko-electric" ,
"name" : "Eko Electricity - EKEDC" ,
"type" : "electricity"
},
{
"code" : "kano-electric" ,
"name" : "Kano Electricity - KEDCO" ,
"type" : "electricity"
},
{
"code" : "portharcourt-electric" ,
"name" : "Port Harcourt Electricity - PHED" ,
"type" : "electricity"
},
{
"code" : "jos-electric" ,
"name" : "Jos Electricity - JED" ,
"type" : "electricity"
},
{
"code" : "ibadan-electric" ,
"name" : "Ibadan Electricity - IBEDC" ,
"type" : "electricity"
},
{
"code" : "kaduna-electric" ,
"name" : "Kaduna Electricity - KAEDCO" ,
"type" : "electricity"
},
{
"code" : "abuja-electric" ,
"name" : "Abuja Electricity - AEDC" ,
"type" : "electricity"
}
]
}
POST
/api/v1/utility/validate
Copy URL
Check a meter
The customer name and address on a meter.
Valid
200
Not valid
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/utility/validate' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"kano-electric","meter_number":"45012345678","meter_type":"prepaid"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/utility/validate', [
'service_id' => 'kano-electric',
'meter_number' => '45012345678',
'meter_type' => 'prepaid',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/validate', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "kano-electric",
"meter_number": "45012345678",
"meter_type": "prepaid"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/utility/validate',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "kano-electric",
"meter_number": "45012345678",
"meter_type": "prepaid"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Meter validated successfully" ,
"data" : {
"customer_name" : "SANDBOX CUSTOMER" ,
"meter_number" : "45012345678" ,
"meter_type" : "prepaid" ,
"address" : "12 Sandbox Street, Kano"
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/utility/validate' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"kano-electric","meter_number":"0000000000","meter_type":"prepaid"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/utility/validate', [
'service_id' => 'kano-electric',
'meter_number' => '0000000000',
'meter_type' => 'prepaid',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/validate', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "kano-electric",
"meter_number": "0000000000",
"meter_type": "prepaid"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/utility/validate',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "kano-electric",
"meter_number": "0000000000",
"meter_type": "prepaid"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Invalid meter number"
}
POST
/api/v1/utility/purchase
Copy URL
Buy a token / pay a bill
Prepaid returns the token; postpaid pays the bill.
Success (token)
200
Processing (202)
202
Failed (refunded)
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/utility/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"kano-electric","meter_number":"45012345678","meter_type":"prepaid","amount":5000,"phone":"08031234567"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/utility/purchase', [
'service_id' => 'kano-electric',
'meter_number' => '45012345678',
'meter_type' => 'prepaid',
'amount' => 5000,
'phone' => '08031234567',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "kano-electric",
"meter_number": "45012345678",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/utility/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "kano-electric",
"meter_number": "45012345678",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Utility payment successful" ,
"data" : {
"transaction_id" : "551731115013276220d7" ,
"meter_number" : "45012345678" ,
"amount" : 5000 ,
"units" : "74.8 kWh" ,
"token" : "Token : 1005-0253-8254-0262-2022" ,
"purchased_code" : "Token : 1005-0253-8254-0262-2022" ,
"balance_before" : "32540.00000000" ,
"balance_after" : 27540
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/utility/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"kano-electric","meter_number":"201000000000","meter_type":"prepaid","amount":5000,"phone":"08031234567"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/utility/purchase', [
'service_id' => 'kano-electric',
'meter_number' => '201000000000',
'meter_type' => 'prepaid',
'amount' => 5000,
'phone' => '08031234567',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "kano-electric",
"meter_number": "201000000000",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/utility/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "kano-electric",
"meter_number": "201000000000",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
},
timeout=90,
)
data = response.json()
Response · 202 Accepted Copy
{
"status" : "pending" ,
"Status" : "processing" ,
"message" : "Transaction is processing. If it fails, the amount is refunded to your wallet automatically." ,
"data" : {
"transaction_id" : "132554150271fd89146b" ,
"meter_number" : "201000000000" ,
"amount" : 5000 ,
"units" : null ,
"token" : null ,
"purchased_code" : "" ,
"balance_before" : "27540.00000000" ,
"balance_after" : 22540
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/utility/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"kano-electric","meter_number":"400000000000","meter_type":"prepaid","amount":5000,"phone":"08031234567"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/utility/purchase', [
'service_id' => 'kano-electric',
'meter_number' => '400000000000',
'meter_type' => 'prepaid',
'amount' => 5000,
'phone' => '08031234567',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/utility/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "kano-electric",
"meter_number": "400000000000",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/utility/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "kano-electric",
"meter_number": "400000000000",
"meter_type": "prepaid",
"amount": 5000,
"phone": "08031234567"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "TRANSACTION FAILED"
}
Exam PINs
WAEC result checker and registration PINs, and JAMB (UTME / Direct Entry) PINs.
GET
/api/v1/education/services
Copy URL
Services
The exam PIN services.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/education/services' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/education/services');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/education/services', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/education/services',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Education services retrieved successfully" ,
"data" : [
{
"service_id" : "waec" ,
"name" : "WAEC Result Checker" ,
"description" : "West African Examinations Council Result Checker" ,
"type" : "result_checker" ,
"image" : "http://localhost/assets/images/brands/waec.png"
},
{
"service_id" : "neco" ,
"name" : "NECO Result Checker" ,
"description" : "National Examinations Council Result Checker" ,
"type" : "result_checker" ,
"image" : "http://localhost/assets/images/brands/neco.png"
},
{
"service_id" : "jamb" ,
"name" : "JAMB PIN" ,
"description" : "Joint Admissions and Matriculation Board PIN" ,
"type" : "pin_vending" ,
"image" : "http://localhost/assets/images/brands/jamb.png"
},
{
"service_id" : "waec-registration" ,
"name" : "WAEC Registration" ,
"description" : "WAEC Registration PIN for Private Candidates" ,
"type" : "registration" ,
"image" : "http://localhost/assets/images/brands/waec.png"
}
]
}
GET
/api/v1/education/plans
Copy URL
Plans and prices
Variations and prices of a service.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/education/plans?service_id=jamb' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/education/plans?service_id=jamb');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/education/plans?service_id=jamb', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/education/plans?service_id=jamb',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Education variations retrieved successfully" ,
"data" : {
"service_name" : "Jamb PIN VENDING (UTME & Direct Entry)" ,
"service_id" : "jamb" ,
"variations" : [
{
"variation_code" : "utme-mock" ,
"name" : "UTME PIN (with mock)" ,
"amount" : "8700.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "utme-no-mock" ,
"name" : "UTME PIN (without mock)" ,
"amount" : "7200.00" ,
"fixedPrice" : "Yes"
},
{
"variation_code" : "de" ,
"name" : "Direct Entry (DE)" ,
"amount" : "7200.00" ,
"fixedPrice" : "Yes"
}
]
}
}
POST
/api/v1/education/validate/profile
Copy URL
Check a JAMB profile
The candidate name on a JAMB profile id.
Valid
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/education/validate/profile' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"jamb","profile_id":"0123456789","variation_code":"utme-no-mock"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/education/validate/profile', [
'service_id' => 'jamb',
'profile_id' => '0123456789',
'variation_code' => 'utme-no-mock',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/education/validate/profile', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "jamb",
"profile_id": "0123456789",
"variation_code": "utme-no-mock"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/education/validate/profile',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "jamb",
"profile_id": "0123456789",
"variation_code": "utme-no-mock"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Profile validated successfully" ,
"data" : {
"customer_name" : "SANDBOX CANDIDATE" ,
"profile_id" : "0123456789" ,
"service_id" : "jamb"
}
}
POST
/api/v1/education/purchase
Copy URL
Buy exam PINs
Up to 10 PINs per request. The PINs are in the answer.
WAEC result checker
200
JAMB
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/education/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"waec","variation_code":"waecdirect","amount":3900,"phone":"08031234567","quantity":2}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/education/purchase', [
'service_id' => 'waec',
'variation_code' => 'waecdirect',
'amount' => 3900,
'phone' => '08031234567',
'quantity' => 2,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/education/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "waec",
"variation_code": "waecdirect",
"amount": 3900,
"phone": "08031234567",
"quantity": 2
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/education/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "waec",
"variation_code": "waecdirect",
"amount": 3900,
"phone": "08031234567",
"quantity": 2
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Education service purchased successfully" ,
"data" : {
"transaction_id" : "905034103252ac997ae9" ,
"service_id" : "waec" ,
"variation_code" : "waecdirect" ,
"quantity" : 2 ,
"amount" : 7800 ,
"purchased_code" : "Serial No:WRN442111456, pin: 403252233181||Serial No:WRN137117856, pin: 305020344716" ,
"balance_before" : "22540.00000000" ,
"balance_after" : 14740 ,
"cards" : [
{
"Serial" : "WRN442111456" ,
"Pin" : "403252233181"
},
{
"Serial" : "WRN137117856" ,
"Pin" : "305020344716"
}
]
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/education/purchase' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"service_id":"jamb","variation_code":"utme-no-mock","amount":7200,"phone":"08031234567","profile_id":"0123456789"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/education/purchase', [
'service_id' => 'jamb',
'variation_code' => 'utme-no-mock',
'amount' => 7200,
'phone' => '08031234567',
'profile_id' => '0123456789',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/education/purchase', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"service_id": "jamb",
"variation_code": "utme-no-mock",
"amount": 7200,
"phone": "08031234567",
"profile_id": "0123456789"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/education/purchase',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"service_id": "jamb",
"variation_code": "utme-no-mock",
"amount": 7200,
"phone": "08031234567",
"profile_id": "0123456789"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "Education service purchased successfully" ,
"data" : {
"transaction_id" : "240202581721864c5a97" ,
"service_id" : "jamb" ,
"variation_code" : "utme-no-mock" ,
"quantity" : 1 ,
"amount" : 7200 ,
"purchased_code" : "Pin : 918604391c0ba41a" ,
"balance_before" : "14740.00000000" ,
"balance_after" : 7540 ,
"pin" : "Pin : 918604391c0ba41a"
}
}
Bank transfers
Send money from your wallet to any Nigerian bank account. Each transfer costs a flat fee, debited with the amount. The fee is ₦50 per transfer.
GET
/api/v1/banks
Copy URL
Bank list
Bank codes to use for transfers and account lookups.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X GET 'https://unitybills.ng/banks' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->get('https://unitybills.ng/banks');
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/banks', {
method: 'GET',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
},
});
const data = await response.json();
import os, requests
response = requests.get(
'https://unitybills.ng/banks',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"data" : [
{
"code" : "044" ,
"name" : "Access Bank"
},
{
"code" : "023" ,
"name" : "Citibank Nigeria"
},
{
"code" : "050" ,
"name" : "Ecobank Nigeria"
},
{
"code" : "070" ,
"name" : "Fidelity Bank"
},
{
"code" : "011" ,
"name" : "First Bank of Nigeria"
},
{
"code" : "214" ,
"name" : "First City Monument Bank"
},
{
"code" : "058" ,
"name" : "Guaranty Trust Bank"
},
{
"code" : "030" ,
"name" : "Heritage Bank"
},
{
"code" : "301" ,
"name" : "Jaiz Bank"
},
{
"code" : "082" ,
"name" : "Keystone Bank"
},
{
"code" : "50211" ,
"name" : "Kuda Microfinance Bank"
},
{
"code" : "50515" ,
"name" : "Moniepoint Microfinance Bank"
},
{
"code" : "999992" ,
"name" : "OPay"
},
{
"code" : "999991" ,
"name" : "PalmPay"
},
{
"code" : "076" ,
"name" : "Polaris Bank"
},
{
"code" : "221" ,
"name" : "Stanbic IBTC Bank"
},
{
"code" : "068" ,
"name" : "Standard Chartered Bank"
},
{
"code" : "232" ,
"name" : "Sterling Bank"
},
{
"code" : "032" ,
"name" : "Union Bank of Nigeria"
},
{
"code" : "033" ,
"name" : "United Bank For Africa"
},
{
"code" : "215" ,
"name" : "Unity Bank"
},
{
"code" : "035" ,
"name" : "Wema Bank"
},
{
"code" : "057" ,
"name" : "Zenith Bank"
}
]
}
POST
/api/v1/verify-account
Copy URL
Look up an account name
Confirm who owns an account before you send money.
Found
200
Not found
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/verify-account' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"bank_code":"058","account_number":"0123456789"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/verify-account', [
'bank_code' => '058',
'account_number' => '0123456789',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/verify-account', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"bank_code": "058",
"account_number": "0123456789"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/verify-account',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"bank_code": "058",
"account_number": "0123456789"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"account_name" : "SANDBOX ACCOUNT 6789"
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/verify-account' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"bank_code":"058","account_number":"0000000000"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/verify-account', [
'bank_code' => '058',
'account_number' => '0000000000',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/verify-account', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"bank_code": "058",
"account_number": "0000000000"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/verify-account',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"bank_code": "058",
"account_number": "0000000000"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Account not found"
}
POST
/api/v1/transfer
Copy URL
Send a transfer
Use your own unique reference so you can match the result. "pending" means the bank has not confirmed yet; if it then fails, the amount and fee are refunded automatically.
Successful
200
Pending
200
Refused (refunded)
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/transfer' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"beneficiaryBankCode":"058","beneficiaryAccountNumber":"0123456789","amount":1000,"narration":"Payout","reference":"PAYOUT-0001"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/transfer', [
'beneficiaryBankCode' => '058',
'beneficiaryAccountNumber' => '0123456789',
'amount' => 1000,
'narration' => 'Payout',
'reference' => 'PAYOUT-0001',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/transfer', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "0123456789",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0001"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/transfer',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "0123456789",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0001"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"success" : true ,
"message" : "Transfer successful" ,
"data" : {
"reference" : "PAYOUT-0001" ,
"status" : "successful" ,
"amount" : 1000 ,
"currency" : "NGN" ,
"created_at" : null ,
"completed_at" : null ,
"beneficiary" : {
"account_number" : "0123456789" ,
"account_name" : "SANDBOX ACCOUNT 6789" ,
"bank_name" : "Guaranty Trust Bank" ,
"bank_code" : "058"
},
"narration" : "Payout" ,
"provider_message" : "Approved"
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/transfer' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"beneficiaryBankCode":"058","beneficiaryAccountNumber":"2222222222","amount":1000,"narration":"Payout","reference":"PAYOUT-0002"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/transfer', [
'beneficiaryBankCode' => '058',
'beneficiaryAccountNumber' => '2222222222',
'amount' => 1000,
'narration' => 'Payout',
'reference' => 'PAYOUT-0002',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/transfer', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "2222222222",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0002"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/transfer',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "2222222222",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0002"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"success" : true ,
"message" : "Transfer is processing" ,
"data" : {
"reference" : "PAYOUT-0002" ,
"status" : "pending" ,
"amount" : 1000 ,
"currency" : "NGN" ,
"created_at" : null ,
"completed_at" : null ,
"beneficiary" : {
"account_number" : "2222222222" ,
"account_name" : "SANDBOX ACCOUNT 2222" ,
"bank_name" : "Guaranty Trust Bank" ,
"bank_code" : "058"
},
"narration" : "Payout" ,
"provider_message" : "Transfer is awaiting confirmation"
}
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/transfer' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"beneficiaryBankCode":"058","beneficiaryAccountNumber":"1111111111","amount":1000,"narration":"Payout","reference":"PAYOUT-0003"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/transfer', [
'beneficiaryBankCode' => '058',
'beneficiaryAccountNumber' => '1111111111',
'amount' => 1000,
'narration' => 'Payout',
'reference' => 'PAYOUT-0003',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/transfer', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "1111111111",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0003"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/transfer',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"beneficiaryBankCode": "058",
"beneficiaryAccountNumber": "1111111111",
"amount": 1000,
"narration": "Payout",
"reference": "PAYOUT-0003"
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"success" : false ,
"message" : "Beneficiary bank declined the transfer" ,
"data" : {
"reference" : "PAYOUT-0003" ,
"status" : "failed" ,
"amount" : 1000 ,
"currency" : "NGN" ,
"created_at" : null ,
"completed_at" : null ,
"beneficiary" : {
"account_number" : "1111111111" ,
"account_name" : null ,
"bank_name" : "Guaranty Trust Bank" ,
"bank_code" : "058"
},
"narration" : "Payout" ,
"provider_message" : "Beneficiary bank declined the transfer"
}
}
Virtual accounts
Give each customer their own account number. Money sent to it is credited to your wallet (less the deposit fee) and reported to the account's webhook_url. Needs an approved business verification (KYB).
POST
/api/v1/virtual-account
Copy URL
Open an account number
Calling again for the same customer returns the same account.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/virtual-account' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"firstname":"Ada","lastname":"Obi","phoneNumber":"08031234567","nin":"12345678901","webhook_url":"https://yourapp.ng/hooks/deposits"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/virtual-account', [
'firstname' => 'Ada',
'lastname' => 'Obi',
'phoneNumber' => '08031234567',
'nin' => '12345678901',
'webhook_url' => 'https://yourapp.ng/hooks/deposits',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/virtual-account', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"firstname": "Ada",
"lastname": "Obi",
"phoneNumber": "08031234567",
"nin": "12345678901",
"webhook_url": "https://yourapp.ng/hooks/deposits"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/virtual-account',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"firstname": "Ada",
"lastname": "Obi",
"phoneNumber": "08031234567",
"nin": "12345678901",
"webhook_url": "https://yourapp.ng/hooks/deposits"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"success" : true ,
"data" : {
"metadata" : [],
"createdAt" : 1792233720000 ,
"updatedAt" : 1792233720000 ,
"id" : 4629 ,
"accountNumber" : "3452858578" ,
"accountName" : "UNITYBILLS/ADA OBI (ADA STORES)" ,
"accountType" : "individual" ,
"firstname" : "Ada Stores" ,
"lastname" : "Ada" ,
"middlename" : "Obi" ,
"mobileNumber" : "08031234567" ,
"externalReference" : "ub020no557871337m979o0n085" ,
"emailAddress" : "ada@adastores.ng" ,
"bvn" : "12345678901" ,
"gender" : "male" ,
"address" : "" ,
"dateOfBirth" : "" ,
"validityType" : "permanent"
}
}
Data & airtime PINs
Hand out PINs you generated (and paid for) on the dashboard, e.g. to print or sell in your own app. Each PIN is given out once.
POST
/api/v1/fetch-data-pins/v2
Copy URL
Take data PINs
Customers load a PIN by dialling *7006*47*PIN#.
Success
200
Not enough PINs
400
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/fetch-data-pins/v2' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":"1","data_plan":"31","quantity":2}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/fetch-data-pins/v2', [
'network' => '1',
'data_plan' => '31',
'quantity' => 2,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/fetch-data-pins/v2', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": "1",
"data_plan": "31",
"quantity": 2
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/fetch-data-pins/v2',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": "1",
"data_plan": "31",
"quantity": 2
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"quantity" : "2" ,
"pin" : "0029224,1743805" ,
"serial" : "B-2283-7455,B-2283-7455" ,
"load_pin" : "*7006*47*pin#" ,
"check_balance" : "*323*4#"
}
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/fetch-data-pins/v2' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":"1","data_plan":"31","quantity":50}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/fetch-data-pins/v2', [
'network' => '1',
'data_plan' => '31',
'quantity' => 50,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/fetch-data-pins/v2', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": "1",
"data_plan": "31",
"quantity": 50
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/fetch-data-pins/v2',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": "1",
"data_plan": "31",
"quantity": 50
},
timeout=90,
)
data = response.json()
Response · 400 Bad Request Copy
{
"status" : "error" ,
"Status" : "failed" ,
"error" : "Only 1 pins available (requested: 50)" ,
"available_quantity" : 1
}
POST
/api/v1/fetch-recharge-pins
Copy URL
Take airtime PINs
Airtime recharge PINs from your stock.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/fetch-recharge-pins' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"network":"1","plan":"MTN100","quantity":2}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/fetch-recharge-pins', [
'network' => '1',
'plan' => 'MTN100',
'quantity' => 2,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/fetch-recharge-pins', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"network": "1",
"plan": "MTN100",
"quantity": 2
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/fetch-recharge-pins',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"network": "1",
"plan": "MTN100",
"quantity": 2
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"quantity" : "2" ,
"pin" : "51340860747,17534456595" ,
"serial" : "SN305512,SN818276" ,
"load_pin" : "*7006*47*pin#" ,
"check_balance" : "*310#"
}
USSD app users
Manage the subscribers of your USSD app: their wallets, status and transactions.
POST
/api/v1/ussd/users/list
Copy URL
List users
Paginated, newest first.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/list' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"status":"active"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/list', [
'status' => 'active',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/list', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"status": "active"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/list',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"status": "active"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "App users retrieved successfully" ,
"data" : {
"users" : [
{
"id" : 501 ,
"fullname" : "Chidi Eze" ,
"phone" : "2348031112222" ,
"balance" : "1,500.00" ,
"status" : "active" ,
"account_number" : "1823035203" ,
"account_name" : "Chidi Eze" ,
"bank_name" : "Wema Bank" ,
"app" : {
"id" : 12 ,
"name" : "Ada Data"
},
"created_at" : "2026-09-17 10:30:00" ,
"updated_at" : "2026-09-17 10:30:00"
}
],
"pagination" : {
"current_page" : 1 ,
"per_page" : 15 ,
"total" : 1 ,
"last_page" : 1 ,
"has_more_pages" : false
},
"summary" : {
"total_users" : 1 ,
"active_users" : 1 ,
"total_balance" : "1,500.00"
}
}
}
POST
/api/v1/ussd/users/create
Copy URL
Register a user
Creates the user and their wallet; with bvn or nin, also an account number for funding.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/create' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"fullname":"Musa Bello","phone":"08035555555","pin":"1234","app_id":12,"nin":"12345678901"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/create', [
'fullname' => 'Musa Bello',
'phone' => '08035555555',
'pin' => '1234',
'app_id' => 12,
'nin' => '12345678901',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/create', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fullname": "Musa Bello",
"phone": "08035555555",
"pin": "1234",
"app_id": 12,
"nin": "12345678901"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/create',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"fullname": "Musa Bello",
"phone": "08035555555",
"pin": "1234",
"app_id": 12,
"nin": "12345678901"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "App user created successfully" ,
"data" : {
"user" : {
"id" : 1851 ,
"fullname" : "Musa Bello" ,
"phone" : "2348035555555" ,
"balance" : "0.00" ,
"status" : "active" ,
"app_id" : 12 ,
"created_at" : "2026-10-17 11:52:00"
},
"virtual_account" : {
"success" : true ,
"account_number" : "2349826071" ,
"account_name" : "UNITYBILLS/MUSA BELLO" ,
"bank_name" : "Wema Bank" ,
"message" : ""
}
}
}
POST
/api/v1/ussd/users/details
Copy URL
One user
Profile and wallet.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/details' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"user_id":501}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/details', [
'user_id' => 501,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/details', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": 501
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/details',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"user_id": 501
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "App user details retrieved successfully" ,
"data" : {
"user" : {
"id" : 501 ,
"fullname" : "Chidi Eze" ,
"phone" : "2348031112222" ,
"balance" : "1,500.00" ,
"status" : "active" ,
"account_number" : "1823035203" ,
"account_name" : "Chidi Eze" ,
"bank_name" : "Wema Bank" ,
"app" : {
"id" : 12 ,
"name" : "Ada Data"
},
"created_at" : "2026-09-17 10:30:00" ,
"updated_at" : "2026-09-17 10:30:00"
},
"recent_transactions" : [
{
"id" : 1559 ,
"transaction_id" : "TXN-66065" ,
"amount" : "280.00" ,
"type" : "buy_data" ,
"description" : "1GB SME data" ,
"status" : "successful" ,
"created_at" : "2026-10-15 10:30:00"
}
]
}
}
POST
/api/v1/ussd/users/update-balance
Copy URL
Credit or debit a wallet
A debit cannot take the wallet below zero.
Credit
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/update-balance' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"user_id":501,"action_type":"credit","amount":500,"note":"Cash top-up"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/update-balance', [
'user_id' => 501,
'action_type' => 'credit',
'amount' => 500,
'note' => 'Cash top-up',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/update-balance', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": 501,
"action_type": "credit",
"amount": 500,
"note": "Cash top-up"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/update-balance',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"user_id": 501,
"action_type": "credit",
"amount": 500,
"note": "Cash top-up"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "User successfully credited with ₦500.00" ,
"data" : {
"user_id" : 501 ,
"action_type" : "credit" ,
"amount" : "500.00" ,
"balance_before" : "1,500.00" ,
"balance_after" : "2,000.00" ,
"transaction_id" : "N170O40963M" ,
"performed_at" : "2026-10-17 11:56:00"
}
}
POST
/api/v1/ussd/users/update-status
Copy URL
Activate or suspend
A suspended user cannot use the app.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/update-status' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"user_id":501,"status":"inactive"}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/update-status', [
'user_id' => 501,
'status' => 'inactive',
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/update-status', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": 501,
"status": "inactive"
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/update-status',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"user_id": 501,
"status": "inactive"
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "User status updated successfully from active to inactive" ,
"data" : {
"user_id" : 501 ,
"old_status" : "active" ,
"new_status" : "inactive" ,
"updated_at" : "2026-10-17 11:58:00"
}
}
POST
/api/v1/ussd/users/transactions
Copy URL
A user's transactions
Paginated, newest first.
Success
200
Request
cURL
PHP
Node.js
Python
Copy
curl -X POST 'https://unitybills.ng/ussd/users/transactions' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"user_id":501}'
$response = Http::withHeaders(['Authorization' => 'Token ' . env('UNITYBILLS_API_KEY')])
->acceptJson()
->timeout(90)
->post('https://unitybills.ng/ussd/users/transactions', [
'user_id' => 501,
]);
$data = $response->json(); // Laravel; or any HTTP client
const response = await fetch('https://unitybills.ng/ussd/users/transactions', {
method: 'POST',
headers: {
Authorization: 'Token ' + process.env.UNITYBILLS_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": 501
})
});
const data = await response.json();
import os, requests
response = requests.post(
'https://unitybills.ng/ussd/users/transactions',
headers={'Authorization': 'Token ' + os.environ['UNITYBILLS_API_KEY'], 'Accept': 'application/json'},
json={
"user_id": 501
},
timeout=90,
)
data = response.json()
Response · 200 OK Copy
{
"status" : "success" ,
"Status" : "successful" ,
"message" : "User transactions retrieved successfully" ,
"data" : {
"user" : {
"id" : 501 ,
"fullname" : "Chidi Eze" ,
"phone" : "2348031112222" ,
"current_balance" : "2,000.00"
},
"transactions" : [
{
"id" : 8280 ,
"transaction_id" : "N170O40963M" ,
"amount" : "500.00" ,
"type" : "fund_wallet" ,
"description" : "Cash top-up" ,
"status" : "successful" ,
"recipient" : null ,
"created_at" : "2026-10-17 11:56:00"
},
{
"id" : 8522 ,
"transaction_id" : "TXN-66065" ,
"amount" : "280.00" ,
"type" : "buy_data" ,
"description" : "1GB SME data" ,
"status" : "successful" ,
"recipient" : "08031112222" ,
"created_at" : "2026-10-15 10:30:00"
}
],
"pagination" : {
"current_page" : 1 ,
"per_page" : 20 ,
"total" : 2 ,
"last_page" : 1 ,
"has_more_pages" : false
}
}
}
Help
Questions about the API, higher limits or going live? Contact us or email support@unitybills.ng . Include the reference of the request you are asking about.