Send Airtime
Create a new airtime top-up transaction that deducts from your pre-funded wallet.
Send Airtime
Create a new airtime top-up. The amount is deducted from your pre-funded wallet and delivered to the recipient's phone number.
POST /v2/topups
Permission required: airtime.write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
phone_number | string | Yes | Recipient phone number in E.164 format |
network_id | integer | Yes | Network ID from catalog lookup |
amount | object | Conditional | Custom amount (required if no product_id) |
amount.value | number | Yes | Amount in local currency |
amount.currency | string | Yes | Local currency code (e.g., GHS) |
product_id | string | Conditional | Bundle/product ID (required if no amount) |
sms | object | No | SMS notification settings |
sms.enabled | boolean | No | Send SMS to recipient (default: false) |
sms.message | string | No | Custom SMS message |
reference | string | No | Your reference for this transaction |
callback_url | string | No | URL for status webhook notifications |
metadata | object | No | Custom key-value pairs stored with the transaction |
You must provide either amount (for custom airtime) or product_id (for a fixed bundle). Not both.
Example: Custom Amount
curl -X POST "https://api.clickairtime.com/v2/topups" \
-H "Authorization: Bearer ce_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+233541112259",
"network_id": 42,
"amount": {
"value": 50,
"currency": "GHS"
},
"sms": {
"enabled": true,
"message": "Airtime top-up from Acme Corp"
},
"reference": "invoice-12345",
"metadata": {
"customer_id": "cust_001",
"department": "sales"
}
}'const response = await fetch('https://api.clickairtime.com/v2/topups', {
method: 'POST',
headers: {
'Authorization': 'Bearer ce_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
phone_number: '+233541112259',
network_id: 42,
amount: { value: 50, currency: 'GHS' },
sms: { enabled: true, message: 'Airtime top-up from Acme Corp' },
reference: 'invoice-12345',
metadata: { customer_id: 'cust_001', department: 'sales' },
}),
});
const data = await response.json();import requests
response = requests.post(
'https://api.clickairtime.com/v2/topups',
headers={
'Authorization': 'Bearer ce_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
json={
'phone_number': '+233541112259',
'network_id': 42,
'amount': {'value': 50, 'currency': 'GHS'},
'sms': {'enabled': True, 'message': 'Airtime top-up from Acme Corp'},
'reference': 'invoice-12345',
'metadata': {'customer_id': 'cust_001', 'department': 'sales'},
}
)
data = response.json()$ch = curl_init('https://api.clickairtime.com/v2/topups');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ce_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'phone_number' => '+233541112259',
'network_id' => 42,
'amount' => ['value' => 50, 'currency' => 'GHS'],
'sms' => ['enabled' => true, 'message' => 'Airtime top-up from Acme Corp'],
'reference' => 'invoice-12345',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch));Example Response (201 Created)
{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"phone_number": "+233541112259",
"network": {
"id": 42,
"name": "MTN Ghana",
"country": "Ghana",
"country_code": "GH"
},
"amount": {
"value": 50,
"currency": "GHS"
},
"cost": {
"value": 4.05,
"currency": "USD"
},
"product_id": null,
"product_name": null,
"sms": {
"enabled": true,
"message": "Airtime top-up from Acme Corp"
},
"reference": "invoice-12345",
"provider_reference": "DT-123456789",
"failure_reason": null,
"metadata": {
"customer_id": "cust_001",
"department": "sales"
},
"created_at": "2024-01-15T10:30:00.000Z",
"completed_at": "2024-01-15T10:30:02.500Z"
},
"meta": {
"request_id": "req_a1b2c3d4e5f6",
"timestamp": "2024-01-15T10:30:02.500Z"
}
}
Transaction Statuses
| Status | Description |
|---|---|
pending | Transaction created, awaiting processing |
processing | Airtime delivery in progress |
completed | Successfully delivered |
failed | Delivery failed (check failure_reason) |
Example: Fixed Bundle
curl -X POST "https://api.clickairtime.com/v2/topups" \
-H "Authorization: Bearer ce_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+233541112259",
"network_id": 42,
"product_id": "pkg_500mb_30d"
}'
Duplicate prevention is handled automatically. If you submit the same phone_number, network_id, and amount within a short time window, the API will return the existing transaction instead of creating a duplicate.
