API Documentation
Welcome to iRecharge Pro API documentation. This guide will help you integrate mobile recharge and billing services into your application.
All API endpoints require authentication using API credentials (Open Key + Secret Key).
Sandbox Environment
Use for testing and development. Keys start with ok_test_* and sk_test_*
• Simulated transactions • No real charges • Perfect for integration testing
Production Environment
Use for live transactions. Keys start with ok_live_* and sk_live_*
• Real transactions • Actual charges • Production-ready
Authentication
All API requests must include your API credentials in the headers. You need both an Open Key and a Secret Key:
Required Headers
ok_test_XXXXXXXXXXXXXXXXXXXXXXXX
Your public API key (visible, used for routing)
sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Your secret API key (keep this secure, used for authentication)
curl -X GET https://pro.irecharge.net/api/billing/balance \
-H "X-Open-Key: ok_test_YOUR_OPEN_KEY" \
-H "X-Authorization: sk_test_YOUR_SECRET_KEY"
IP Whitelist (Optional)
For enhanced security, you can restrict API access to specific IP addresses or CIDR ranges from your Developer Dashboard.
• Add single IPs: 192.168.1.1
• Add CIDR ranges: 10.0.0.0/24
• Leave empty to allow all IPs
You can obtain your API credentials from the Developer Dashboard after signing up.
Base URL
All API endpoints use the following base URL:
https://pro.irecharge.net/api/billing
Note: The same API credentials work for both sandbox and production environments. The system automatically detects your environment based on your API key prefix (ok_test_* = Sandbox, ok_live_* = Production).
API Endpoints
Check Balance
Get your current wallet balance.
/api/billing/wallet/balance
curl --location 'https://pro.irecharge.net/api/billing/wallet/balance' \
--header 'X-Open-Key: ok_test_YOUR_OPEN_KEY' \
--header 'X-Authorization: sk_test_YOUR_SECRET_KEY'
Response (200 OK):
{
"balance": "7000.00",
"currency": "BDT"
}
Get Available Operators
Retrieve a list of available mobile operators and services.
/api/billing/operators
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
country |
No | Filter by country name or shortcut, for example Bangladesh or bd. |
service |
No | Filter by service slug, for example mobile-recharge or mobile-banking. |
search or q |
No | Search by operator name or code, for example robi or GP. |
curl --location 'https://pro.irecharge.net/api/billing/operators?country=bd&service=mobile-recharge&search=robi' \
--header 'X-Open-Key: ok_test_YOUR_OPEN_KEY' \
--header 'X-Authorization: sk_test_YOUR_SECRET_KEY'
Response (200 OK):
[
{
"id": 1,
"country": "Bangladesh",
"service": "Mobile Recharge",
"operator_code": "GP",
"operator_name": "Grameenphone",
"logo": "https://pro.irecharge.net/operator_logo/grameenphone.png"
},
{
"id": 2,
"country": "Bangladesh",
"service": "Mobile Recharge",
"operator_code": "BL",
"operator_name": "Banglalink",
"logo": "https://pro.irecharge.net/operator_logo/banglalink.png"
},
{
"id": 3,
"country": "Bangladesh",
"service": "Mobile Recharge",
"operator_code": "RB",
"operator_name": "Robi",
"logo": "https://pro.irecharge.net/operator_logo/robi.png"
}
// ... more operators
]
Normal Recharge
Submit a standard mobile recharge request with a specific amount.
number means the customer's mobile number. If you provide webhook_url, iRecharge will send transaction callbacks to that URL using HTTP POST with a JSON body.
/api/billing/service-requests/recharge/normal
Important: The reference field is required and must be unique. Duplicate references will be rejected.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
operator |
string | Yes | Operator code: gp, rb, at, bl, tt, sk |
number |
string | Yes | Customer mobile number / phone number, for example 01712345678. |
amount |
number | Yes | Recharge amount |
service_type |
string | No | Service type: prepaid or postpaid |
reference |
string | Yes | Unique reference ID (also accepts client_reference, clientReference) |
webhook_url |
string | No | Your callback URL for transaction updates. iRecharge sends the webhook to this URL with HTTP POST and a JSON payload. recharge_webhook_url is also supported. |
{
"number": "01712345678",
"amount": 10,
"operator": "gp",
"service_type": "prepaid",
"webhook_url": "https://your-domain.com/webhooks/recharge",
"reference": "BILL-026401"
}
curl -X POST https://pro.irecharge.net/api/billing/service-requests/recharge/normal \
-H "X-Open-Key: ok_test_YOUR_OPEN_KEY" \
-H "X-Authorization: sk_test_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"number": "01712345678",
"amount": 10,
"operator": "gp",
"service_type": "prepaid",
"webhook_url": "https://your-domain.com/webhooks/recharge",
"reference": "BILL-026401"
}'
Response (200 OK):
{
"success": true,
"message": "Recharge processed successfully",
"billing": {
"reference": "BILL-026401",
"status": "success",
"rechargeType": "normal",
"number": "01712345678",
"amount": 10,
"fee": 0.5,
"commission": 1.5,
"remainingBalance": 6989.5
}
}
Response Field Description:
| Field | Type | Description |
|---|---|---|
success |
boolean | Indicates whether the API request was accepted successfully. |
message |
string | Human-readable result message. |
billing.reference |
string | Your unique request reference. |
billing.status |
string | Current transaction state. Possible values: success, processing, pending, failed, approved, rejected, reversed. |
billing.rechargeType |
string | normal or offer. |
billing.number |
string | Customer mobile number. |
billing.amount |
number | Recharge amount. |
billing.fee |
number | Service fee charged for this request. |
billing.commission |
number | Commission amount for this request. |
billing.remainingBalance |
number | Current wallet balance after this request is submitted. |
Sandbox Mode: If using sandbox credentials (ok_test_*), transactions will be simulated with random success/failure responses for testing purposes.
Offer Recharge
Fetch offers, purchase the selected one, then verify the final status. This section is structured in the same order your integration usually happens.
Step 1
Get offers
GET /api/billing/recharge/offers
Step 2
Purchase selected offer
POST /api/billing/recharge/offers/purchase
Step 3
Check final status
GET/POST /api/billing/transactions/status/check
Quick Flow
- Call
GET /api/billing/recharge/offerswith query params likenumber=01614031175andoperator=airtel. - Show the returned
offers[]list in your app. - When the customer selects an offer, build the purchase payload from that offer's flat fields and send it to
POST /api/billing/recharge/offers/purchase. - Add your own unique
referencebefore posting, so you can check status later.
Step 1. Get Available Offers
/api/billing/recharge/offers
Interactive Offer Explorer
Pick an operator, inspect the offer response, then copy the matching purchase request.
No operator found for this filter.
Selected operator
Banglalink
Bangladesh / banglalink
Request parameters
Offer search uses GET, so there is no request body.
Request
Response
Purchase cURL request for selected offer
/api/billing/recharge/offers/purchase
Important: The billing API requires a unique reference or client_reference. Always send the selected offer's operator in the purchase request, because phone prefix is not reliable after mobile number portability.
Banglalink
Required identifiers: offer_id, tran_id
Request Body
cURL
Response
Validation Error
GET Offer Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
number |
string | Yes | Customer mobile number. Bangladesh format, for example 01712345678. |
operator |
string | Yes | Operator code for offer lookup. Supported: gp, robi/rb, airtel/at, banglalink/bl. |
operator_code or operator_short |
string | No | Aliases for operator. |
Best integration rule: Use title, amount, validity, category, and commission for display. For purchase, always send operator together with the returned fields needed for that operator. Robi/Airtel can use operator, number, amount, and ticketId. Banglalink can use operator, number, amount, offerId, and tranId. Add reference and optional webhook URL for the billing API.
Offer Response Fields
| Field | Meaning |
|---|---|
id |
Display identifier for the offer row. |
amount |
Amount to charge for this offer. Send as amount during purchase. |
title, titleBn |
Display text for your customer. |
validity |
Validity label returned by the operator. |
category |
Detected category such as INTERNET, MINUTES, COMBO, or TALKTIME. |
highlighted |
Only shown when the provider marks this as a highlighted offer. |
commission |
Commission amount for this offer. |
operator |
Operator for the selected offer. Send this same value in the purchase request. |
offerId, ticketId, campaignId, sessionContext, optInKeyword, tranId |
Operator-specific identifiers returned by the offers API. Use the fields that exist on the selected offer when building the purchase request. |
Step 2. Purchase Request Body
| Field | Type | Required | Notes |
|---|---|---|---|
operator |
string | Yes | Use the same operator returned by the selected offer, for example airtel, robi, banglalink, or gp. |
number |
string | Yes | Customer mobile number. |
amount |
number or string | Yes | Send the selected offer amount. |
reference or client_reference |
string | Yes | Your unique billing reference for reconciliation and status checks. |
ticketId |
string | Robi/Airtel only | Required for Robi and Airtel offer purchase. |
offerId or offer_id |
string | GP/Banglalink | Required for GP and Banglalink offer purchase. |
campaignId or campaign_id |
string | GP only | Required for GP offer purchase. |
sessionContext or session_context |
string | GP only | Required for GP offer purchase. |
optInKeyword or opt_in_keyword |
string | Optional | Send only if the selected GP offer includes it. |
tranId or tran_id |
string | Banglalink only | Required for Banglalink offer purchase. |
webhook_url or recharge_webhook_url |
string | Optional | Webhook endpoint for recharge callbacks. |
Step 2. Purchase Response
{
"success": true,
"message": "Recharge 68 Tk to 1614031175 is successful. Transaction number is R260423.2309.36014f. Your new balance is 6814.64 TAKA.",
"provider": {
"success": true,
"message": "Recharge 68 Tk to 1614031175 is successful. Transaction number is R260423.2309.36014f. Your new balance is 6814.64 TAKA.",
"usimActiveStatus": {
"active": false,
"isReplaceable": false,
"usimEligibility": false
},
"isSuccessful": true,
"isResult": true
},
"billing": {
"reference": "BILL-20260204-00012",
"status": "success",
"rechargeType": "offer",
"number": "01614031175",
"amount": 68,
"fee": 0.34,
"commission": 1.02,
"remainingBalance": 174.41,
"offerId": "__EL_RECHARGE_OFFER__"
}
}
| Field | Meaning |
|---|---|
success |
Whether the purchase request was accepted and processed successfully. |
message |
Human-readable result message. |
provider |
Normalized upstream provider details for operators like Robi and Airtel. |
provider.success |
Provider-level success flag. |
provider.message |
Provider SMS-style confirmation message in a cleaner developer-friendly location. |
provider.usimActiveStatus |
Optional provider flags related to USIM eligibility and replacement state. |
billing.reference |
Your submitted unique reference. |
billing.status |
Current transaction status such as success, pending, or processing. |
billing.rechargeType |
Shows this transaction was an offer recharge. |
billing.number |
Customer mobile number used for the purchase. |
billing.amount |
Offer amount charged. |
billing.fee |
Applied fee amount deducted with the purchase. |
billing.commission |
Calculated commission amount for the offer purchase. |
billing.remainingBalance |
Wallet balance after the purchase request is booked. |
billing.offerId |
Offer identifier echoed back for tracking. This may contain the operator ticket ID or upstream offer marker for Robi/Airtel purchases. |
Status Checks: Store billing.reference or your submitted reference. Use GET /api/billing/transactions/status/check?reference=YOUR_REFERENCE to confirm the final state if your request is pending, processing, or if your webhook is delayed.
Copy-Paste Examples
# Recommended curl pattern
BASE_URL="https://pro.irecharge.net/api/billing"
OPEN_KEY="ok_live_YOUR_OPEN_KEY"
SECRET_KEY="sk_live_YOUR_SECRET_KEY"
PHONE="01937395849"
OPERATOR="banglalink"
curl --request GET "${BASE_URL}/recharge/offers?number=${PHONE}&operator=${OPERATOR}" \
--header "X-Open-Key: ${OPEN_KEY}" \
--header "X-Authorization: ${SECRET_KEY}"
# Purchase offer for Robi/Airtel
BASE_URL="https://pro.irecharge.net/api/billing"
OPEN_KEY="ok_test_YOUR_OPEN_KEY"
SECRET_KEY="sk_test_YOUR_SECRET_KEY"
PHONE="01612345678"
curl --request POST "${BASE_URL}/recharge/offers/purchase" \
--header "X-Open-Key: ${OPEN_KEY}" \
--header "X-Authorization: ${SECRET_KEY}" \
--header "Content-Type: application/json" \
--data '{
"operator": "airtel",
"number": "'"${PHONE}"'",
"amount": "698",
"ticketId": "243753368.243753368.243753368.1746120780000.507401.67335-1570h_",
"reference": "BILL-20260204-0002"
}'
# Purchase offer for Banglalink
BASE_URL="https://pro.irecharge.net/api/billing"
OPEN_KEY="ok_test_YOUR_OPEN_KEY"
SECRET_KEY="sk_test_YOUR_SECRET_KEY"
PHONE="01912345678"
curl --request POST "${BASE_URL}/recharge/offers/purchase" \
--header "X-Open-Key: ${OPEN_KEY}" \
--header "X-Authorization: ${SECRET_KEY}" \
--header "Content-Type: application/json" \
--data '{
"operator": "banglalink",
"number": "'"${PHONE}"'",
"offerId": "OFF32071",
"amount": "549",
"tranId": "4891011729527520112",
"reference": "BILL-20260204-0003"
}'
// 1. Fetch offers
const offersResponse = await fetch("https://pro.irecharge.net/api/billing/recharge/offers?number=01937395849&operator=banglalink", {
headers: {
"X-Open-Key": "ok_live_YOUR_OPEN_KEY",
"X-Authorization": "sk_live_YOUR_SECRET_KEY"
}
});
const offersData = await offersResponse.json();
// 2. Customer selects an offer
const selectedOffer = offersData.offers[0];
// 3. Purchase selected offer
const purchaseBody = selectedOffer.ticketId
? {
operator: selectedOffer.operator ?? offersData.operator,
number: selectedOffer.number ?? offersData.number,
amount: selectedOffer.amount,
ticketId: selectedOffer.ticketId,
reference: `ORDER-${Date.now()}`,
webhook_url: "https://example.com/webhooks/recharge"
}
: {
operator: selectedOffer.operator ?? offersData.operator,
number: selectedOffer.number ?? offersData.number,
amount: selectedOffer.amount,
offerId: selectedOffer.offerId,
tranId: selectedOffer.tranId,
reference: `ORDER-${Date.now()}`,
webhook_url: "https://example.com/webhooks/recharge"
};
const purchaseResponse = await fetch("https://pro.irecharge.net/api/billing/recharge/offers/purchase", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Open-Key": "ok_live_YOUR_OPEN_KEY",
"X-Authorization": "sk_live_YOUR_SECRET_KEY"
},
body: JSON.stringify(purchaseBody)
});
const purchaseData = await purchaseResponse.json();
Offer Integration Checklist
- Use sandbox keys first:
ok_test_*andsk_test_*. - Always submit a unique
reference. - Always send
operatorfrom the selected offer or response context when building the purchase request. - Use
offers[].commissionif you need to display commission. - Handle both immediate
successand failed/rejected responses. - Implement webhooks and status checks for reconciliation.
Check Transaction Status
Use this after purchase if you want to confirm the final state with your saved reference.
Recommended
Lookup by reference
Best for external systems and reconciliation.
Alternative
Lookup by transaction ID
Useful when you already stored the internal transaction ID.
Flexible Lookup: You can check status using either your reference or the transaction_id returned during recharge.
Method 1. GET by Reference
/api/billing/transactions/status/check
curl --location 'https://pro.irecharge.net/api/billing/transactions/status/check?reference=BILL-20260204-0001' \
--header 'X-Open-Key: ok_test_YOUR_OPEN_KEY' \
--header 'X-Authorization: sk_test_YOUR_SECRET_KEY'
Method 2. POST by Transaction ID
/api/billing/transactions/status/check
Accepted lookup fields:
transaction_idortransactionIdreference,client_reference, orclientReference
curl --location --request POST 'https://pro.irecharge.net/api/billing/transactions/status/check' \
--header 'X-Open-Key: ok_test_YOUR_OPEN_KEY' \
--header 'X-Authorization: sk_test_YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data '{
"transaction_id": 1
}'
Response (200 OK):
{
"success": true,
"message": "Transaction status fetched successfully.",
"data": {
"transactionId": 1,
"reference": "BILL-20260204-0001",
"status": "success",
"isFinal": true,
"amount": 10,
"fee": 0.5,
"commission": 0,
"service": {
"type": "recharge",
"status": "success",
"number": "01712345678"
},
"operator": {
"code": "GP",
"name": "Grameenphone"
},
"decision": {
"mode": "auto"
},
"createdAt": "2026-02-05T19:42:34.000000Z",
"updatedAt": "2026-02-05T19:42:34.000000Z",
"approvedAt": "2026-02-05T19:42:34.000000Z"
}
}
| Field | Meaning |
|---|---|
data.transactionId, data.reference |
Main identifiers for the transaction you looked up. |
data.status, data.isFinal |
Current status and whether the transaction has reached a final state. |
data.amount, data.fee, data.commission |
Booked financial values for the transaction. |
data.service |
Short summary of the related recharge or banking request. |
data.operator |
Operator code and name for quick display. |
data.decision |
Shows whether the result was completed automatically or by admin action when available. |
Transaction Statuses:
Awaiting processing
Being processed
Completed successfully
Transaction failed
Error Handling
The API uses standard HTTP status codes and returns error details in JSON format:
| Status Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API credentials |
| 402 | Payment Required - Insufficient balance or no active API subscription |
| 403 | Forbidden - IP not whitelisted or account inactive |
| 404 | Not Found - Transaction not found |
| 422 | Validation Error - Missing/invalid parameters or duplicate reference |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Error Response Format:
{
"success": false,
"message": "Insufficient balance",
"error": "Your account balance is insufficient for this transaction",
"code": "INSUFFICIENT_BALANCE"
}
Common Errors
| HTTP | Case | Example Message |
|---|---|---|
| 401 | Missing/invalid API key headers | Missing headers: X-Open-Key and X-Authorization are required. |
| 422 | Missing reference in billing recharge | Billing recharge requires a unique reference in body (reference/client_reference). |
| 422 | Duplicate reference | Reference already exists. Please send a unique reference. |
| 404 | Status check not found | Transaction not found for provided identifier. |
| 402 | No active API subscription | No active API subscription found. |
IP Whitelist Restriction: If you receive a 403 error with message "Your IP address is not whitelisted", add your server IP to the whitelist in your Developer Dashboard.
Rate Limits
API rate limits vary by package:
Starter
60 requests/minute
Business
120 requests/minute
Enterprise
Custom limits
Rate limit headers are included in each response for monitoring.
Webhooks
Receive real-time notifications about transaction events. Set webhook URL in request body (webhook_url or recharge_webhook_url) or configure it in your API key settings. Webhooks are delivered as HTTP POST requests with a JSON body.
Webhook Events
| Event | Description |
|---|---|
billing.recharge.success |
Initial request accepted/processed response |
billing.recharge.approved |
Transaction auto-approved or admin-approved |
billing.recharge.rejected |
Transaction rejected or reversed |
billing.banking.success |
Banking transaction created |
billing.banking.approved |
Banking transaction approved |
billing.banking.rejected |
Banking transaction rejected |
Webhook Payload Example:
{
"event": "billing.recharge.approved",
"timestamp": "2026-02-04T20:10:12.000000Z",
"api_key_id": 3,
"user_id": 5,
"transaction": {
"id": 21,
"reference": "BILL-20260204-0001",
"status": "success"
},
"decision": {
"action": "approved",
"mode": "auto"
}
}
Best Practice: Always verify webhook authenticity and respond with HTTP 200 to acknowledge receipt. Failed webhooks will be retried automatically.
Need Help?
Our support team is here to help you integrate our API successfully.