Quick start
This documentation is public. To call the API you need a Bundle Wasp account.
Authentication
Every request must include your API key in the Authorization header as a Bearer token. Keys start with dhk_.
Authorization: Bearer dhk_your_api_key_hereRequests and responses use JSON. Send Content-Type: application/json with request bodies.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /bundles | List active data bundles and prices |
| GET | /bundles/{id} | Get one bundle |
| GET | /networks | List available networks |
| POST | /orders | Place a data bundle order |
| GET | /orders | List your orders (paginated) |
| GET | /orders/{id} | Get one order and its status |
| GET | /balance | Get your wallet balance |
Returns every active bundle with its price in Ghana cedis (GHS). Use the id when placing an order.
{
"success": true,
"data": [
{ "id": 1, "network": "MTN", "type": "Daily", "size": "1GB", "price": 5.00 },
{ "id": 2, "network": "Telecel", "type": "Weekly", "size": "5GB", "price": 20.00 }
],
"total": 2
}Returns one bundle, including whether it can currently be ordered (active).
{
"success": true,
"data": { "id": 1, "network": "MTN", "type": "Daily", "size": "1GB", "price": 5.00, "active": true }
}Returns 404 with "error": "Bundle not found" for an unknown id.
Returns the networks you can currently buy bundles for.
{
"success": true,
"data": [
{ "id": 1, "name": "MTN", "code": "mtn" },
{ "id": 3, "name": "AirtelTigo", "code": "airteltigo" },
{ "id": 4, "name": "Telecel", "code": "telecel" }
]
}Places an order for one bundle to one phone number. The bundle's price is taken from your wallet when the order is accepted.
| Field | Type | Description |
|---|---|---|
bundleId | integer | Required. The bundle id from GET /bundles. |
phone | string | Required. The number to receive the data: 0XXXXXXXXX, 233XXXXXXXXX or +233XXXXXXXXX. |
{ "bundleId": 1, "phone": "0241234567" }{
"success": true,
"data": {
"orderId": 42,
"reference": "API-1709901234567-abc123",
"bundle": { "id": 1, "network": "MTN", "type": "Daily", "size": "1GB", "price": 5.00 },
"phone": "0241234567",
"amount": 5.00,
"status": "pending",
"message": "Order placed successfully. Data bundle will be delivered shortly."
}
}Save the orderId and use GET /orders/{id} to follow delivery. If your balance is too low you get 402 and nothing is charged.
Returns your orders, newest first. limit defaults to 20 (maximum 100).
{
"success": true,
"orders": [
{
"orderId": 42,
"reference": "API-1709901234567-abc123",
"phone": "0241234567",
"amount": 5.00,
"status": "completed",
"bundle": { "network": "MTN", "type": "Daily", "size": "1GB" },
"createdAt": "2026-09-27T10:15:00.000+00:00"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}Returns one of your orders with its current status.
{
"success": true,
"data": {
"orderId": 42,
"reference": "API-1709901234567-abc123",
"phone": "0241234567",
"amount": 5.00,
"status": "completed",
"bundle": { "network": "MTN", "type": "Daily", "size": "1GB" },
"createdAt": "2026-09-27T10:15:00.000+00:00",
"updatedAt": "2026-09-27T10:17:42.000+00:00"
}
}Returns your current wallet balance.
{
"success": true,
"data": { "balance": 95.00, "currency": "GHS" }
}Order status
An order's status follows the data provider's own delivery status. An accepted order is pending until the bundle is actually delivered.
| Status | Meaning |
|---|---|
pending | Order received and paid; waiting to be delivered. |
processing | The network is delivering the bundle. |
completed | The bundle has been delivered to the phone number. |
failed | The bundle could not be delivered. Contact support if you were charged. |
cancelled | The order was cancelled and refunded to your wallet. |
refunded | The order's amount was returned to your wallet. |
Most bundles are delivered within minutes. To follow an order, check GET /orders/{id} about once a minute until it is completed, failed, cancelled or refunded.
Errors
Errors use standard HTTP status codes and always return a JSON body:
{ "success": false, "error": "Invalid or inactive API key" }| Code | When it happens |
|---|---|
400 | Missing bundleId or phone, or the phone number format is invalid. |
401 | The Authorization header is missing, or the API key is wrong or revoked. |
402 | Your wallet balance is too low for this order. |
403 | Your account is suspended or not yet approved. |
404 | The bundle or order doesn't exist (or isn't yours). |
500 | Something went wrong on our side. Try again shortly. |
Code examples
Placing an order. Replace dhk_your_api_key_here with your key and run the code on your server.
curl -X POST https://bundlewasp.com/api/v1/orders \
-H "Authorization: Bearer dhk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"bundleId": 1, "phone": "0241234567"}'const res = await fetch('https://bundlewasp.com/api/v1/orders', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BUNDLEWASP_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ bundleId: 1, phone: '0241234567' }),
});
const result = await res.json();
if (!result.success) throw new Error(result.error);
console.log('Order', result.data.orderId, result.data.status);<?php
$ch = curl_init('https://bundlewasp.com/api/v1/orders');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('BUNDLEWASP_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['bundleId' => 1, 'phone' => '0241234567']),
]);
$result = json_decode(curl_exec($ch), true);
if (empty($result['success'])) {
throw new Exception($result['error'] ?? 'Request failed');
}
echo 'Order ' . $result['data']['orderId'] . ' is ' . $result['data']['status'];import os
import requests
res = requests.post(
"https://bundlewasp.com/api/v1/orders",
headers={"Authorization": f"Bearer {os.environ['BUNDLEWASP_API_KEY']}"},
json={"bundleId": 1, "phone": "0241234567"},
timeout=30,
)
result = res.json()
if not result.get("success"):
raise RuntimeError(result.get("error"))
print("Order", result["data"]["orderId"], result["data"]["status"])FAQ
Do I need an account to use the API?
You can read this documentation without an account. To make API calls you need an approved Bundle Wasp account and an API key, which you create in your dashboard under API.
How are orders paid for?
Each order is paid from your Bundle Wasp wallet at the bundle's listed price. Top up your wallet in the dashboard before placing orders, and check it any time with GET /balance.
Which networks are supported?
The networks returned by GET /networks, currently MTN, Telecel and AirtelTigo in Ghana.
What if an order fails?
Its status becomes failed. Contact support with the order's reference and we'll retry it or refund your wallet.
Can I have more than one API key?
Yes. Create a separate key for each app or website so you can revoke one without affecting the others.
Create a free account, then generate your API key in the dashboard.