Overview #
Everything you need before making your first request.
How it works: Your application calls the SchedWave API. We authenticate your request, validate your balance, then forward the order to our fulfillment provider. Your users never touch the upstream provider directly.
Your API key is in your SchedWave dashboard under Profile → API Key. POST endpoints accept application/x-www-form-urlencoded or application/json. All responses are JSON.
Authentication #
Pass your API key with every request via query param or header.
Keep it secret. Never expose your API key in client-side code or public repos.
Query param
?api_key=YOUR_KEYHTTP Header
Authorization: Bearer YOUR_KEYcurl
# Query param curl "https://schedwave.com/api/v1/balance?api_key=YOUR_KEY" # Bearer header curl "https://schedwave.com/api/v1/balance" \ -H "Authorization: Bearer YOUR_KEY"
Error Handling #
Errors return a consistent JSON envelope with an HTTP status code ≥ 400.
json — error envelope
{ "error": true, "error_code": "INSUFFICIENT_BALANCE", "message": "Required: 0.5200, Available: 0.1000." }
| HTTP | error_code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Missing or invalid parameter |
| 401 | UNAUTHORIZED | Invalid or missing API key |
| 402 | INSUFFICIENT_BALANCE | Not enough wallet balance |
| 404 | NOT_FOUND | Service or order not found |
| 405 | METHOD_NOT_ALLOWED | Wrong HTTP method |
| 422 | PROVIDER_REJECTED | Upstream provider rejected request |
| 500 | DB_ERROR | Internal error — contact support |
| 502 | PROVIDER_ERROR | Could not reach provider |
Rate Limits #
60 requests per minute per API key. Exceeding this returns HTTP
429. Contact support for higher limits.Services #
List all active services grouped by platform. Use the
service_id when placing orders.
GET
/api/v1/services
List all active services
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| categoryoptional | string | Filter by platform e.g. Instagram |
| searchoptional | string | Keyword search on name & description |
Example
curl
curl "https://schedwave.com/api/v1/services?api_key=KEY&category=Instagram"
Response
json 200
{
"error": false, "count": 24,
"services": {
"Instagram": [{
"service_id": 101,
"name": "Instagram Followers — High Quality",
"category": "Instagram",
"type": "Default",
"rate": "0.9500",
"min": 100, "max": 500000,
"avg_time": "0-1 hours",
"refill": true, "cancel": true
}]
}
}Balance #
Check your current wallet balance.
GET
/api/v1/balance
Wallet balance
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
Response
json 200
{ "error": false, "balance": "48.7200", "currency": "USD" }Place Order #
Submit a new order using a
service_id from the services list. Balance is deducted immediately.
POST
/api/v1/order
Place a new order
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| service_idrequired | integer | Service ID from /services |
| linkrequired | string | Target URL or username |
| quantityrequired | integer | Units to order, within service min/max |
| runsoptional | integer | Drip-feed: number of runs |
| intervaloptional | integer | Drip-feed: minutes between runs |
| commentsoptional | string | Newline-separated comments (comment services) |
| usernamesoptional | string | Newline-separated usernames (mention services) |
Example
curl
curl -X POST "https://schedwave.com/api/v1/order" \ -d "api_key=KEY&service_id=101&link=https://instagram.com/page&quantity=1000"
Response
json 200
{ "error": false, "order": 98245, "charge": 0.95, "currency": "USD", "balance": 47.77, "status": "pending" }Order Status #
Check live status of one or many orders. Active orders are refreshed from the provider on each call.
GET
/api/v1/status
Check order status
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| orderone of | integer | Single order ID |
| ordersone of | string | Comma-separated IDs, max 100 |
Status Values
pending
Queued, not yet started
in_progress
Being delivered
completed
Fully delivered
partial
Partially delivered
cancelled
Cancelled & refunded
Response
json 200
{
"error": false,
"orders": { "98245": {
"order": 98245, "service_id": 101,
"service_name": "Instagram Followers",
"link": "https://instagram.com/page",
"quantity": 1000, "charge": 0.95,
"status": "in_progress", "start_count": 12450,
"remains": 620, "created_at": "2026-02-19 10:34:01"
}}
}Order History #
Paginated list of all your orders with optional filters.
GET
/api/v1/orders
Paginated order history
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| pageoptional | integer | Page number (default: 1) |
| limitoptional | integer | Per page, max 100 (default: 20) |
| statusoptional | string | pending | in_progress | completed | partial | cancelled |
| service_idoptional | integer | Filter by service ID |
Response
json 200
{ "error": false, "total": 142, "page": 1, "limit": 20, "total_pages": 8,
"orders": [{ "order": 98245, "service_id": 101, "status": "completed" /* ... */ }] }Cancel Order #
Cancel pending/processing orders. Check the
cancel flag on the service first.
POST
/api/v1/cancel
Cancel orders
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| orderone of | integer | Single order ID |
| ordersone of | string | Comma-separated IDs, max 100 |
Response
json 200
{
"error": false, "results": {
"98245": { "cancelled": true, "refund": 0.95 },
"98246": { "cancelled": false, "reason": "Service does not support cancellation." }
}
}Request Refill #
Free refill for a completed order where counts dropped. Check
refill: true on the service.
POST
/api/v1/refill
Request a refill
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| orderrequired | integer | Completed order ID to refill |
Response
json 200
{ "error": false, "refill": 44012, "status": "pending" }Refill Status #
Check the progress of a refill request using the ID returned from
/refill.
GET
/api/v1/refill-status
Refill progress
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| refillrequired | integer | Refill ID from /refill |
Response
json 200
{ "error": false, "refill": 44012, "order": 98245,
"service_name": "Instagram Followers", "status": "completed",
"created_at": "2026-02-20 08:10:42" }VTU Services #
Airtime, Data, Cable TV, Electricity, and Exam PINs — all powered through our provider network. Prices shown are your final charged amounts (inclusive of platform fee).
Base URL prefix: All VTU endpoints live under
https://schedwave.com/api/v1/vtu/. Balance is deducted immediately on success. All amounts are in NGN.
VTU Networks #
List available networks for a given service type. Use the returned
id in purchase calls.
GET
/api/v1/vtu/networks
List networks for airtime or data
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| servicerequired | string | airtime or data |
Example
curl
curl "https://schedwave.com/api/v1/vtu/networks?api_key=KEY&service=data"
Response
json 200
{
"error": false, "service": "data",
"networks": [
{ "id": 1, "network": "MTN", "prefix": "0702|0803|0806..." },
{ "id": 2, "network": "Airtel", "prefix": "0802|0808..." },
{ "id": 3, "network": "Glo", "prefix": "0805|0807..." },
{ "id": 4, "network": "9mobile", "prefix": "0809|0818..." }
]
}Buy Airtime #
Top up any Nigerian phone number with VTU airtime.
POST
/api/v1/vtu/airtime
Purchase airtime
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| networkrequired | integer | Network ID from /vtu/networks |
| phonerequired | string | 11-digit Nigerian phone number |
| amountrequired | integer | Airtime face value in NGN (min ₦50, max ₦50,000) |
Example
curl
curl -X POST "https://schedwave.com/api/v1/vtu/airtime" \ -d "api_key=KEY&network=1&phone=08012345678&amount=500"
Response
json 200
{
"error": false,
"order_id": 1042,
"reference": "API_66bbd45c67b7b",
"network": "MTN",
"phone": "08012345678",
"amount": 500,
"charged": 515,
"currency": "NGN",
"status": "completed",
"balance": 9485,
"message": "Airtime Purchase Successful."
}Data Plans #
Fetch all available data bundles with your platform pricing applied. Use
plan_id when purchasing.
GET
/api/v1/vtu/data-plans
List available data bundles
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| networkoptional | string | Filter by network name e.g. MTN |
Response
json 200
{
"error": false, "count": 48,
"plans": [
{ "plan_id": 1, "network": "MTN", "datasize": "500MB", "type": "SME", "validity": 30, "price": 473, "currency": "NGN" },
{ "plan_id": 2, "network": "MTN", "datasize": "1GB", "type": "SME", "validity": 30, "price": 683, "currency": "NGN" }
]
}Buy Data #
Purchase a data bundle using a
plan_id from /vtu/data-plans.
POST
/api/v1/vtu/data
Purchase data bundle
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| networkrequired | integer | Network ID from /vtu/networks |
| phonerequired | string | 11-digit recipient phone number |
| plan_idrequired | integer | Plan ID from /vtu/data-plans |
Example
curl
curl -X POST "https://schedwave.com/api/v1/vtu/data" \ -d "api_key=KEY&network=1&phone=08012345678&plan_id=2"
Response
json 200
{
"error": false,
"order_id": 1043,
"reference": "API_66bbd305d2fa2",
"plan": "1GB 30days MTN",
"network": "MTN",
"datasize": "1GB",
"phone": "08012345678",
"charged": 683,
"currency": "NGN",
"status": "completed",
"balance": 8802
}Cable TV Plans #
Fetch available cable TV subscription plans for a given provider.
GET
/api/v1/vtu/cable-plans
List cable TV plans
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| cablerequired | string | GOTV, DSTV, or STARTIMES |
Response
json 200
{
"error": false, "count": 8,
"plans": [
{ "plan_id": 1, "name": "GOtv Max N8,500", "cable": "Gotv", "cable_id": 1, "price": 8755, "currency": "NGN" }
]
}Verify IUC / Smartcard #
Validate an IUC or smartcard number before subscribing. Always call this before a cable purchase.
GET
/api/v1/vtu/cable-validate
Verify IUC number
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| iucrequired | string | IUC / smartcard number |
| cablerequired | integer | Cable provider ID (cable_id from plans) |
Response
json 200
{ "error": false, "name": "Ibrahim Musa", "outstanding": 3000, "message": "kindly check the name." }Buy Cable TV #
Renew or subscribe to a cable TV plan using the IUC/smartcard number.
POST
/api/v1/vtu/cable
Purchase cable subscription
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| cablerequired | integer | Cable provider ID (cable_id from plans) |
| iucrequired | string | IUC or smartcard number |
| cable_planrequired | integer | Plan ID from /vtu/cable-plans |
Response
json 200
{
"error": false,
"order_id": 1044,
"reference": "API_66bc696addd8e",
"plan": "GOtv Max N8,500",
"provider": "Gotv",
"iuc": "01831092587",
"charged": 8755,
"currency": "NGN",
"status": "completed",
"balance": 45230
}Electricity Providers #
List all supported DISCOs (Distribution Companies) and their IDs.
GET
/api/v1/vtu/electricity-providers
List electricity DISCOs
Response
json 200
{
"error": false,
"providers": [
{ "id": 1, "name": "Ikeja Electric", "code": "IE" },
{ "id": 2, "name": "Eko Electric", "code": "EKEDC" },
{ "id": 8, "name": "Abuja Electric", "code": "AEDC" }
]
}Verify Meter Number #
Validate a meter number before payment. Returns customer name and address.
GET
/api/v1/vtu/electricity-validate
Verify meter number
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| meter_numberrequired | string | Meter number |
| meter_typerequired | string | prepaid or postpaid |
| discorequired | integer | Provider ID from /vtu/electricity-providers |
Response
json 200
{ "error": false, "name": "IBRAHIM MUSA", "address": "NO 5 Amule, Ilorin Kwara state", "message": "verified, kindly check the name." }Pay Electricity Bill #
Purchase prepaid token or pay postpaid electricity bill. Token is returned in the response for prepaid meters.
POST
/api/v1/vtu/electricity
Pay electricity bill
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| discorequired | integer | Provider ID from /vtu/electricity-providers |
| meter_numberrequired | string | Meter number |
| meter_typerequired | string | prepaid or postpaid |
| amountrequired | integer | Amount in NGN (min ₦500) |
| phoneoptional | string | Phone for SMS token delivery |
Response
json 200
{
"error": false,
"order_id": 1045,
"reference": "API_Bill_66bc6a8a0bfa5",
"provider": "Ikeja Electric",
"meter_number":"56789076064",
"meter_type": "prepaid",
"token": "1234-5678-9012-3456-7890",
"amount": 2000,
"charged": 2050,
"currency": "NGN",
"status": "completed",
"balance": 43180
}Exam Types #
List available exam PIN types (WAEC, NECO, JAMB, NABTEB) with prices.
GET
/api/v1/vtu/exam-types
List exam PIN types
Response
json 200
{
"error": false,
"exams": [
{ "exam_id": 1, "name": "WAEC", "price": 3640, "currency": "NGN" },
{ "exam_id": 2, "name": "NECO", "price": 2340, "currency": "NGN" },
{ "exam_id": 4, "name": "JAMB", "price": 1092, "currency": "NGN" },
{ "exam_id": 3, "name": "NABTEB", "price": 1040, "currency": "NGN" }
]
}Buy Exam PIN #
Purchase one or more exam scratch card PINs. Up to 10 per transaction.
POST
/api/v1/vtu/exam
Purchase exam PIN(s)
Body Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| exam_idrequired | integer | Exam ID from /vtu/exam-types |
| quantityoptional | integer | Number of PINs (default: 1, max: 10) |
Response
json 200
{
"error": false,
"order_id": 1046,
"reference":"API_Exam_66bd2dbdcf7e4",
"exam": "NECO",
"quantity": 1,
"pin": "234981177264",
"charged": 2340,
"currency": "NGN",
"status": "completed",
"balance": 40840
}VTU Order History #
Paginated VTU transaction history, filterable by service type and status.
GET
/api/v1/vtu/orders
Paginated VTU order history
Parameters
| Param | Type | Description |
|---|---|---|
| api_keyrequired | string | Your API key |
| typeoptional | string | airtime | data | cable | electricity | exam |
| statusoptional | string | pending | completed | failed |
| pageoptional | integer | Page number (default: 1) |
| limitoptional | integer | Per page, max 100 (default: 20) |
Response
json 200
{ "error": false, "total": 87, "page": 1, "limit": 20, "total_pages": 5,
"orders": [{ "order_id": 1046, "type": "data", "network": "MTN", "phone": "08012345678",
"amount": 683, "currency": "NGN", "status": "completed", "created_at": "2026-02-21 14:22:10" }] }Code Examples #
Replace
YOUR_API_KEY with the key found in your Profile page.PHP
<?php class SchedWave { private string $base = 'https://schedwave.com/api/v1'; public function __construct(private string $key) {} private function call(string $ep, array $p=[], string $m='GET'): array { $p['api_key']=$this->key; $url="{$this->base}/{$ep}"; $ch=curl_init(); $m==='POST' ? (curl_setopt($ch,CURLOPT_POST,true),curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($p))) : $url.='?'.http_build_query($p); curl_setopt_array($ch,[CURLOPT_URL=>$url,CURLOPT_RETURNTRANSFER=>true]); $r=json_decode(curl_exec($ch),true); curl_close($ch); return $r; } public function services(string $c='') { return $this->call('services',$c?['category'=>$c]:[]); } public function balance() { return $this->call('balance'); } public function order(int $id, string $link, int $qty) { return $this->call('order',['service_id'=>$id,'link'=>$link,'quantity'=>$qty],'POST'); } public function status(int $id) { return $this->call('status',['order'=>$id]); } } $api=$new SchedWave('YOUR_API_KEY'); $o=$api->order(101,'https://instagram.com/page',1000); echo "Order #{$o['order']} — Balance: \${$o['balance']}";
JavaScript (fetch)
const BASE='https://schedwave.com/api/v1', KEY='YOUR_API_KEY'; const sw=async(ep,p={},m='GET')=>{ p.api_key=KEY; const url=m==='GET'?`${BASE}/${ep}?${new URLSearchParams(p)}`:`${BASE}/${ep}`; return(await fetch(url,m==='POST'?{method:'POST',body:new URLSearchParams(p), headers:{'Content-Type':'application/x-www-form-urlencoded'}}:{})).json(); }; const o=await sw('order',{service_id:101,link:'https://instagram.com/page',quantity:1000},'POST'); console.log(`Order #${o.order} — Balance: $${o.balance}`);
Python
import requests BASE,KEY="https://schedwave.com/api/v1","YOUR_API_KEY" def sw(ep,p=None,m="GET"): p=(p or {})|{"api_key":KEY} return(requests.get if m=="GET" else requests.post)( f"{BASE}/{ep}",**(dict(params=p) if m=="GET" else dict(data=p)),timeout=30).json() o=sw("order",{"service_id":101,"link":"https://instagram.com/page","quantity":1000},"POST") print(f"Order #{o['order']} placed. Balance: ${o['balance']}")