Data¶
Activate mobile data bundles from the live plan catalogue.
Buy data¶
Auth: API key (live or test) or session.
curl -X POST https://api.instapaybill.com/api/v1/data/buy \
-H "Authorization: Bearer $IPB_LIVE_KEY" \
-H "Content-Type: application/json" \
-H "User-Agent: my-integration/1.0" \
-d '{
"phone": "08012345678",
"planId": "MTN-1.5GB-30D",
"network": "MTN",
"apiRefId": "order-1002"
}'
Request body¶
| Field | Type | Required | Description |
|---|---|---|---|
phone |
string | ✅ | Nigerian mobile number (en-NG). |
planId |
string | ✅ | Provider plan identifier. See catalogue. |
network |
string | ✅ | Network the plan belongs to. Required in practice — the plan lookup is { planId, network }. |
apiRefId |
string | — | Your order reference. API-channel only. |
pin |
string | — | Wallet PIN. Ignored for API-key requests. |
promoCode / coupon |
string | — | Not applied for API-channel requests. |
network is not optional in practice
There is no validator for network on this route, but the plan is looked
up with DataPlanModel.findOne({ planId, network: network?.toUpperCase() }).
A missing network produces a "Plan Id not found" error that looks like
a bad plan id. Always send it.
Success response — 200¶
{
"msg": "MTN Data Purchase of ₦500 for 08012345678 | 30Days 5GB was successful",
"data": {
"code": 200,
"reference": "IP|TN|D|124|20260918120000_ASDFG",
"msg": "Data purchase successful",
"message": "Data bundle activated on 08012345678",
"description": "MTN Data Purchase of ₦500 for 08012345678 | 30Days 5GB",
"type": "data"
},
"code": 200
}
Pending — 300¶
{
"code": 300,
"reference": "IP|TN|D|124|20260918120000_ASDFG",
"error": [
{
"path": "data-merrybills",
"msg": "Your purchase is being verified with the provider. We will confirm delivery shortly."
}
]
}
Failure — 400¶
{
"code": 400,
"reference": "IP|TN|D|124|20260918120000_ASDFG",
"error": [
{
"path": "data-merrybills",
"msg": "Plan not available for selected network"
}
]
}
One internal code is normalised
The provider layer can return an internal retry code of 301. The API
always reports that as 300 to you, so a 300 in the response means
"pending" in every case.
Guards¶
Identical to airtime, with the plan-specific additions:
| Check | Rejects when | Response |
|---|---|---|
| Plan exists | No plan matches { planId, network } |
300, "Plan Id not found" |
| Biller not retired | The plan's biller was decommissioned | 300 + hold: true |
| Category enabled | The plan's category is off | 300 |
| Phone/network match | The number's carrier differs from the plan's network | 300 |
| Bucket wallet | The plan routes to a bucket-wallet SKU | routed, not rejected |
Agent data catalogue¶
The single most useful endpoint for building a plan picker. It returns the data plans and the cable plans in one call.
curl https://api.instapaybill.com/api/v1/data/agent-data \
-H "Authorization: Bearer $IPB_LIVE_KEY" \
-H "User-Agent: my-integration/1.0"
{
"msg": "Agent data retrieved successfully",
"data": {
"data": [ /* data plans */ ],
"cables": { /* cable plans */ }
}
}
A data plan entry carries the fields you need to render and buy:
{
"planId": "MTN-1.5GB-30D",
"network": "MTN",
"price": 500,
"provider_price": 480,
"validity": "30Days",
"size": "1.5GB",
"category": "<categoryId>",
"biller": "<billerId>"
}
Use planId + network + price for the buy call. provider_price is the
platform's cost — do not send it.
Available networks¶
{
"success": true,
"msg": "Available networks retrieved successfully",
"data": {
"networks": ["AIRTEL", "GLO", "MTN", "T2MOBILE"],
"count": 4
}
}
Derived from data plans that are enabler: 'enable' and available: true.
Note the success key — this endpoint uses a slightly different envelope from
the purchase endpoints.
Plans for one network¶
curl https://api.instapaybill.com/api/v1/data/networks/MTN/plans \
-H "Authorization: Bearer $IPB_LIVE_KEY" \
-H "User-Agent: my-integration/1.0"
Returns the active plans for one network. Cheaper than fetching the whole catalogue when you only need one network.
Data plans¶
curl "https://api.instapaybill.com/api/v1/data/?category=<categoryId>&planId=<planId>" \
-H "Authorization: Bearer $IPB_LIVE_KEY" \
-H "User-Agent: my-integration/1.0"
Both query parameters are optional filters. The full list is large — prefer
/agent-data or
/networks/{network}/plans for a UI.
Related¶
- Airtime — same envelope, simpler body
- Catalogue — networks, categories, providers
- Transactions — resolving a data purchase