KemDataplus API
Integrate data bundle purchasing directly into your application. Place orders, check balances, and track deliveries programmatically.
The KemDataplus API lets you buy data bundles across all major networks (MTN, Telecel, AirtelTigo) programmatically. All requests use JSON over HTTPS and are authenticated with a Bearer token.
Authentication
All endpoints require an API key in the Authorization header. Generate yours from Profile → Settings.
Wallet-Based
Orders are deducted from your pre-funded wallet balance. Top up your wallet before placing orders. Insufficient balance returns a clear error.
Instant Delivery
Orders are dispatched automatically to providers. Track status per order — PENDING → PROCESSING → COMPLETED.
Base URL
All API requests should be made to: Loading...
All request and response bodies are JSON. Set Content-Type: application/json and Accept: application/json on every request.
Quick Start
Three steps to place your first order.
Fetch available bundles to get a bundleId
curl '/api/bundles?network=MTN'
[
{ "id": "cm3x9a1b2c3d4e5f6", "name": "MTN 5GB", "dataAmount": "5GB", "basePrice": 8.50 },
{ "id": "cm3x9b7c8d9e0f1a2", "name": "MTN 10GB", "dataAmount": "10GB", "basePrice": 15.00 }
]
Place an order using the bundleId and recipient phone
curl --request POST '/api/order-groups' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9' \ --header 'Content-Type: application/json' \ --data '{ "items": [{ "bundleId": "cm3x9a1b2c3d4e5f6", "recipientPhone": "0241234567" }] }'
{
"message": "Order created successfully",
"order": { "orderId": "GRP-000105", "status": "PROCESSING", "totalAmount": 8.50 }
}
Poll the order status until COMPLETED
curl '/api/order-groups/GRP-000105' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"id": "GRP-000105",
"summaryStatus": "COMPLETED",
"items": [{ "recipientPhone": "0241234567", "bundle": "MTN 5GB", "status": "COMPLETED" }]
}
All protected endpoints require an API key in the Authorization header. Generate your key from the Profile → Settings page.
How to authenticate
Generate an API key from your Profile → Settings tab. It never expires — use it on every request without re-authenticating.
Authorization: Bearer kdp_sk_a3f9c8d2...
Keep your API key secret. Revoke or regenerate it anytime from your profile page.
No request body needed. Generates a new key and immediately invalidates the old one (if any). You can also do this from Profile → Settings in the dashboard.
curl --location --request POST '/api/auth/api-key/regenerate' \
--header 'Authorization: Bearer <your-token-or-existing-api-key>'
{
"apiKey": "kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9d3e6f2a1b4c7d9e3f6a2b5c8d1e4f7a"
}
Copy and store this key immediately. For security, the full value is only shown once per generation — but you can always regenerate a new one.
No request body needed. Permanently deletes your current API key. Any integrations using it will stop working immediately.
curl --location --request DELETE '/api/auth/api-key' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"message": "API key revoked successfully."
}
| Field | Type | Required | Description |
|---|---|---|---|
| string | Required | Your account email address | |
| password | string | Required | Your account password |
curl --location '/api/auth/login' \ --header 'Content-Type: application/json' \ --data '{ "email": "you@example.com", "password": "yourpassword" }'
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "usr_abc123",
"name": "Kwame Mensah",
"email": "you@example.com",
"role": "USER"
}
}
{
"error": "Invalid email or password"
}
No request body required. Just include your Authorization header.
curl --location '/api/auth/me' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"id": "usr_abc123",
"name": "Kwame Mensah",
"email": "you@example.com",
"phone": "0241234567",
"role": "USER"
}
Retrieve the available data bundles. Use the bundle ID when placing orders.
No authentication required. Optional query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | string | Optional | Filter by network: MTN, Telecel, AirtelTigo |
| active | boolean | Optional | Set true to return only active bundles |
curl --location '/api/bundles'
[
{
"id": "bundle_abc123",
"name": "MTN 5GB",
"network": "MTN",
"dataAmount": "5GB",
"validity": "1 Day",
"basePrice": 8.50,
"isActive": true,
"outOfStock": false
},
{ /* ... more bundles */ }
]
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | string (path) | Required |
Supported networks: MTN Telecel AirtelTigo |
curl --location '/api/bundles/network/MTN'
[
{
"id": "bundle_abc123",
"name": "MTN 5GB",
"network": "MTN",
"dataAmount": "5GB",
"validity": "1 Day",
"basePrice": 8.50,
"isActive": true
}
]
Place single or bulk data bundle orders. Each order deducts from your wallet and is dispatched to the provider automatically.
| Field | Type | Required | Description |
|---|---|---|---|
| items | array | Required | Array of order items (single or bulk) |
| items[].bundleId | string | Required | Bundle ID from /api/bundles |
| items[].recipientPhone | string | Required | Recipient's phone number (e.g. 0241234567) |
| idempotencyKey | string | Optional | Unique key to prevent duplicate submissions on retry |
curl --location '/api/order-groups' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9' \ --header 'Content-Type: application/json' \ --data '{ "items": [ { "bundleId": "cm3x9a1b2c3d4e5f6", "recipientPhone": "0241234567" } ] }'
curl --location '/api/order-groups' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9' \ --header 'Content-Type: application/json' \ --data '{ "items": [ { "bundleId": "cm3x9a1b2c3d4e5f6", "recipientPhone": "0241234567" }, { "bundleId": "cm3x9b7c8d9e0f1a2", "recipientPhone": "0557654321" } ], "idempotencyKey": "batch-20260715-001" }'
{
"message": "Order created successfully",
"order": {
"orderId": "GRP-000042",
"itemCount": 2,
"isBatch": true,
"totalAmount": 17.00,
"status": "PROCESSING",
"items": [
{
"itemNumber": 1,
"reference": "ORD-000042-01",
"bundle": "MTN 5GB",
"recipientPhone": "0241234567",
"totalPrice": 8.50
}
]
}
}
{
"error": "Insufficient wallet balance",
"code": "INSUFFICIENT_BALANCE",
"required": 17.00,
"available": 5.50
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | Page number (default: 1) |
| limit | integer | Optional | Results per page (default: 20, max: 100) |
curl --location '/api/order-groups?page=1&limit=20' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"orders": [
{
"id": "GRP-000042",
"summaryStatus": "COMPLETED",
"totalAmount": 8.50,
"itemCount": 1,
"createdAt": "2024-07-01T10:22:00.000Z"
}
],
"total": 47,
"page": 1,
"limit": 20
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string (path) | Required | Order group ID (e.g. GRP-000042) |
curl --location '/api/order-groups/GRP-000042' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"id": "GRP-000042",
"summaryStatus": "COMPLETED",
"totalAmount": 8.50,
"createdAt": "2024-07-01T10:22:00.000Z",
"items": [
{
"reference": "ORD-000042-01",
"bundle": "MTN 5GB",
"network": "MTN",
"recipientPhone": "0241234567",
"status": "COMPLETED",
"price": 8.50
}
]
}
Status values: PENDING →
PROCESSING →
COMPLETED /
FAILED /
CANCELLED
Check your balance and view transaction history. Orders are funded from your wallet — make sure it has enough balance before placing orders.
No request body required.
curl --location '/api/wallet/balance' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"balance": 125.50
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | Page number (default: 1) |
| limit | integer | Optional | Results per page (default: 20) |
curl --location '/api/wallet/transactions?page=1&limit=20' \ --header 'Authorization: Bearer kdp_sk_a3f9c8d2e1b47f6a9c3d8e2f1b4a7c9'
{
"transactions": [
{
"id": "txn_xyz789",
"type": "DEBIT",
"amount": 8.50,
"description": "Order GRP-000042",
"balanceAfter": 117.00,
"createdAt": "2024-07-01T10:22:00.000Z"
}
],
"total": 84,
"page": 1
}
All errors return a JSON body with an error message and an optional code field for programmatic handling.
{
"error": "Human-readable message",
"code": "MACHINE_READABLE_CODE"
}
/api/auth/login.required and available amounts.bundleId or recipientPhone in one of the order items.Need help? Contact us at support@kemdataplus.com or visit your dashboard.