Build on DataMobile
Sell data, airtime, cable TV and electricity from your own website, app, POS or bot. Simple JSON over HTTPS, paid from your wallet at your plan's prices.
https://datamobile.com.ng/api/v1.phpQuick start
- Upgrade to API Client. API access comes with that plan.
- Create a key in Dashboard > API Access. Lock it to your server IP.
- Fund your wallet. Every order is paid from your balance.
- Test it: call
?action=balance. You should get"status": "success".
curl -X GET "https://datamobile.com.ng/api/v1.php?action=balance" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
Authentication
Send your key on every request as a Bearer token. You can also use the X-API-Key header.
Authorization: Bearer imk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Responses & errors
Every response is JSON with a status field. Reads return success or error. Purchases return success, pending or failed; errors have a machine-readable code.
{
"status": "error",
"code": "insufficient_balance",
"message": "Insufficient wallet balance. Please fund your wallet."
}
| HTTP | code | Meaning |
|---|---|---|
| 400 | bad_json / no_action | Body is not valid JSON or the action is missing. |
| 401 | no_key / invalid_key | Key missing, wrong or revoked. |
| 402 | insufficient_balance | Fund your wallet and retry. |
| 403 | ip_not_allowed / no_api_access | Request IP not on the key whitelist, or your plan has no API access. |
| 404 | unknown_action / not_found | Wrong action name or the transaction does not exist. |
| 405 | method_not_allowed | Use GET for reads and POST for purchases. |
| 422 | validation_error / request_id_required / network_mismatch | A field is missing or wrong. See message and field. |
| 429 | rate_limited | More than 60 requests per minute. Wait and retry. |
| 503 | service_unavailable / maintenance | Service switched off or maintenance. Retry later. |
request_id & retries
Every purchase needs your own unique request_id (your order ID). If you send the same request_id again, we do not charge you twice. You get the original transaction back with "duplicate": true.
- Save the order in your database before calling us.
- On a timeout, retry with the same request_id. It is always safe.
- Store our
reference. Support will ask for it.
Statuses & webhooks
Delivered. Complete the order. HTTP 200.
Still with the network. HTTP 202. We confirm it automatically; check transaction or wait for the webhook.
Not delivered and refunded to your wallet. Do not charge your customer.
Webhooks
Add a webhook URL to your key. When an order finishes we POST it to you (events transaction.success and transaction.failed), retrying up to 6 times over about 4 hours until you return HTTP 2xx.
{
"event": "transaction.success",
"sent_at": "2026-10-16T09:31:02+01:00",
"data": {
"reference": "IM20261016093012A1B2C3D4",
"request_id": "ORDER_1001",
"service": "data",
"status": "success",
"refunded": false,
"product": "MTN 1GB SME",
"recipient": "08031234567",
"amount": 280,
"face_value": 280,
"message": "Delivered",
"created_at": "2026-10-16T09:30:12+01:00",
"updated_at": "2026-10-16T09:30:16+01:00"
}
}
Check the X-Signature header: HMAC-SHA256 of the raw body with your webhook signing secret (shown on your API page).
$body = file_get_contents("php://input");
$sig = hash_hmac("sha256", $body, "whsec_YOUR_SECRET");
if (!hash_equals($sig, $_SERVER["HTTP_X_SIGNATURE"] ?? "")) {
http_response_code(401); exit;
}
$event = json_decode($body, true);
// update the order with $event["data"]["request_id"], then:
http_response_code(200);
Rate limits
Up to 60 requests per minute per key. Cache plan lists instead of fetching them before every sale. Over the limit you get HTTP 429 with a Retry-After header.
?action=pingTest your key
Checks that your key, IP and plan are valid. Use it when setting up.
curl -X GET "https://datamobile.com.ng/api/v1.php?action=ping" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=ping");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=ping", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"message": "Your API key works.",
"data": {
"key": "imk_Ab12Cd34...",
"label": "My website",
"tier": "API Client",
"ip": "102.89.0.10"
}
} ?action=balanceWallet balance
Your main wallet balance. Every API purchase is paid from it.
curl -X GET "https://datamobile.com.ng/api/v1.php?action=balance" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=balance");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=balance", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"message": "OK",
"data": {
"balance": 25000,
"bonus_balance": 120,
"currency": "NGN",
"tier": "API Client"
}
} ?action=networksNetworks
Network codes, airtime limits and your airtime discount.
curl -X GET "https://datamobile.com.ng/api/v1.php?action=networks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=networks");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=networks", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"data": [
{
"id": 1,
"code": "mtn",
"name": "MTN",
"airtime": true,
"data": true,
"airtime_min": 50,
"airtime_max": 50000,
"airtime_discount": {
"type": "percent",
"value": 3
}
}
]
} ?action=data-plansData plans
Every active plan with its ID and YOUR price. Optional filters: network (mtn, airtel, glo, 9mobile) and type (SME, GIFTING, CORPORATE...). Cache it and refresh every 30 minutes.
| Field | Type | Required | Description |
|---|---|---|---|
network | string | No | mtn, airtel, glo or 9mobile |
type | string | No | SME, GIFTING, CORPORATE, AWOOF... |
curl -X GET "https://datamobile.com.ng/api/v1.php?action=data-plans" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=data-plans");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=data-plans", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"count": 1,
"data": [
{
"id": 12,
"network": "mtn",
"network_name": "MTN",
"type": "SME",
"type_label": "SME",
"name": "MTN 1GB SME",
"size_mb": 1024,
"validity": "30 Days",
"price": 280
}
]
} Example IDs right now (prices shown are public prices, yours depend on your plan):
| plan_id | Network | Plan | Price |
|---|---|---|---|
1 | MTN | MTN 500MB | ₦281.00 |
2 | MTN | MTN 1GB | ₦481.00 |
3 | MTN | MTN 1GB Pro | ₦605.00 |
4 | MTN | MTN 2GB | ₦929.00 |
46 | MTN | MTN 2GB premium | ₦983.00 |
6 | MTN | MTN 3GB | ₦1,631.00 |
?action=cable-plansCable bouquets
DStv, GOtv and StarTimes bouquets with IDs and your price. Optional filter provider.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | No | dstv, gotv or startimes |
curl -X GET "https://datamobile.com.ng/api/v1.php?action=cable-plans" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=cable-plans");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=cable-plans", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"count": 1,
"convenience_fee": {
"type": "flat",
"value": 0
},
"data": [
{
"id": 31,
"provider": "gotv",
"provider_name": "GOtv",
"name": "GOtv Max",
"validity": "1 Month",
"price": 8500
}
]
} ?action=discosElectricity companies
DISCO codes, minimum / maximum amount and your fee.
curl -X GET "https://datamobile.com.ng/api/v1.php?action=discos" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=discos");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=discos", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"data": [
{
"id": 3,
"code": "ikeja",
"name": "Ikeja Electric",
"min_amount": 1000,
"max_amount": 200000,
"fee": {
"type": "flat",
"value": 0
}
}
]
} ?action=dataBuy data
Sends a data bundle. The plan decides the network.
| Field | Type | Required | Description |
|---|---|---|---|
plan_id | integer | Yes | ID from data-plans |
phone | string | Yes | 11-digit number, e.g. 08031234567 |
request_id | string | Yes | Your unique order ID (6-80 chars) |
network | string | No | If sent, must match the plan (safety check) |
curl -X POST "https://datamobile.com.ng/api/v1.php?action=data" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"plan_id":12,"phone":"08031234567","request_id":"ORDER_1001"}'
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=data");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => '{"plan_id":12,"phone":"08031234567","request_id":"ORDER_1001"}',
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=data", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({"plan_id":12,"phone":"08031234567","request_id":"ORDER_1001"})
});
const data = await res.json();
{
"status": "success",
"message": "Transaction successful",
"duplicate": false,
"balance": 18450,
"data": {
"reference": "IM20261016093012A1B2C3D4",
"request_id": "ORDER_1001",
"service": "data",
"status": "success",
"refunded": false,
"product": "MTN 1GB SME",
"recipient": "08031234567",
"amount": 280,
"face_value": 280,
"message": "Delivered",
"created_at": "2026-10-16T09:30:12+01:00",
"updated_at": "2026-10-16T09:30:16+01:00"
}
} ?action=airtimeBuy airtime
Tops up any number. Your discount is applied automatically.
| Field | Type | Required | Description |
|---|---|---|---|
network | string | Yes | mtn, airtel, glo or 9mobile |
phone | string | Yes | 11-digit number |
amount | integer | Yes | Whole naira, within the network limits |
request_id | string | Yes | Your unique order ID |
curl -X POST "https://datamobile.com.ng/api/v1.php?action=airtime" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"network":"mtn","phone":"08031234567","amount":500,"request_id":"ORDER_1002"}'
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=airtime");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => '{"network":"mtn","phone":"08031234567","amount":500,"request_id":"ORDER_1002"}',
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=airtime", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({"network":"mtn","phone":"08031234567","amount":500,"request_id":"ORDER_1002"})
});
const data = await res.json();
?action=cablePay cable TV
Renews a DStv, GOtv or StarTimes decoder. Always confirm the IUC number with your customer.
| Field | Type | Required | Description |
|---|---|---|---|
plan_id | integer | Yes | ID from cable-plans |
iuc_number | string | Yes | Smartcard / IUC number |
request_id | string | Yes | Your unique order ID |
curl -X POST "https://datamobile.com.ng/api/v1.php?action=cable" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"plan_id":31,"iuc_number":"7012345678","request_id":"ORDER_1003"}'
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=cable");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => '{"plan_id":31,"iuc_number":"7012345678","request_id":"ORDER_1003"}',
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=cable", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({"plan_id":31,"iuc_number":"7012345678","request_id":"ORDER_1003"})
});
const data = await res.json();
?action=electricityPay electricity
Prepaid token or postpaid bill. For prepaid, the token is in data.token.
| Field | Type | Required | Description |
|---|---|---|---|
disco | string | Yes | Code from discos, e.g. ikeja |
meter_number | string | Yes | Customer meter number |
meter_type | string | No | prepaid (default) or postpaid |
amount | integer | Yes | Whole naira |
request_id | string | Yes | Your unique order ID |
curl -X POST "https://datamobile.com.ng/api/v1.php?action=electricity" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"disco":"ikeja","meter_number":"45012345678","meter_type":"prepaid","amount":2000,"request_id":"ORDER_1004"}'
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=electricity");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => '{"disco":"ikeja","meter_number":"45012345678","meter_type":"prepaid","amount":2000,"request_id":"ORDER_1004"}',
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=electricity", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({"disco":"ikeja","meter_number":"45012345678","meter_type":"prepaid","amount":2000,"request_id":"ORDER_1004"})
});
const data = await res.json();
{
"status": "success",
"message": "Transaction successful",
"data": {
"reference": "IM2026...",
"service": "electricity",
"status": "success",
"token": "1234-5678-9012-3456-7890",
"units": "28.4 kWh"
}
} ?action=transactionTransaction status
Look up one order by our reference or your request_id. Use it for pending orders.
| Field | Type | Required | Description |
|---|---|---|---|
reference | string | One of | Our reference |
request_id | string | One of | Your request_id |
curl -X GET "https://datamobile.com.ng/api/v1.php?action=transaction" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=transaction");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=transaction", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"data": {
"reference": "IM20261016093012A1B2C3D4",
"request_id": "ORDER_1001",
"service": "data",
"status": "success",
"refunded": false,
"product": "MTN 1GB SME",
"recipient": "08031234567",
"amount": 280,
"face_value": 280,
"message": "Delivered",
"created_at": "2026-10-16T09:30:12+01:00",
"updated_at": "2026-10-16T09:30:16+01:00"
}
} ?action=transactionsTransaction history
Your latest orders, newest first.
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | success, pending or failed |
service | string | No | data, airtime, cable, electricity |
from / to | date | No | YYYY-MM-DD |
limit | integer | No | 1-100 (default 50) |
page | integer | No | Page number |
curl -X GET "https://datamobile.com.ng/api/v1.php?action=transactions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json"
$ch = curl_init("https://datamobile.com.ng/api/v1.php?action=transactions");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
const res = await fetch("https://datamobile.com.ng/api/v1.php?action=transactions", {
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
});
const data = await res.json();
{
"status": "success",
"page": 1,
"limit": 50,
"total": 1,
"data": [
{
"reference": "IM20261016093012A1B2C3D4",
"request_id": "ORDER_1001",
"service": "data",
"status": "success",
"refunded": false,
"product": "MTN 1GB SME",
"recipient": "08031234567",
"amount": 280,
"face_value": 280,
"message": "Delivered",
"created_at": "2026-10-16T09:30:12+01:00",
"updated_at": "2026-10-16T09:30:16+01:00"
}
]
}