Quick Start
Get started with Bundle Zone API in 3 simple steps:
- Get Your API Key Navigate to your Bundle Zone dashboard → Profile → API tab and copy your unique API key
- Make Your First Request Use the code examples below to send your first data bundle
- Monitor Your Usage Track your transactions and wallet balance in real-time
Authentication
Every API request must include your API key in the x-api-key header:
x-api-key: bh_live_your_api_key_here
bh_live_ and should be kept confidential.
Base URL
All API endpoints use this base URL:
API Endpoints
All requests are sent as POST with a JSON body specifying the action.
POST Place Order
Purchase and send a data bundle to a recipient.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
String | Required | Must be "place_order" |
network |
String | Required | mtn, telecel, or ishare |
recipient |
String | Required | 10-digit phone (e.g., 0244123456) |
package_size |
Number | Required | Bundle size in GB (e.g., 1, 5, 10) |
order_id |
String | Optional | Your unique reference (auto-generated if omitted) |
const response = await fetch('https://bundlezonegh.com/api/v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'bh_live_your_api_key_here'
},
body: JSON.stringify({
action: 'place_order',
network: 'mtn',
recipient: '0244123456',
package_size: 5,
order_id: 'order-12345' // Optional
})
});
const data = await response.json();
console.log(data);
curl -X POST https://bundlezonegh.com/api/v1 \
-H "Content-Type: application/json" \
-H "x-api-key: bh_live_your_api_key_here" \
-d '{
"action": "place_order",
"network": "mtn",
"recipient": "0244123456",
"package_size": 5,
"order_id": "order-12345"
}'
import requests
url = "https://bundlezonegh.com/api/v1"
headers = {
"Content-Type": "application/json",
"x-api-key": "bh_live_your_api_key_here"
}
data = {
"action": "place_order",
"network": "mtn",
"recipient": "0244123456",
"package_size": 5,
"order_id": "order-12345"
}
response = requests.post(url, json=data, headers=headers)
print(response.json())
Success Response (200 OK)
{
"success": true,
"message": "Order placed successfully",
"data": {
"order_id": "API_1702404123_abc",
"transaction_id": 12345,
"reference": "BZ_REF_123",
"network": "mtn",
"recipient": "0244123456",
"package_size": 5,
"bundle": "5GB",
"validity": "30 Days",
"amount": 22.50,
"status": "processing",
"new_balance": 477.50,
"timestamp": "2025-12-12T22:51:00Z"
}
}
POST Check Balance
Retrieve your current wallet balance.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
String | Required | Must be "check_balance" |
Example Request
const response = await fetch('https://bundlezonegh.com/api/v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'bh_live_your_api_key_here'
},
body: JSON.stringify({ action: 'check_balance' })
});
const data = await response.json();
console.log(data);
Success Response
{
"success": true,
"data": {
"wallet_balance": 500.00,
"currency": "GHS",
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}
}
POST Get Available Bundles
Fetch all available bundles with your custom pricing applied.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
String | Required | Must be "get_bundles" |
network |
String | Optional | Filter: mtn, telecel, or airteltigo |
Example Request
const response = await fetch('https://bundlezonegh.com/api/v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'bh_live_your_api_key_here'
},
body: JSON.stringify({
action: 'get_bundles',
network: 'mtn' // Optional filter
})
});
Success Response
{
"success": true,
"data": {
"bundles": [
{
"id": 1,
"network": "mtn",
"size": "1GB",
"size_gb": 1,
"price": 4.50,
"validity": "30 Days",
"has_custom_price": true
},
{
"id": 2,
"network": "mtn",
"size": "5GB",
"size_gb": 5,
"price": 22.50,
"validity": "30 Days",
"has_custom_price": false
}
],
"count": 2
}
}
POST Get Transaction History
Retrieve your recent transactions with pagination support.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
String | Required | Must be "get_transactions" |
limit |
Number | Optional | Records per page (default: 10) |
offset |
Number | Optional | Page offset (default: 0) |
Example Request
const response = await fetch('https://bundlezonegh.com/api/v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'bh_live_your_api_key_here'
},
body: JSON.stringify({
action: 'get_transactions',
limit: 10,
offset: 0
})
});
Success Response
{
"success": true,
"data": {
"transactions": [
{
"id": 123,
"type": "purchase",
"amount": 22.50,
"status": "completed",
"description": "MTN 5GB",
"created_at": "2025-12-12T22:51:00Z"
}
],
"count": 1,
"total": 25
}
}
Error Handling
All errors return JSON with success: false and descriptive error messages.
401 Unauthorized - Invalid API Key
{
"success": false,
"error": "Invalid API key",
"message": "Authentication failed. Please provide a valid API key.",
"code": 401
}
400 Bad Request - Insufficient Balance
{
"success": false,
"error": "Insufficient balance",
"message": "Required: GH₵ 22.50, Available: GH₵ 10.00"
}
400 Bad Request - Invalid Phone Number
{
"success": false,
"error": "Invalid phone number",
"message": "Phone number must be 10 digits starting with 0 (e.g., 0241234567)"
}
503 Service Unavailable - Platform Closed
Returned by place_order when Bundle Zone is closed and not accepting new orders. No balance is reserved and no order is created. When a reopening time is scheduled it is given in reopens_at, and the same interval is sent as a Retry-After header in seconds. Read-only actions such as check_status, check_balance and get_transactions keep working while closed, so you can still reconcile orders you already placed.
{
"success": false,
"error": "Service closed",
"code": "SITE_CLOSED",
"message": "Bundle Zone is temporarily closed and is not accepting new orders. Please try again later.",
"reopens_at": "2026-08-24T06:00:00.000Z",
"retry_after": 28800
}
400 Bad Request - Bundle Not Found
{
"success": false,
"error": "Bundle not found",
"message": "No active bundle found for mtn with size 999GB"
}
Best Practices
Never expose keys in client-side code or repositories
Always check response status and catch errors gracefully
Check wallet balance before placing large orders
Validate phone numbers and bundle sizes before sending
Need Help?
If you encounter any issues or have questions:
- Verify your API key is correct and starts with
bh_live_ - Ensure your wallet has sufficient balance
- Check phone numbers are 10 digits starting with 0
- Review error messages for specific details
- Contact support through your Bundle Zone dashboard
Join our community
support@bundlezonegh.com
Common questions
