OniData API Log in Get API access

OniData Developer API

Let your own website or app sell data, airtime, cable TV, electricity, exam pins and recharge cards — powered by our network, paid from your wallet balance.

Base URL · https://myrabbithq.info/api/v1

Introduction

A simple JSON REST API. Every purchase is debited from the wallet balance of the account that owns the API key, at the same prices shown on our website.

🔐 Approval onlyAccess is granted by our team after you submit a request.
🌐 IP lockedCalls work only from the server IPs you whitelist (max 5).
🧩 Per-service accessYou can call only the services we approved for you.
♻️ Safe retriesSend a client_reference to prevent double charges.
Server-side only. Never put your API key in a mobile app, browser JavaScript or a public repository. Call the API from your backend.

Getting access

  1. Create an account and log in, then open Developer API in your dashboard.
  2. Submit the access form: your website link, the services you want (data, airtime, cable, electricity, exam pins, recharge cards) and your server IP address(es).
  3. Wait for approval. You get an email and an in-app notice when we approve or decline. Our team may approve only some of the services you asked for.
  4. Generate your API key (confirmed with a one-time code) and copy it — it is shown once.
  5. Fund your wallet and start calling the API from your whitelisted server.

Later you can add or remove whitelisted IPs (up to 5) and change your services from the same page. Every IP change, service change and key generation is confirmed with a one-time code sent to your email. IP changes apply immediately; service changes are sent to our team for re-approval and your current services stay active until then.

Authentication

Send your API key on every request using either header:

Authorization: Bearer YOUR_API_KEYrecommended
X-API-Key: YOUR_API_KEYalternative

Requests accept application/json bodies (or standard form fields). All responses are JSON. Rate limit: 60 requests per minute per account (429 RATE_LIMITED when exceeded).

Two open endpoints need no key:

GET/pingOpen

Health check

Returns ok when the API is online.

curl -X GET "https://myrabbithq.info/api/v1/ping" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/ping");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/ping", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/ping",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "OniData API v1 is online.",
    "data": {
        "version": "v1"
    }
}
GET/my-ipOpen

Find your server IP

Returns the IP address our server sees for your request. Run this from your server, then whitelist that IP in your dashboard.

curl -X GET "https://myrabbithq.info/api/v1/my-ip" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/my-ip");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/my-ip", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/my-ip",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "This is the IP address our server sees for your request. Whitelist it under API Access.",
    "data": {
        "ip": "102.89.12.34"
    }
}

IP whitelisting

Every call is checked against the server IPs you registered. If a request comes from any other IP, we refuse it and tell you the IP we saw in the JSON, so you can add it:

Response 403 Forbidden
{
    "ok": false,
    "code": "IP_NOT_WHITELISTED",
    "message": "This request came from IP 197.210.54.8, which is not whitelisted on your account. Add it under API Access \u2192 Whitelisted IPs.",
    "your_ip": "197.210.54.8",
    "whitelisted_ips": 1
}
Check order on every call: API key → account active → access approved → IP whitelisted → rate limit → service approved. Servers behind a proxy or with several outgoing IPs (IPv4/IPv6) should whitelist each outgoing address.

Responses & errors

Every response has an ok boolean and a human-readable message. Successful calls return data; failures return a machine-readable code (see Error codes) and a matching HTTP status.

Success 200
{
    "ok": true,
    "message": "Data plans.",
    "data": [
        "\u2026"
    ]
}
Failure 402
{
    "ok": false,
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient wallet balance. Please fund your wallet."
}

Transaction object

Purchases return a transaction in data:

FieldDescription
referenceOur unique transaction reference. Use it with GET /transaction.
statussuccess, pending (being processed — poll /transaction), failed or reversed.
amountAmount debited from your wallet (₦).
service, recipient, network, descriptionWhat was bought and for whom.
wallet_balance_afterYour balance after the debit.
tokenElectricity only — the meter token (prepaid). For manually processed orders it appears when the order is completed.
network_responseData only — the confirmation message returned by the mobile network.
pinsExam pins / recharge cards — array of {pin, serial}.
client_referenceEcho of the reference you supplied (if any).
Failed purchases are refunded automatically. If a purchase fails you receive an error response and nothing is charged. A pending status means the order was accepted and is being completed — poll GET /transaction rather than retrying.

Avoiding double purchases

Add your own unique client_reference (6–64 characters: letters, numbers, . - _) to any purchase call. If you send the same reference again — for example after a timeout — we return the original result with "duplicate": true and do not charge again. A purchase that failed (and was refunded) can be retried with the same reference.

You can look a transaction up by either reference: GET /transaction?reference=OUR_REF or GET /transaction?client_reference=YOUR_REF.

Account & status

GET/accountAccount

Account details

Your wallet balance, the services approved for you, any service change awaiting review, and the IP we see.

curl -X GET "https://myrabbithq.info/api/v1/account" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/account");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/account", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/account",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Account details.",
    "data": {
        "name": "Ada Obi",
        "wallet_balance": 25000.5,
        "approved_services": [
            "data",
            "airtime"
        ],
        "services_pending_review": [
            "cable"
        ],
        "your_ip": "102.89.12.34"
    }
}
GET/transactionAccount

Check a transaction

Fetch the current status of any purchase made through the API.

FieldTypeRequiredDescription
referencestringNoOur reference returned by the purchase call.
client_referencestringNoThe reference you supplied. Send one of the two.
curl -X GET "https://myrabbithq.info/api/v1/transaction?reference=DATA261012093011A1B2C3" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/transaction?reference=DATA261012093011A1B2C3");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/transaction?reference=DATA261012093011A1B2C3", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/transaction?reference=DATA261012093011A1B2C3",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Transaction found.",
    "data": {
        "reference": "DATA261012093011A1B2C3",
        "status": "success",
        "service": "data",
        "amount": 275,
        "recipient": "08031234567",
        "network": "mtn",
        "description": "MTN 1GB (30 days) \u2013 08031234567",
        "wallet_balance_after": 24725.5,
        "created_at": "2026-10-12 09:30:11"
    }
}

Data

GET/data/plansData

List data plans

All active plans with the plan_id you use to buy. Filter by network. Live IDs are also listed under Plan IDs & codes.

FieldTypeRequiredDescription
networkstringNomtn, airtel, glo or 9mobile.
curl -X GET "https://myrabbithq.info/api/v1/data/plans?network=mtn" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/data/plans?network=mtn");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/data/plans?network=mtn", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/data/plans?network=mtn",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Data plans.",
    "data": [
        {
            "plan_id": 12,
            "network": "mtn",
            "name": "MTN 1GB",
            "size": "1GB",
            "validity": "30 days",
            "type": "sme",
            "price": 275
        }
    ]
}
POST/data/purchaseData

Buy data

Debits your wallet and delivers the bundle.

FieldTypeRequiredDescription
plan_idintegerYesFrom data/plans.
phonestringYesRecipient number, e.g. 08031234567 or 2348031234567.
client_referencestringNoYour unique reference (see double purchases).
curl -X POST "https://myrabbithq.info/api/v1/data/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan_id":12,"phone":"08031234567","client_reference":"order-10045"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/data/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['plan_id' => 12, 'phone' => '08031234567', 'client_reference' => 'order-10045']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/data/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "plan_id": 12,
      "phone": "08031234567",
      "client_reference": "order-10045"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/data/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"plan_id": 12, "phone": "08031234567", "client_reference": "order-10045"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "data",
        "amount": 275,
        "recipient": "08031234567",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "network": "mtn",
        "description": "MTN 1GB \u2013 08031234567",
        "network_response": "Dear Customer, you have successfully shared 1GB data to 08031234567.",
        "client_reference": "order-10045"
    }
}

Airtime

GET/airtime/networksAirtime

List airtime networks

Minimum/maximum amount and the discount you get. You pay amount × (1 − discount_percent ÷ 100).

curl -X GET "https://myrabbithq.info/api/v1/airtime/networks" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/airtime/networks");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/airtime/networks", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/airtime/networks",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Airtime networks.",
    "data": [
        {
            "network": "mtn",
            "min_amount": 50,
            "max_amount": 50000,
            "discount_percent": 3
        }
    ]
}
POST/airtime/purchaseAirtime

Buy airtime

The amount is the airtime value delivered to the phone; your wallet is charged the discounted price.

FieldTypeRequiredDescription
networkstringYesmtn, airtel, glo, 9mobile.
phonestringYesRecipient number.
amountnumberYesAirtime value in ₦ (within the min/max).
client_referencestringNoYour unique reference.
curl -X POST "https://myrabbithq.info/api/v1/airtime/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"network":"mtn","phone":"08031234567","amount":500,"client_reference":"airtime-7781"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/airtime/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['network' => 'mtn', 'phone' => '08031234567', 'amount' => 500, 'client_reference' => 'airtime-7781']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/airtime/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "network": "mtn",
      "phone": "08031234567",
      "amount": 500,
      "client_reference": "airtime-7781"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/airtime/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"network": "mtn", "phone": "08031234567", "amount": 500, "client_reference": "airtime-7781"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "airtime",
        "amount": 485,
        "recipient": "08031234567",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "network": "mtn",
        "description": "MTN \u20a6500.00 airtime \u2013 08031234567",
        "client_reference": "airtime-7781"
    }
}

Cable TV

Validate the smartcard first, show the customer name to your user, then subscribe.

GET/cable/providersCable TV

List providers

Active cable providers.

curl -X GET "https://myrabbithq.info/api/v1/cable/providers" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/cable/providers");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/cable/providers", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/cable/providers",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Cable providers.",
    "data": [
        {
            "provider": "dstv",
            "label": "DSTv"
        },
        {
            "provider": "gotv",
            "label": "GOtv"
        }
    ]
}
GET/cable/plansCable TV

List plans

Plans (bouquets) for a provider.

FieldTypeRequiredDescription
providerstringYesdstv, gotv, startimes, showmax.
curl -X GET "https://myrabbithq.info/api/v1/cable/plans?provider=dstv" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/cable/plans?provider=dstv");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/cable/plans?provider=dstv", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/cable/plans?provider=dstv",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Cable plans.",
    "data": [
        {
            "plan_id": 5,
            "provider": "dstv",
            "name": "DStv Compact",
            "validity": "30 days",
            "price": 15700
        }
    ]
}
POST/cable/verifyCable TV

Validate a smartcard / IUC

Returns the account holder name. Always validate before purchasing.

FieldTypeRequiredDescription
providerstringYesProvider code.
smartcardstringYesSmartcard / IUC number (8–15 digits).
curl -X POST "https://myrabbithq.info/api/v1/cable/verify" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"provider":"dstv","smartcard":"7012345678"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/cable/verify");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['provider' => 'dstv', 'smartcard' => '7012345678']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/cable/verify", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "provider": "dstv",
      "smartcard": "7012345678"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/cable/verify",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"provider": "dstv", "smartcard": "7012345678"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Smartcard verified.",
    "data": {
        "provider": "dstv",
        "smartcard": "7012345678",
        "customer_name": "ADA OBI"
    }
}
POST/cable/purchaseCable TV

Subscribe

Pays the bouquet for the smartcard.

FieldTypeRequiredDescription
plan_idintegerYesFrom cable/plans.
smartcardstringYesSmartcard / IUC number.
customer_namestringNoName returned by cable/verify (stored on the receipt).
client_referencestringNoYour unique reference.
curl -X POST "https://myrabbithq.info/api/v1/cable/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan_id":5,"smartcard":"7012345678","customer_name":"ADA OBI","client_reference":"tv-2290"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/cable/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['plan_id' => 5, 'smartcard' => '7012345678', 'customer_name' => 'ADA OBI', 'client_reference' => 'tv-2290']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/cable/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "plan_id": 5,
      "smartcard": "7012345678",
      "customer_name": "ADA OBI",
      "client_reference": "tv-2290"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/cable/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"plan_id": 5, "smartcard": "7012345678", "customer_name": "ADA OBI", "client_reference": "tv-2290"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "cable_tv",
        "amount": 15700,
        "recipient": "7012345678",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "description": "DSTV DStv Compact \u2013 7012345678",
        "client_reference": "tv-2290"
    }
}

Electricity

Validate the meter first, then purchase. Prepaid purchases return the meter token.

GET/electricity/discosElectricity

List distribution companies

Active DisCos with their minimum/maximum purchase amount.

curl -X GET "https://myrabbithq.info/api/v1/electricity/discos" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/electricity/discos");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/electricity/discos", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/electricity/discos",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Electricity distribution companies. meter_type is \"prepaid\" or \"postpaid\".",
    "data": [
        {
            "disco": "ikedc",
            "name": "Ikeja Electric",
            "min_amount": 500,
            "max_amount": 200000
        }
    ]
}
POST/electricity/verifyElectricity

Validate a meter

Returns the customer name and address registered to the meter.

FieldTypeRequiredDescription
discostringYesDisCo code from electricity/discos.
meterstringYesMeter number.
meter_typestringYesprepaid or postpaid.
curl -X POST "https://myrabbithq.info/api/v1/electricity/verify" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"disco":"ikedc","meter":"45012345678","meter_type":"prepaid"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/electricity/verify");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['disco' => 'ikedc', 'meter' => '45012345678', 'meter_type' => 'prepaid']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/electricity/verify", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "disco": "ikedc",
      "meter": "45012345678",
      "meter_type": "prepaid"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/electricity/verify",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"disco": "ikedc", "meter": "45012345678", "meter_type": "prepaid"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Meter verified.",
    "data": {
        "disco": "ikedc",
        "meter": "45012345678",
        "meter_type": "prepaid",
        "customer_name": "ADA OBI",
        "address": "12 Allen Ave, Ikeja"
    }
}
POST/electricity/purchaseElectricity

Buy electricity

Vends units to the meter.

FieldTypeRequiredDescription
discostringYesDisCo code.
meterstringYesMeter number.
meter_typestringYesprepaid or postpaid.
phonestringYesCustomer phone (token SMS).
amountnumberYesAmount in ₦ (within the DisCo min/max).
customer_namestringNoName from electricity/verify.
client_referencestringNoYour unique reference.
If a DisCo is handled manually by our team, the response is "status": "pending" with no token yet. Poll GET /transaction — the token appears once the order is completed.
curl -X POST "https://myrabbithq.info/api/v1/electricity/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"disco":"ikedc","meter":"45012345678","meter_type":"prepaid","phone":"08031234567","amount":5000,"customer_name":"ADA OBI","client_reference":"pwr-5521"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/electricity/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['disco' => 'ikedc', 'meter' => '45012345678', 'meter_type' => 'prepaid', 'phone' => '08031234567', 'amount' => 5000, 'customer_name' => 'ADA OBI', 'client_reference' => 'pwr-5521']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/electricity/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "disco": "ikedc",
      "meter": "45012345678",
      "meter_type": "prepaid",
      "phone": "08031234567",
      "amount": 5000,
      "customer_name": "ADA OBI",
      "client_reference": "pwr-5521"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/electricity/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"disco": "ikedc", "meter": "45012345678", "meter_type": "prepaid", "phone": "08031234567", "amount": 5000, "customer_name": "ADA OBI", "client_reference": "pwr-5521"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "electricity",
        "amount": 5000,
        "recipient": "45012345678",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "description": "IKEDC prepaid \u20a65,000.00 | Meter: 45012345678",
        "token": "1234-5678-9012-3456-7890",
        "client_reference": "pwr-5521"
    }
}

Exam pins

GET/exam/plansExam pins

List exam pin plans

WAEC, NECO, JAMB and NABTEB plans.

FieldTypeRequiredDescription
exam_typestringNowaec, neco, jamb, nabteb.
curl -X GET "https://myrabbithq.info/api/v1/exam/plans?exam_type=waec" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/exam/plans?exam_type=waec");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/exam/plans?exam_type=waec", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/exam/plans?exam_type=waec",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Exam pin plans.",
    "data": [
        {
            "plan_id": 3,
            "exam_type": "waec",
            "name": "WAEC Result Checker",
            "price": 3500
        }
    ]
}
POST/exam/purchaseExam pins

Buy exam pins

Returns the pins/serials in data.pins (or later via GET /transaction if the order is pending).

FieldTypeRequiredDescription
plan_idintegerYesFrom exam/plans.
phonestringYesCustomer phone number.
quantityintegerNo1–10. Default 1.
client_referencestringNoYour unique reference.
curl -X POST "https://myrabbithq.info/api/v1/exam/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan_id":3,"phone":"08031234567","quantity":1,"client_reference":"exam-310"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/exam/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['plan_id' => 3, 'phone' => '08031234567', 'quantity' => 1, 'client_reference' => 'exam-310']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/exam/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "plan_id": 3,
      "phone": "08031234567",
      "quantity": 1,
      "client_reference": "exam-310"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/exam/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"plan_id": 3, "phone": "08031234567", "quantity": 1, "client_reference": "exam-310"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "exam",
        "amount": 3500,
        "recipient": "WAEC",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "pins": [
            {
                "pin": "123456789012",
                "serial": "WRN123456789"
            }
        ],
        "client_reference": "exam-310"
    }
}

Recharge card printing

GET/recharge/pricingRecharge cards

Unit prices

Price you pay per card for each network and denomination, plus how many cards are currently in stock (in_stock).

curl -X GET "https://myrabbithq.info/api/v1/recharge/pricing" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/recharge/pricing");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "GET",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/recharge/pricing", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
});
console.log(await res.json());
import requests

res = requests.request(
    "GET", "https://myrabbithq.info/api/v1/recharge/pricing",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Recharge card unit prices and available stock. Quantity per request: 1\u2013500.",
    "data": [
        {
            "network": "mtn",
            "denomination": 100,
            "unit_price": 97,
            "in_stock": 250
        }
    ]
}
POST/recharge/purchaseRecharge cards

Generate cards

Takes real ePINs from our stock, debits unit_price × quantity and returns the PINs with their serial numbers. ePINs do not expire. If we hold fewer cards than you ask for, nothing is charged and the error says how many are left.

FieldTypeRequiredDescription
networkstringYesmtn, airtel, glo, 9mobile.
denominationintegerYes50, 100, 200, 500 or 1000.
quantityintegerYes1–500.
client_referencestringNoYour unique reference.
curl -X POST "https://myrabbithq.info/api/v1/recharge/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"network":"mtn","denomination":100,"quantity":2,"client_reference":"cards-88"}'
<?php
$ch = curl_init("https://myrabbithq.info/api/v1/recharge/purchase");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => "POST",
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS     => json_encode(['network' => 'mtn', 'denomination' => 100, 'quantity' => 2, 'client_reference' => 'cards-88']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
const res = await fetch("https://myrabbithq.info/api/v1/recharge/purchase", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "network": "mtn",
      "denomination": 100,
      "quantity": 2,
      "client_reference": "cards-88"
  })
});
console.log(await res.json());
import requests

res = requests.request(
    "POST", "https://myrabbithq.info/api/v1/recharge/purchase",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"network": "mtn", "denomination": 100, "quantity": 2, "client_reference": "cards-88"}
)
print(res.json())
Response 200 OK
{
    "ok": true,
    "message": "Purchase successful.",
    "data": {
        "reference": "REF261012093011A1B2C3",
        "status": "success",
        "service": "recharge_card",
        "amount": 194,
        "recipient": "MTN",
        "wallet_balance_after": 0,
        "created_at": "2026-10-12 09:30:11",
        "network": "mtn",
        "description": "MTN \u20a6100 Recharge Cards \u00d7 2",
        "pins": [
            {
                "pin": "1234567890123456",
                "serial": "SN000001"
            },
            {
                "pin": "6543210987654321",
                "serial": "SN000002"
            }
        ],
        "client_reference": "cards-88"
    }
}

Plan IDs & codes

Live reference from our system — these are the IDs to send. Prices are what your wallet is charged.

Network codes

CodeNetwork
mtnMTN
airtelAirtel
gloGlo
9mobile9mobile

Data plans

MTN
plan_idPlanSizeValidityTypePrice
2MTN SME 1GB1GB30 Dayssme₦400.00
3MTN SME 2GB2GB30 Dayssme₦810.00

Airtime

networkMinMaxDiscount
mtn₦50.00₦5,000.002%
airtel₦50.00₦50,000.003%
glo₦50.00₦50,000.003%

Cable TV

providerName
dstvDSTv
gotvGOtv
startimesStarTimes
showmaxShowmax
GOTV
plan_idPlanValidityPrice
1Smallie1 MONTH₦2,500.00

Electricity (DisCo codes)

discoCompanyMinMax
ikedcIkeja Electric₦500.00₦200,000.00
ekedcEko Electricity₦500.00₦200,000.00
aedcAbuja Electricity₦500.00₦200,000.00
ibedcIbadan Electricity₦500.00₦200,000.00
phedcPort Harcourt Electric₦500.00₦200,000.00
kaedcoKaduna Electricity₦500.00₦100,000.00
kedcoKano Electricity₦500.00₦100,000.00
jedJos Electricity₦500.00₦100,000.00
bedcBenin Electricity₦500.00₦100,000.00
eedcEnugu Electricity₦500.00₦100,000.00

Meter types: prepaid, postpaid.

Exam pins

WAEC
plan_idPlanPrice
1WAEC Result Checker₦3,500.00
2WAEC GCE Result Checker₦3,500.00
3WAEC Scratch Card (Direct)₦3,800.00
NECO
plan_idPlanPrice
4NECO Result Checker₦250.00
5NECO GCE Result Checker₦1,000.00
JAMB
plan_idPlanPrice
8JAMB Mock ePIN₦1,000.00
7JAMB ePIN (Direct Entry)₦2,000.00
6JAMB ePIN (UTME)₦3,500.00
NABTEB
plan_idPlanPrice
9NABTEB Result Checker₦2,500.00
10NABTEB GCE Result Checker₦2,500.00

Recharge cards

network₦50 card₦100 card₦200 card₦500 card₦1000 card
mtn₦48.50₦97.00₦194.00₦485.00₦970.00
airtel₦48.00₦96.00₦192.00₦480.00₦960.00
glo₦48.00₦96.00₦192.00₦480.00₦960.00
9mobile₦47.50₦95.00₦190.00₦475.00₦950.00

Error codes

HTTPcodeMeaning
401MISSING_API_KEYNo key was sent.
401INVALID_API_KEYThe key is wrong or was regenerated/revoked.
403ACCESS_NOT_APPROVEDYour access request is not approved.
403ACCESS_SUSPENDEDYour API access is suspended — contact support.
403ACCOUNT_INACTIVEYour account is not active.
403IP_NOT_WHITELISTEDThe request IP is not on your whitelist. The response includes your_ip.
403SERVICE_NOT_APPROVEDThat service is not approved for you. The response lists approved_services.
403KYC_REQUIREDKYC verification is required for this service.
402INSUFFICIENT_BALANCEWallet balance too low — fund your wallet.
404NOT_FOUNDUnknown endpoint or transaction.
405METHOD_NOT_ALLOWEDUse the HTTP method shown for the endpoint.
409DUPLICATE_IN_PROGRESSA call with the same client_reference is still processing.
422VALIDATION_ERRORA field is missing or invalid; fields lists them.
422VALIDATION_FAILEDSmartcard/meter could not be verified.
422SERVICE_UNAVAILABLEThe plan/network/provider is unavailable right now.
422PURCHASE_FAILEDThe provider could not complete the purchase. You were not charged.
429RATE_LIMITEDToo many requests.
500SERVER_ERRORUnexpected error — check the transaction status before retrying.
503API_DISABLEDThe API is temporarily switched off.