Gsubz Store – Buy From China, Ship to Nigeria
Login / Register
API Documentation

GSUBZ API documentation

Sell airtime, data, cable TV, electricity tokens, exam pins and social media services from your own website or app, using your GSUBZ wallet.

Base URLhttps://api.gsubz.com
AuthenticationBearer token (your API key)
Request formatForm data
Response formatJSON
CurrencyNigerian naira (₦)
Time zoneWest Africa Time (UTC+1)

Building with an AI assistant? Give it the Markdown or OpenAPI version of these docs, and it can write the integration for you.

OpenAPI Open in Claude Open in ChatGPT

Quickstart

From zero to your first successful call in a few minutes.

  1. Create your account and fund your walletEvery API purchase is paid from your GSUBZ wallet, so add funds before you start.
  2. Copy your API keyOpen your dashboard key page and copy the key. It starts with ap_.
  3. Check your wallet balanceThis confirms your key works and costs nothing. Replace YOUR_API_KEY with your key.
Request
curl --location 'https://api.gsubz.com/api/balance/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"'
Example response 200 OK
{
  "balance": "747.5"
}
Prefer to test without writing code? Open any endpoint below and use Try it live. Enter your API key and the fields, then send a real request from this page.
  1. Make your first purchase A typical data purchase takes three calls:
  2. Check your API pricesEvery plan from Get Plans shows two prices: price, the normal price, and api_price, what you pay through the API.

Authentication

Send your API key as a Bearer token in the Authorization header of every request, except Get Plans, List All Services, the eSIM country and package lists and the two game lists, which are public.

Authorization: Bearer YOUR_API_KEY

Most POST endpoints also take the same key in the api body field. Send both, exactly as the examples show. The Store endpoints take the Bearer header only.

Keep your key secret. Anyone with your key can spend your wallet. Call GSUBZ from your server only, never from a mobile app or website JavaScript. If a key is exposed, reset it from your dashboard and update your integration.

Making requests

These conventions apply to every endpoint.

TopicDetail
Base URLhttps://api.gsubz.com. Always use HTTPS.
Endpoint pathsPaths end with a trailing slash, for example /api/pay/. Use the URLs exactly as shown.
Request bodyForm data: multipart/form-data or application/x-www-form-urlencoded. Every value is sent as text. The GET endpoints (Get Plans, List All Services, List Airports, the eSIM lists, the two game lists and every Store endpoint except Image Search) take their fields in the query string instead. Place an Order and Book a Flight also accept a JSON body (application/json), which is the easiest way to send their lists (items, passengers).
Response bodyJSON, UTF-8 encoded.
AuthenticationHeader Authorization: Bearer YOUR_API_KEY. See Authentication above.
Phone numbers11-digit Nigerian format, for example 08031234567.
MoneyNigerian naira (₦). Send plain numbers: no ₦ symbol, commas or spaces (2400, not ₦2,400).
Dates and timeISO 8601 with the West Africa Time offset, for example 2026-01-01T09:30:00+01:00.
TimeoutsA purchase can take a few seconds while the network or biller responds. Use a client timeout of at least 60 seconds.

Responses

Every purchase returns the same flat JSON object. Check status first: successful means delivered and failed means it did not go through.

FieldTypeDescription
codeintegerResult code. 200 means the request was processed. See Errors.
statusstringOutcome of the purchase. successful means it was delivered. failed means it did not go through.
transactionIDintegerGSUBZ's unique reference for this transaction.
amountnumberValue of the purchase in naira (the plan price, or the amount you requested).
phonestringThe phone number the purchase was made for, where the service uses one.
serviceIDstringThe service you bought.
amountPaidnumberAmount deducted from your wallet, in naira, at your API price. It can be lower than amount.
initialBalancenumberWallet balance before the purchase.
finalBalancenumberWallet balance after the purchase.
datestringWhen the transaction was created (ISO 8601, West Africa Time).
api_responsestringThe message returned by the network or provider, for example the confirmation text for a recharge or data purchase.

Errors

A transaction can return HTTP 200 and still have failed. Always check the status field, not just the response code.
CodestatusdescriptionMeaningWhat to do
200 successful — The request was processed. A transaction can still fail with HTTP 200, so always read the status field. Deliver value only when status is successful. A purchase that did not go through returns failed.
204 failed REQUIRED_CONTENT_NOT_SENT A required field is missing from your request. Compare your request with the Parameters table for that endpoint.
400 failed REQUIRED_CONTENT_REQUESTID_IS_EMPTY You sent neither requestID nor transactionID to Fetch Transaction Status. Send one of them.
206 failed INVALID_CONTENT One of the fields has an invalid value. Check the phone number, amount and service ID formats.
401 failed INVALID_PLAN The plan or variation_code does not match the serviceID. Call Get Plans again and use a value from that list.
401 failed INVALID_API_OR_NOT_FOUND The API key is missing or is not valid. Send it as Authorization: Bearer YOUR_API_KEY, and copy it again from your dashboard if it still fails.
402 failed INSUFFICIENT_BALANCE Your wallet balance is too low for this purchase. Fund your wallet, then try again.
404 failed CONTENT_NOT_FOUND The resource you asked for could not be found. Check the URL and the reference you sent.
405 failed REQUEST_METHOD_NOT_IN_POST You used GET where POST is required, or the other way round. Use the method shown for the endpoint.
406 failed SERVICE_DISABLED This service is temporarily disabled. Try again later or use another service.
406 successful or failed INVALID_ARGUMENTS_DUPLICATE_REQUEST_ID You already used this requestID. Nothing was charged again, and the response carries the original result. A requestID already used by another account is refused the same way, with no transaction details. Read the original result from the response, or send a new requestID for a new order.
406 failed NOT_CANCELLABLE The eSIM cannot be cancelled, for example because it was already installed or already refunded. Nothing was changed. Only an unused eSIM can be cancelled.
404 failed PLAYER_NOT_FOUND The player ID you sent does not exist for that game. Check the ID with the player. Nothing was charged.
406 failed OUT_OF_STOCK That game product is out of stock right now. For a Store order: you asked for more than is in stock, and the response has available. Nothing was charged. Pick another amount or lower the quantity, or try again later.
406 failed PRICE_CHANGED The price changed while your order was being placed. For a Store order: a product costs more than the price you sent, and the response lists currentPriceNgn for each item. Nothing was charged. Fetch the products again (List Game Products or Get Product Details) and retry.
206 failed REGION_MISMATCH The player account is in a region that cannot receive this product. Use the product line for the player's region. Nothing was charged.
406 failed ORDER_FAILED The order could not be completed, and your wallet was refunded automatically. The response carries the refunded order. Try another product or try again later.
406 failed REQUEST_IN_PROGRESS An earlier request with this requestID has not finished yet. Look it up with Fetch Game Orders in a minute, or send a new requestID for a new order.
206 failed BELOW_MINIMUM_ORDER A product needs more pieces (across its variants) than you ordered. The response has moq. Raise the quantity to at least moq.
406 failed SEARCH_EXPIRED The flight search you are booking from is older than one hour (or is not yours). Search again and pick a flight from the new results. Nothing was charged.
406 failed QUOTE_EXPIRED The locked flight price expired (about 25 minutes) or was already used. Call Book a Flight with preview=true for a new price. Nothing was charged.
406 failed FARE_UNAVAILABLE The airline no longer offers that fare. Search again and pick another flight. Nothing was charged.
406 failed BOOKING_FAILED The airline could not issue the booking, and your wallet was refunded automatically. Nothing was charged. Search again, or try another flight.
406 failed CANCEL_NOT_ALLOWED The order or item can no longer be cancelled: more than 2 hours have passed, or it is already being processed or cancelled. Nothing was changed. Contact support if something went wrong with the order.
406 failed NOTHING_DUE No shipping fee is due on that order or item right now. Nothing was charged. Check shipping.status in Get Orders.
406 failed ACCOUNT_BLOCKED This account is blocked. Contact support.
407 failed Chat Admin to get upgraded before using our API, Thank you! Your account has not been upgraded for API use yet. Contact support to be upgraded. The HTTP status for this one is 403.
429 failed TOO_MANY_REQUESTS You sent too many requests in a short time. The Store endpoints allow 60 calls a minute for each API key, and flight searches 20. Wait a minute, then try again.
500 failed SERVER_ERROR Something went wrong on our side. Nothing was charged. Try again. If it keeps happening, contact support.
502 failed GATEWAY_ERROR The upstream provider did not respond. Safe to retry. If you sent a requestID, check Fetch Transaction Status first, then retry. Store calls that fail this way are never charged.

A failed request returns "status": "failed", the code, a description from the table above, and an api_response that explains in plain words what went wrong.

{
  "code": 402,
  "status": "failed",
  "description": "INSUFFICIENT_BALANCE",
  "api_response": "Your wallet balance is too low for this purchase"
}

Best practices

Follow these before you go live. They prevent the most common problems, including charging a customer twice.

  • Keep your API key on your server

    Never put it in a mobile app, in website JavaScript or in a public repository. Call GSUBZ from your backend only. If a key is ever exposed, reset it from your dashboard.

  • Send a unique requestID with every purchase

    Use your own order or invoice number. It lets you look the transaction up later with Fetch Transaction Status. You can also look it up with the transactionID from the response, so save that too.

  • Read status, not just the HTTP code

    A response can arrive with HTTP 200 and still describe a failed transaction. Treat a purchase as successful only when status is successful. A failed purchase returns failed.

  • Never resend a purchase blindly after a timeout

    If a request times out or you get no response, the purchase may still have gone through. Look it up by requestID first, so you do not charge your customer twice. A purchase that takes longer than 10 seconds, or whose answer never reaches you, also sends its final result to your webhook as transaction.updated.

  • Fetch plans instead of hard-coding them

    Plan values and prices can change. Call Get Plans and use the value it returns as your plan (or variation_code).

  • Verify meter and smartcard numbers before paying

    Call Verify Meter / IUC Number so your customer can confirm their name before you charge them. It catches typing mistakes before money moves.

  • Watch your wallet balance

    Check Fetch Wallet Balance and top up before it runs low, so customers do not hit INSUFFICIENT_BALANCE.

  • Treat processing game orders as unfinished

    A game purchase can return orderStatus processing. You have been charged, and the order ends as completed or refunded. Wait for the games.order.updated webhook, or check it with Fetch Game Orders, before you tell your customer it is done.

  • Cache Store results on your side

    Every paid Store call is charged, even when you repeat the same request. Save search results and product details in your own database or cache, and refresh them only when you need to.

  • Preview Store orders, and send a reference

    Call Place an Order with preview=true to show your customer the exact total first. Then place it with your own unique reference, so a retry after a timeout can never create a second order.

  • Preview a flight, then book it

    Show your customer the price from Book a Flight with preview=true, not the one from search, then book with the quoteID and a unique requestID. A booking can be processing for a while: wait for the flight.order.updated webhook before you tell your customer the ticket is issued.

  • Check every webhook's signature

    Verify X-Gsubz-Signature with your signing secret before you trust a webhook, answer 2xx quickly, and ignore an eventId you have already handled.

  • Convert numbers before doing arithmetic

    Amounts and balances are numbers in naira. Convert them yourself before doing arithmetic, in case a value ever arrives as text.

Webhooks

We send a POST with a JSON event to your webhook URL whenever something changes on an order you placed through the API: the final result of a slow purchase, a refund, a new status, a shipping fee after weighing, a tracking number, a flight ticket, a game order finishing, a cancellation and its refund.

  • Set your webhook URL and copy your signing secret on your key page. The URL must be https://. One URL receives every event for your account.

  • Webhooks are sent for orders you place through the API. Each one carries the whole order as it is now, so you never need a second call to know where things stand.

  • Answer with any 2xx status within 10 seconds. Save the event and do the slow work afterwards.

  • If your server does not answer 2xx, we try again after about 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours (7 attempts in all). You can see every delivery, and resend failed ones, on your key page.

  • The same event can arrive more than once, and events can arrive out of order. Use eventId to ignore repeats, and trust the newest order or transaction you have received (or call Get Orders or Fetch Transaction Status).

Headers

HeaderMeaning
Content-TypeAlways application/json.
X-Gsubz-EventThe event name, for example store.order.updated.
X-Gsubz-DeliveryThe unique ID of this event (the same as eventId in the body). Retries of the same event keep the same ID, so use it to ignore duplicates.
X-Gsubz-TimestampUnix time (seconds) when this attempt was sent.
X-Gsubz-Signaturesha256= followed by the HMAC-SHA256 of timestamp + "." + raw body, made with your signing secret.

Events

Eventdata.change.typeWhen
transaction.updatedCOMPLETEDThe final result of a data, airtime, cable TV, electricity, exam pin or social media purchase (/api/pay/), sent when the call took longer than 10 seconds or the connection closed before our answer reached you. So a short timeout on your side never leaves you guessing. reason is SLOW_RESPONSE or CLIENT_DISCONNECTED, and processingSeconds is how long it took. Sent at most once per transaction.
transaction.updatedREFUNDEDA purchase that had already answered was refunded to your wallet later, for example by our support team, or because the provider cancelled a social media order: from, to (failed), refundNgn and reason (ADMIN or PROVIDER_CANCELLED). The transaction's status is now failed and amountRefunded shows the refund. Sent at most once per transaction.
store.order.updatedORDER_PLACEDAn order you placed through the API was created and paid.
store.order.updatedSTATUSAn item moved to a new status (from, to). A cancellation also carries refund (totalNgn, itemNgn, serviceFeeNgn, shippingNgn, deliveryNgn) and reason.
store.order.updatedSHIPPING_FEEAn item was weighed and its shipping fee was set or changed (previousUnitNgn, unitNgn). The item's shipping in order has the new weightKg, volumeCbm and dueNgn. Pay with Pay Shipping when dueNgn is more than 0.
store.order.updatedSHIPPING_METHODAn item had to switch between air and sea (from, to), with its new fee and any refund (refundNgn).
store.order.updatedSHIPPING_PAIDShipping you paid was received (items, amountNgn).
store.order.updatedTRACKINGThe delivery tracking number for the pickup station was added (trackingNumber).
flight.order.updatedCONFIRMEDA flight you booked was confirmed. order carries the pnr and tickets when they are already issued.
flight.order.updatedTICKETEDThe PNR and e-ticket numbers arrived after the booking was confirmed.
flight.order.updatedREFUNDEDA flight booking failed or was cancelled by the airline, and your wallet was refunded: reason (FAILED or CANCELLED) and refundNgn.
games.order.updatedSTATUSA game order that was still processing when Buy Game Top-up answered has finished (from, to). to is completed (any gift-card codes are in order) or refunded (your wallet was refunded). Not sent when the purchase response already gave the final result.
webhook.test-Sent when you press "Send test event" on your key page.

Every event has event, eventId, createdAt and data. Transaction events carry data.change (what happened) and data.transaction: the purchase as it is now, with the fields of the purchase response plus requestID, description and amountRefunded. Store order events carry data.change (what happened) and data.order: the whole order as it is now, in the same format as Get Orders. Flight events carry data.change and data.order in the format of Fetch Flight Orders. Game events carry data.change and data.order in the format of one order from Fetch Game Orders.

Example body

Data, airtime and bills (a refund)

{
  "event": "transaction.updated",
  "eventId": "evt_7d41c2b9e0a35f6d8c12ab90",
  "createdAt": "2026-10-19T10:20:05+01:00",
  "data": {
    "change": { "type": "REFUNDED", "from": "successful", "to": "failed", "refundNgn": 2284.56, "reason": "ADMIN" },
    "transaction": {
      "transactionID": 3878886201,
      "requestID": "8dhbc8w7huwh8hw9hew9",
      "serviceID": "mtn_sme",
      "status": "failed",
      "description": "TRANSACTION_REVERSED",
      "amount": 2400,
      "amountPaid": 0,
      "amountRefunded": 2284.56,
      "phone": "08031234567",
      "initialBalance": 5000,
      "finalBalance": 2715.44,
      "date": "2026-10-19T09:47:15+01:00",
      "api_response": "Dear Customer, You have successfully shared 10GB Data to 2348031234567. Thankyou"
    }
  }
}

Store order

{
  "event": "store.order.updated",
  "eventId": "evt_8f2c1d0a9b7e6f5a4c3b2a19",
  "createdAt": "2026-10-16T13:02:44+01:00",
  "data": {
    "change": { "type": "SHIPPING_FEE", "itemId": 88121, "previousUnitNgn": 0, "unitNgn": 13068 },
    "order": {
      "orderId": 5231,
      "reference": "ORDER-10045",
      "amounts": { "itemsNgn": 14100, "serviceFeeNgn": 1900, "shippingPaidNgn": 16676, "shippingDueNgn": 13068, "deliveryNgn": 2400 },
      "items": [
        {
          "itemId": 88121,
          "status": "PAID",
          "shipping": { "method": "air", "weightKg": 0.9, "volumeCbm": 0.001, "status": "due", "unitNgn": 13068, "totalNgn": 13068, "paidNgn": 0, "dueNgn": 13068 }
        }
      ]
    }
  }
}

Flight booking

{
  "event": "flight.order.updated",
  "eventId": "evt_3c9a77d1b0e24f6a8d15c2e7",
  "createdAt": "2026-10-17T11:04:10+01:00",
  "data": {
    "change": { "type": "CONFIRMED" },
    "order": {
      "transactionID": "TRV261017110002AB12CD34",
      "requestID": "flight-1001",
      "orderStatus": "completed",
      "origin": "LOS",
      "destination": "ABV",
      "departureDate": "2026-12-01",
      "amountPaid": 95000,
      "pnr": "ABC123",
      "tickets": [
        { "name": "Ada Obi", "type": "ADT", "ticketNumber": "1234567890123" }
      ]
    }
  }
}

Game order

{
  "event": "games.order.updated",
  "eventId": "evt_5b1e93c0d7a24f88b6e01c4d",
  "createdAt": "2026-10-17T13:54:33+01:00",
  "data": {
    "change": { "type": "STATUS", "from": "processing", "to": "completed" },
    "order": {
      "orderID": 15,
      "transactionID": "GM261007113015A1B2C3D4",
      "requestID": "game-1001",
      "game": "Free Fire · Direct Topup Mena",
      "product": "100 Diamonds",
      "amount": 1520,
      "amountPaid": 1520,
      "amountRefunded": 0,
      "orderStatus": "completed",
      "playerName": "ProGamer99",
      "codes": [],
      "date": "2026-10-07T11:30:15+01:00"
    }
  }
}

Check the signature

Always check X-Gsubz-Signature before you trust a webhook, using the raw body exactly as received.

PHP

<?php
$secret = 'whsec_...';                       // from your key page
$body   = file_get_contents('php://input');  // the RAW body, before json_decode
$ts     = $_SERVER['HTTP_X_GSUBZ_TIMESTAMP'] ?? '';
$sig    = $_SERVER['HTTP_X_GSUBZ_SIGNATURE'] ?? '';

$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($expected, $sig) || abs(time() - (int)$ts) > 300) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);
// Save it, skip it if you already have $event['eventId'], then do the work later.
http_response_code(200);
echo 'ok';

Node.js

// Express: use the raw body for the signature
app.post('/gsubz/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-Gsubz-Timestamp');
  const expected = 'sha256=' + crypto.createHmac('sha256', process.env.GSUBZ_WEBHOOK_SECRET)
    .update(ts + '.' + req.body).digest('hex');
  const got = req.get('X-Gsubz-Signature') || '';
  if (got.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body);
  // Save it, skip it if you already have event.eventId, then do the work later.
  res.send('ok');
});

Service IDs

Use the serviceID exactly as shown, including capitals and underscores. This list is generated live from our system, so it is always current. Click a row to copy its ID. Want this in a single API call instead? See List All Services.

Airtime 4 services
ServiceserviceID
Airtel Airtime airtel
Glo Airtime glo
MTN Airtime mtn
T2 (formerly 9mobile) Airtime etisalat
Data Subscription 6 services
ServiceserviceID
Airtel Gifting Data airtel_gifting
Airtel SME Data airtel_sme
Glo Corporate Gifting Data glo_data
Glo SME Data glo_sme
MTN Gifting Data mtn_gifting
MTN SME Data mtn_sme
Education (Result Pins) 3 services
ServiceserviceID
NABTEB Result Pin nabteb
NECO Result Pin neco
WAEC Result Pin waec
Electricity Billl 12 services
ServiceserviceID
Aba (ABEDC/APL) aba-electric
Abuja (AEDC) abuja-electric
Benin (BEDC) benin-electric
Eko (EKEDC) eko-electric
Enugu (EEDC) enugu-electric
Ibadan (IBEDC) ibadan-electric
Ikeja (IKEDC) ikeja-electric
Jos (JEDC) jos-electric
Kaduna KAEDCO) kaduna-electric
Kano (KEDCO) kano-electric
Port Harcourt (PHED) portharcourt-electric
Yola (YEDC) yola-electric
Pro Services/Apps 1 service
ServiceserviceID
Canva Pro canva
Socials Media Market 1 service
ServiceserviceID
Socials Media Market socials
TV Subscriptions 3 services
ServiceserviceID
DSTV dstv
GOTV gotv
Startimes startimes
Uncategorised 1 service
ServiceserviceID
MTN-SME-Datashare mtn_datashare

API reference

MethodEndpointWhat it does
POST /api/balance/ Fetch Wallet Balance Get your current wallet balance in naira.
GET /api/category/ List All Services List every active service, grouped by category.
GET /api/plans/ Get Plans List the plans, and their prices, for any data, cable TV or social media service.
POST /api/verify-customer/ Verify Meter / IUC Number Check an electricity meter or cable smartcard number and get the customer name before paying.
POST /api/pay/ Buy Data Send a data bundle to a phone number.
POST /api/pay/ Buy Airtime Send airtime to a phone number on MTN, Airtel, 9mobile or Glo.
POST /api/pay/ Buy TV / Decoder / Cable Sub Renew a DStv, GOtv or StarTimes subscription.
POST /api/pay/ Buy Electric Token Buy a prepaid electricity token or pay a postpaid electricity bill.
POST /api/pay/ Buy Exam Pin Buy a WAEC, NECO or NABTEB result checker or registration pin.
POST /api/pay/ Buy Social Media Service Place a social media order such as followers or likes.
POST /api/generate/ Recharge Pins / Epins Printing Generate recharge card pins for MTN, Airtel, Glo or 9mobile.
GET /api/generate/history/ Fetch Recharge Pin Orders List your last 200 recharge pin orders, or fetch one order with its pins.
GET /api/esim/countries/ List eSIM Countries List the countries and regions you can buy an eSIM for.
GET /api/esim/packages/ List eSIM Packages List the eSIM packages for a country, cheapest first, priced in naira.
POST /api/esim/buy/ Buy eSIM Buy an eSIM package and get its QR code and activation code.
POST /api/esim/orders/ Fetch eSIM Orders Look up your eSIM orders, or check one that was still being prepared.
POST /api/esim/cancel/ Cancel eSIM Cancel an eSIM that has not been installed and get your money back.
GET /api/games/list/ List Games List the games and gift-card brands on sale, with the lowest price of each.
GET /api/games/products/ List Game Products List the product lines, required fields and prices for one game.
POST /api/games/validate/ Validate Player ID Check a player ID, and get the player's name, before you charge for a top-up.
POST /api/games/buy/ Buy Game Top-up Top up a game account, or buy a gift card, and get the result or the codes.
POST /api/games/orders/ Fetch Game Orders Look up your game orders, or check one that was still processing.
POST /api/sms/ Send Bulk SMS Send one text message to many Nigerian phone numbers.
GET /api/flight/search/ List Airports Find the airport codes to search with. Free.
POST /api/flight/search/ Search Flights Search one-way or return flights and get priced options. Free.
POST /api/flight/book/ Book a Flight Lock the final price, or book the flight and pay from your wallet. preview=true only returns the price.
POST /api/flight/orders/ Fetch Flight Orders Look up a flight booking, or check one that was still processing. Free.
GET /api/store/search/ Search Products Browse trending products, the Gsubz Official Store, or search the whole product catalogue by keyword.
POST /api/store/image-search/ Search Products by Image Find products that look like a photo you send.
GET /api/store/product/ Get Product Details Get everything the store shows for one product: media, price tiers, variants, specs and shipping data.
GET /api/store/supplier/ Get Supplier Products List the products of one supplier, 20 at a time.
GET /api/store/categories/ List Categories and Brands Get the store's category tree and the Official Store brands. Free.
GET /api/store/order/ List Pickup Stations Get the pickup stations an order can be delivered to, with their delivery fees. Free.
POST /api/store/order/ Place an Order Buy products for your customer, paid from your wallet. preview=true only returns the price.
GET /api/store/order/ Get Orders Get one order by order_id or reference, or a page of your orders. Free.
POST /api/store/order/ Cancel an Order Cancel a whole order, or one item, within 2 hours of ordering. Refunded to your wallet.
POST /api/store/order/ Pay Shipping Pay shipping that became due after an item was weighed.
POST /api/verify/ Fetch Transaction Status Look up the status and response of a purchase using its requestID or transactionID.

All purchases (data, airtime, cable, electricity, exam pins and social media) use the same POST /api/pay/ endpoint. The serviceID you send decides what is bought. eSIMs have their own endpoints under /api/esim/, bulk SMS uses POST /api/sms/, game top-ups and gift cards have their own endpoints under /api/games/, and the product store has its own endpoints under /api/store/, where /api/store/order/ places and manages orders.

Wallet

POST

Fetch Wallet Balance

#

Returns your current wallet balance in naira (₦). Check it before a purchase so you can top up before a transaction fails with INSUFFICIENT_BALANCE.

Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. balance is returned as a string. Convert it to a number before doing arithmetic.

Request
curl --location 'https://api.gsubz.com/api/balance/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"'
Example response 200 OK
{
  "balance": "747.5"
}

Services

GET

List All Services

#

Returns every active serviceID GSUBZ offers, grouped under its category — data, cable TV, electricity, social media and so on. Call this once to build a full picture of what's available, then use Get Plans for a specific service's pricing. No parameters: it always returns everything in one response, so filter or sort on your side.

No authentication needed
No parameters. It always returns everything in one response — filter or sort on your side.
Try it live

This endpoint is public, so no API key is needed.

About the response. A category with no active services still appears, with an empty services array. image is null when the category has no icon set. This list is cached for up to 60 seconds, so a change can take up to a minute to show here.

Request
curl --location 'https://api.gsubz.com/api/category/'
Example response 200 OK
[
  {
    "name": "electricity",
    "displayName": "Electricity",
    "image": "//gsubz.com/uploads/2021/9/1/electric-icon.png",
    "services": [
      {
        "serviceID": "eko-electric",
        "displayName": "Eko (EKEDC)"
      },
      {
        "serviceID": "kaduna-electric",
        "displayName": "Kaduna Electric"
      }
    ]
  },
  {
    "name": "cable",
    "displayName": "Cable TV",
    "image": "//gsubz.com/uploads/2021/9/1/cable-icon.png",
    "services": [
      {
        "serviceID": "gotv",
        "displayName": "GOtv"
      }
    ]
  }
]

Plans

GET

Get Plans

#

One shared endpoint for every category's plan list: data, cable TV, social media and more. Pass the service you want and get back that service's plans. Call it before a purchase to get the correct plan value. Every plan shows its normal price and its api_price, the price you pay through the API.

  • The plan identifier is returned in a field called PlanName, and its value tells you which body field to submit when buying. Data and social media services use plan. Cable TV services use variation_code.
No authentication needed
Query parameter Description
service string Required The service ID, for example mtn_sme. Also accepts cable (gotv, dstv, startimes) and social media (socials) service IDs. See Service IDs.
Example: mtn_sme
Try it: live plan lookup
Pick a category and a service, then send the request.

This sends a real GET /api/plans/ request, so you see an actual response before you write any code.

About the response. Use value as your plan (or variation_code) when you buy. price is the normal price and api_price is the price you pay through the API, both in naira. discount is your API discount on this service.

Request
curl --location 'https://api.gsubz.com/api/plans/?service=mtn_sme'
Example response 200 OK
{
  "service": "MTN-SME-Data(*461*4#)",
  "PlanName": "plan",
  "fixedPrice": true,
  "discount": "4.81%",
  "plans": [
    {
      "displayName": "10GB - 30days",
      "value": "260",
      "price": "2400",
      "api_price": "2284.56"
    }
  ]
}

Verify Customer

POST

Verify Meter / IUC Number

#

Checks a meter number or a cable smartcard/IUC number before payment and returns the customer's name (and, for electricity meters, their address and account type). Always verify before you charge: it catches typing mistakes before money moves.

  • For electricity services, type is required: prepaid or postpaid. For cable services (dstv, gotv, startimes), leave type out.
Requires your API key as a Bearer token
Available service IDs (live from our system, click to copy)
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
serviceID string Required Any electricity or cable service ID: see the list below, or dstv, gotv, startimes for cable. Underscores and hyphens both work, so kaduna_electric and kaduna-electric are the same.
Example: kaduna_electric
billersCode string Required The meter number (electricity) or smartcard/IUC number (cable).
Example: 00000000000
type string Electricity only prepaid or postpaid. Required for electricity, omit for cable.
Example: prepaid
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. Some fields, such as accountType, can be null when the provider does not send them. Cable verification returns customerName, status, dueDate, customerNumber and customerType instead of the address and meter fields. Both shapes are under content, so you can always read customerName the same way.

Request
curl --location 'https://api.gsubz.com/api/verify-customer/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'serviceID="kaduna_electric"' \
--form 'billersCode="00000000000"' \
--form 'type="prepaid"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "description": "CUSTOMER_FOUND",
  "content": {
    "customerName": "JOHN ADEBAYO",
    "address": "12 SAMPLE STREET, IKEJA",
    "meterNumber": "45000000000",
    "meterType": "PREPAID",
    "accountType": null,
    "canVend": "yes"
  }
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "Could not verify this meter number"
}

Data & Airtime

POST

Buy Data

#

Send a data bundle to any Nigerian phone number. Call Get Plans with the network's serviceID first to get the exact plan value, then submit it here. The data service IDs are listed under Service IDs.

Requires your API key as a Bearer token
Body field Description
serviceID string Required The data service ID, for example mtn_sme.
Example: mtn_sme
plan string Required The plan value from Get Plans for this service.
Example: 260
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
amount string Required Send as an empty string. The price is set by the plan.
Example: empty string
phone string Required The phone number to receive the data.
Example: 08031234567
requestID string Optional Your own unique reference for this order (for example your order ID). Use it later with Fetch Transaction Status.
Example: 8dhbc8w7huwh8hw9hew9
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="mtn_sme"' \
--form 'plan="260"' \
--form 'api="YOUR_API_KEY"' \
--form 'amount=""' \
--form 'phone="08031234567"' \
--form 'requestID="8dhbc8w7huwh8hw9hew9"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3878886201,
  "amount": 2400,
  "phone": "08031234567",
  "serviceID": "mtn_sme",
  "amountPaid": 2284.56,
  "initialBalance": 5000,
  "finalBalance": 2715.44,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "Dear Customer, You have successfully shared 10GB Data to 2348031234567. Thankyou"
}
POST

Buy Airtime

#

Send airtime to any Nigerian number. The serviceID must be one of mtn, airtel, etisalat (9mobile) or glo: lowercase, spelt exactly as shown.

Requires your API key as a Bearer token
Available service IDs (live from our system, click to copy)
Body field Description
serviceID string Required mtn, airtel, etisalat (9mobile) or glo.
Example: mtn
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
amount string Required Amount of airtime in naira. The minimum is ₦100.
Example: 100
phone string Required The phone number to receive the airtime.
Example: 08031234567
requestID string Optional Your own unique reference for this order (for example your order ID). Use it later with Fetch Transaction Status.
Example: 8dhbc8w7huwh8hw9hew9
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="mtn"' \
--form 'api="YOUR_API_KEY"' \
--form 'amount="100"' \
--form 'phone="08031234567"' \
--form 'requestID="8dhbc8w7huwh8hw9hew9"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3768661863,
  "amount": 800,
  "phone": "08031234567",
  "serviceID": "mtn",
  "amountPaid": 768,
  "initialBalance": 5000,
  "finalBalance": 4232,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "You have topped up N800.00 to 2348031234567. ref: 2026092809402519057879292"
}

Cable TV

POST

Buy TV / Decoder / Cable Sub

#

Renew a DStv, GOtv or StarTimes subscription. The serviceID must be gotv, dstv or startimes. Verify the smartcard/IUC number with Verify Meter / IUC Number first.

  • For cable, Get Plans returns the package identifier as variation_code. Send that value in the variation_code field.
Requires your API key as a Bearer token
Body field Description
serviceID string Required dstv, gotv or startimes.
Example: gotv
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
variation_code string Required The package from Get Plans (service=gotv, dstv or startimes).
Example: gotv-smallie
phone string Required Customer phone number. Can be any valid number.
Example: 08031234567
amount string Required Send as an empty string. The price is set by the plan.
Example: empty string
customerID string Required The IUC or smartcard number of the decoder.
Example: 0000000000
requestID string Optional Your own unique reference for this order (for example your order ID). Use it later with Fetch Transaction Status.
Example: 8dhbc8w7huwh8hw9hew9
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="gotv"' \
--form 'api="YOUR_API_KEY"' \
--form 'variation_code="gotv-smallie"' \
--form 'phone="08031234567"' \
--form 'amount=""' \
--form 'customerID="0000000000"' \
--form 'requestID="8dhbc8w7huwh8hw9hew9"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3685573902,
  "amount": 900,
  "phone": "08031234567",
  "serviceID": "gotv",
  "amountPaid": 882,
  "initialBalance": 5000,
  "finalBalance": 4118,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "Your GOtv subscription was successful."
}

Electricity

POST

Buy Electric Token

#

Generate an electricity token (prepaid) or pay a postpaid bill for any supported distribution company. Verify the meter number first with Verify Meter / IUC Number so your customer sees their own name before you charge them.

Requires your API key as a Bearer token
Available service IDs (live from our system, click to copy)
Body field Description
serviceID string Required The distribution company service ID. See the list below.
Example: kaduna_electric
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
phone string Required Customer phone number. Can be any valid number.
Example: 08031234567
customerID string Required The meter number.
Example: 00000000000
amount string Required Amount of electricity to buy, in naira.
Example: 1100
variation_code string Required prepaid or postpaid.
Example: prepaid
requestID string Optional Your own unique reference for this order (for example your order ID). Use it later with Fetch Transaction Status.
Example: 8dhbc8w7huwh8hw9hew9
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="kaduna_electric"' \
--form 'api="YOUR_API_KEY"' \
--form 'phone="08031234567"' \
--form 'customerID="00000000000"' \
--form 'amount="1100"' \
--form 'variation_code="prepaid"' \
--form 'requestID="8dhbc8w7huwh8hw9hew9"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3574357094,
  "amount": 1100,
  "phone": "08031234567",
  "serviceID": "kaduna_electric",
  "amountPaid": 1100,
  "initialBalance": 5000,
  "finalBalance": 3900,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "Token: 47488383838383838383833"
}

Exam Pins

POST

Buy Exam Pin

#

Buy an exam pin. The serviceID must be waec, neco or nabteb: lowercase, spelt exactly as shown. Each exam service has one plan.

Requires your API key as a Bearer token
Body field Description
serviceID string Required waec, neco or nabteb.
Example: waec
plan string Required The plan for the exam service. There is one plan per service; for WAEC it is waecdirect.
Example: waecdirect
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
amount string Required Send as an empty string. The price is set by the plan.
Example: empty string
phone string Required Customer phone number.
Example: 08031234567
requestID string Optional Your own unique reference for this order. Use it later with Fetch Transaction Status.
Example: 87dfhw8dbw8e7hw9d9dh
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="waec"' \
--form 'plan="waecdirect"' \
--form 'api="YOUR_API_KEY"' \
--form 'amount=""' \
--form 'phone="08031234567"' \
--form 'requestID="87dfhw8dbw8e7hw9d9dh"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3075647209,
  "amount": 3500,
  "phone": "08031234567",
  "serviceID": "waec",
  "amountPaid": 3500,
  "initialBalance": 5000,
  "finalBalance": 1500,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "968686868685<=>WRN2056666666"
}

Social Media Market

POST

Buy Social Media Service

#

Place a social media order. The serviceID is always socials. Call Get Plans with service=socials first to get the plan value for the service you want (for example Instagram followers or TikTok likes).

Requires your API key as a Bearer token
Body field Description
serviceID string Required Always socials.
Example: socials
plan string Required The plan value from Get Plans (service=socials).
Example: 179
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
amount string Required Send as an empty string. The price is set by the plan.
Example: empty string
link string Required The profile or post URL the order should be delivered to.
Example: https://instagram.com/gsubzonline
quantity integer Required How many to deliver. Must be a positive whole number.
Example: 1000
requestID string Optional Your own unique reference for this order (for example your order ID). Use it later with Fetch Transaction Status.
Example: 8dhbc8w7huwh8hw9hew9
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. Values are examples. Read status (successful or failed) to know the outcome, and see Responses for every field.

Request
curl --location 'https://api.gsubz.com/api/pay/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'serviceID="socials"' \
--form 'plan="179"' \
--form 'api="YOUR_API_KEY"' \
--form 'amount=""' \
--form 'link="https://instagram.com/gsubzonline"' \
--form 'quantity="1000"' \
--form 'requestID="8dhbc8w7huwh8hw9hew9"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3075647200,
  "amount": 179,
  "serviceID": "socials",
  "amountPaid": 179,
  "initialBalance": 5000,
  "finalBalance": 4821,
  "date": "2026-09-28T09:47:15+01:00",
  "api_response": "Order received. Order ID: 39554883"
}

Recharge Pins

POST

Recharge Pins / Epins Printing

#

Generate recharge card pins for printing. The network must be mtn, airtel, glo or 9mobile: lowercase, spelt exactly as shown. This endpoint authenticates with the Authorization header only.

  • If you get UNABLE_TO_PROCESS_REQUEST, or no response at all, do not resend the order straight away. Check Fetch Recharge Pin Orders first: if the order is listed, it went through and your pins are there. Only send a new order when it is not listed.
Requires your API key as a Bearer token
Body field Description
network string Required mtn, airtel, glo or 9mobile.
Example: airtel
value string Required Face value of each pin in naira: 100, 200, 400 or 500.
Example: 500
number string Required How many pins to generate. The minimum is 10 for values below 500.
Example: 1
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and delivers to the phone number or account you enter. Use small amounts when you are testing.

About the response. delivered and pending show how many pins have been issued so far. Each item in pins has the pin and its serial number sn.

Request
curl --location 'https://api.gsubz.com/api/generate/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'network="airtel"' \
--form 'value="500"' \
--form 'number="1"'
Example response 200 OK
{
  "message": "We Received your order, 1 of 1 delivered\n Thank you for your patronage",
  "status": "success",
  "id": "c143e774874a59623aa928292d128f97",
  "network": "Airtel",
  "value": "500",
  "number": "1",
  "delivered": "1",
  "pending": 0,
  "pins": [
    {
      "pin": "5794977707301520",
      "sn": "26026825914918714922"
    }
  ]
}
GET

Fetch Recharge Pin Orders

#

Returns your recent Recharge Pins orders, newest first, so you can compare them with your own records. If an order timed out or its response never reached you, the pins are here: read them from this endpoint instead of resending the order. Send an order_id to get just one order. This endpoint is free and authenticates with the Authorization header only. It also accepts POST.

  • Every order comes with its pins (the pin and its serial number sn), so you can save any you did not receive. A long list can be large: use limit for fewer orders, or order_id for one. Send pins=0 if you only want the order details.
  • order_id is the id returned when you placed the order.
Requires your API key as a Bearer token
Query parameter Description
limit integer Optional How many orders to return, from 1 to 200. The default is 200.
Example: 200
order_id string Optional Return only this order, with its pins. Use the id from the order response.
Example: c143e774874a59623aa928292d128f97
pins string Optional Pins are included by default. Send 0 to leave them out.
Example: 0
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. status is success when every pin you asked for was delivered, partial when only some were, and failed when none were. requested and delivered are pin counts. pins lists every pin issued for the order, and is empty for an order that failed.

Request
curl --location 'https://api.gsubz.com/api/generate/history/' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": "200",
  "status": "TRANSACTION_SUCCESSFUL",
  "count": 1,
  "orders": [
    {
      "order_id": "c143e774874a59623aa928292d128f97",
      "description": "Airtel-500-1 28/09/2026",
      "network": "airtel",
      "value": "500",
      "requested": 1,
      "delivered": 1,
      "amount_paid": "485",
      "status": "success",
      "timestamp": 1790585235,
      "date": "2026-09-28 09:47:15",
      "pins": [
        {
          "pin": "5794977707301520",
          "sn": "26026825914918714922"
        }
      ]
    }
  ]
}
Example error response 404
{
  "code": "404",
  "description": "ORDER_NOT_FOUND",
  "status": "TRANSACTION_FAILED"
}

eSIM

GET

List eSIM Countries

#

An eSIM gives your customer mobile data in another country without a physical SIM card. Start here: list the countries, pick one, then call List eSIM Packages with its locationCodes. This list is public and needs no API key.

No authentication needed
Query parameter Description
q string Optional Search text to filter countries by name, for example fra for France. Leave it out to list every country.
Example: fra
Try it live

This endpoint is public, so no API key is needed.

About the response. locationCodes can hold more than one code, separated by commas. Send the whole value as locationCode to List eSIM Packages. plans is how many packages exist for that country.

Request
curl --location 'https://api.gsubz.com/api/esim/countries/?q=fra'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "countries": [
    {
      "country": "France",
      "locationCodes": "FR",
      "plans": 12
    },
    {
      "country": "Spain",
      "locationCodes": "ES",
      "plans": 9
    }
  ]
}
GET

List eSIM Packages

#

Returns the data packages for one country, cheapest first. Use the packageCode of the one your customer wants when you call Buy eSIM. This list is public and needs no API key.

  • price is in naira and can change slightly between this list and your purchase, because the live price is checked when you buy. Read amountPaid in the purchase response for what was actually charged.
No authentication needed
Query parameter Description
locationCode string Required The locationCodes value from List eSIM Countries. You can send up to twenty codes, separated by commas.
Example: FR
Try it live

This endpoint is public, so no API key is needed.

About the response. dataGB is the data allowance and duration is how long the package lasts, in durationUnit. A package with refundable set to false cannot be cancelled for a refund. topUp shows whether more data can be added later.

Request
curl --location 'https://api.gsubz.com/api/esim/packages/?locationCode=FR'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "packages": [
    {
      "packageCode": "FR_1_7",
      "name": "France 1GB 7Days",
      "country": "France",
      "dataGB": 1,
      "duration": 7,
      "durationUnit": "DAY",
      "price": 2607,
      "refundable": true,
      "topUp": true
    }
  ]
}
POST

Buy eSIM

#

Buys one eSIM. Your wallet is charged and the eSIM details come back in the response: scan the qrCodeUrl image or type the activationCode into the phone to install it.

  • Always send a requestID. If you send the same one again, the API returns the original order (code 406, INVALID_ARGUMENTS_DUPLICATE_REQUEST_ID) and never charges twice.
  • If esimStatus is provisioning, the eSIM is still being prepared. Call Fetch eSIM Orders in a minute to get the QR code and activation code. You have already been charged.
Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
packageCode string Required The packageCode from List eSIM Packages.
Example: FR_1_7
requestID string Optional Your own unique reference for this order, up to 100 characters. Use it later with Fetch eSIM Orders.
Example: esim-1001
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This is a real purchase. Sending it deducts money from your wallet and creates a real eSIM. Choose the cheapest package when you are testing.

About the response. esimStatus is active when the eSIM is ready to install, or provisioning while it is still being prepared (then iccid, activationCode and qrCodeUrl are null). Keep orderID: you need it to cancel or look the order up.

Request
curl --location 'https://api.gsubz.com/api/esim/buy/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'packageCode="FR_1_7"' \
--form 'requestID="esim-1001"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": "ESIMA0BA0EC673A45212",
  "orderID": 1,
  "amount": 3476,
  "serviceID": "esim",
  "amountPaid": 3476,
  "initialBalance": 100000,
  "finalBalance": 96524,
  "date": "2026-09-28T12:36:59+01:00",
  "api_response": "Your eSIM is ready. Scan the QR code or enter the activation code to install it.",
  "requestID": "esim-1001",
  "packageCode": "FR_1_7",
  "packageName": "France 1GB 7Days",
  "country": "France",
  "esimStatus": "active",
  "iccid": "8944500102030405060",
  "activationCode": "LPA:1$rsp.example.com$ABCD-1234-EFGH",
  "qrCodeUrl": "https://example.com/qr/ORD-123"
}
Example error response 402
{
  "code": 402,
  "status": "failed",
  "description": "INSUFFICIENT_BALANCE",
  "api_response": "Insufficient balance. This eSIM costs ₦3,476.00 but your wallet has ₦100.00."
}
POST

Fetch eSIM Orders

#

Returns your eSIM orders. Send a requestID or an orderID to get one order, or send neither to list your last 50. An order that was still being prepared is checked again each time you call, so this is also how you collect the QR code after a provisioning purchase.

Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
requestID string Optional The requestID you sent when you bought the eSIM.
Example: esim-1001
orderID integer Optional The orderID from the purchase response.
Example: 1
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. esimStatus is one of active, provisioning, refunded or failed. amountRefunded shows what was returned to your wallet, if anything.

Request
curl --location 'https://api.gsubz.com/api/esim/orders/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'requestID="esim-1001"' \
--form 'orderID="1"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "orders": [
    {
      "orderID": 1,
      "transactionID": "ESIMA0BA0EC673A45212",
      "packageCode": "FR_1_7",
      "packageName": "France 1GB 7Days",
      "country": "France",
      "amountPaid": 3476,
      "amountRefunded": 0,
      "esimStatus": "active",
      "iccid": "8944500102030405060",
      "activationCode": "LPA:1$rsp.example.com$ABCD-1234-EFGH",
      "qrCodeUrl": "https://example.com/qr/ORD-123",
      "date": "2026-09-28T12:36:59+01:00"
    }
  ]
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "No eSIM order found for that reference."
}
POST

Cancel eSIM

#

Cancels an eSIM that has not been installed and returns what you paid to your wallet. It can only work once for each order.

Only an unused eSIM can be cancelled. If it has already been installed, used or refunded, the request is refused with NOT_CANCELLABLE and nothing is refunded.
Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
orderID integer Required The orderID from the purchase response or from Fetch eSIM Orders.
Example: 1
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This cancels a real eSIM. If it works, the eSIM stops working and the money is returned to your wallet. Only cancel an eSIM you have not installed.
Request
curl --location 'https://api.gsubz.com/api/esim/cancel/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'orderID="1"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "orderID": 1,
  "amountRefunded": 3476,
  "initialBalance": 96524,
  "finalBalance": 100000,
  "date": "2026-09-28T12:37:22+01:00",
  "api_response": "Refunded ₦3,476.00."
}
Example error response 406
{
  "code": 406,
  "status": "failed",
  "description": "NOT_CANCELLABLE",
  "api_response": "This eSIM cannot be cancelled. It may already be in use."
}

Games

GET

List Games

#

Top up a player's game account or sell a gift card. Start here: list the games and brands on sale, most popular first, then call List Game Products with the gameID you want. This list is public and needs no API key.

No authentication needed
Query parameter Description
q string Optional Search text to filter by name, for example free for Free Fire. Leave it out to list everything.
Example: free
Try it live

This endpoint is public, so no API key is needed.

About the response. lines is how many product lines the game has (for example one per region) and products is how many amounts or packs you can buy. fromPrice is the lowest price in naira. note is an important message about the game, or null. image is null when the game has no logo. The example is shortened.

Request
curl --location 'https://api.gsubz.com/api/games/list/?q=free'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "games": [
    {
      "gameID": 12,
      "name": "Free Fire",
      "image": "https://gsubz.com/uploads/gaming/free-fire.png",
      "note": null,
      "lines": 2,
      "products": 24,
      "fromPrice": 1440
    },
    {
      "gameID": 20,
      "name": "Roblox",
      "image": "https://gsubz.com/uploads/gaming/roblox.png",
      "note": "Codes arrive within seconds.",
      "lines": 1,
      "products": 8,
      "fromPrice": 8000
    }
  ]
}
GET

List Game Products

#

Returns the product lines of one game, each with the fields the player must give and the amounts or packs you can buy, priced in naira. Use a productID from here with Validate Player ID and Buy Game Top-up. This list is public and needs no API key.

  • A game can have several product lines, usually one for each region. A player's account only works with the line for its own region, so check region and use Validate Player ID before charging. Each line has its own requirements: send every field it lists, using its field name, when you validate or buy.
No authentication needed
Query parameter Description
gameID integer Required The gameID from List Games.
Example: 12
Try it live

This endpoint is public, so no API key is needed.

About the response. price is in naira and is exactly what a purchase charges (it is checked live when you buy). kind is amount for a top-up of an amount, or pack for a bundle, pass or gift card. inStock is true, false (cannot be bought right now) or null (not known, the purchase is still attempted). options lists the allowed values when a field is a choice, such as a server. Gift cards have an empty requirements list. The example is shortened.

Request
curl --location 'https://api.gsubz.com/api/games/products/?gameID=12'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "game": {
    "gameID": 12,
    "name": "Free Fire",
    "image": "https://gsubz.com/uploads/gaming/free-fire.png",
    "note": null
  },
  "lines": [
    {
      "lineID": 467,
      "name": "Direct Topup Mena",
      "region": "Mena",
      "requirements": [
        {
          "field": "player_id",
          "label": "Player ID",
          "type": "text",
          "required": true,
          "options": null
        }
      ],
      "products": [
        {
          "productID": "101",
          "name": "100 Diamonds",
          "price": 1520,
          "kind": "amount",
          "inStock": true
        },
        {
          "productID": "102",
          "name": "Weekly Membership",
          "price": 5200,
          "kind": "pack",
          "inStock": null
        }
      ]
    }
  ]
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "That game is not available."
}
POST

Validate Player ID

#

Checks the player's details for a product and returns the player's name (and region, when the game states one), so your customer can confirm it is the right account before you buy. It is free. Always validate before you buy: it catches a wrong ID or the wrong region before any money moves.

  • Send every field the product line lists under requirements, using its field name. Most games need only player_id. Games that need more, such as a zone or server, take those as extra fields named exactly as listed in requirements, for example zone_id. Gift cards need no player details and answer NO_ID_NEEDED.
  • You can make 20 checks every 10 minutes for each API key.
Requires your API key as a Bearer token
Body field Description
productID string Required The productID from List Game Products.
Example: 101
player_id string Optional The player's ID. Needed by most games. It is one of the fields a line lists under requirements.
Example: 12345678
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

Other fields the product line asks for, one name=value on each line.

About the response. playerName and region are null when the game does not give them. description is PLAYER_FOUND or, for products that need no player details, NO_ID_NEEDED.

Request
curl --location 'https://api.gsubz.com/api/games/validate/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'productID="101"' \
--form 'player_id="12345678"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "description": "PLAYER_FOUND",
  "playerName": "ProGamer99",
  "region": "AF",
  "api_response": "Player found."
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "PLAYER_NOT_FOUND",
  "api_response": "We could not find that player ID. Please check it and try again."
}
POST

Buy Game Top-up

#

Buys one game top-up or gift card. Your wallet is charged first. A top-up goes straight to the player's account, and a gift card returns its code or codes in codes. Validate the player with Validate Player ID first.

An order can still be processing. When orderStatus is processing, you have been charged and the order is not finished. It ends as completed or refunded. We send you a webhook (games.order.updated) when it finishes, and you can always check it with Fetch Game Orders. A refund goes back to your wallet automatically, and an order is never refunded while its outcome is unclear.
  • Always send a requestID. If you send the same one again, the API returns the original order (code 406, INVALID_ARGUMENTS_DUPLICATE_REQUEST_ID) and never buys twice. A requestID is free to use again only after a request that was refused before any money moved (for example a wrong player ID or too little balance).
  • Send every field the product line lists under requirements, using its field name. Most games need only player_id. Games that need more, such as a zone or server, take those as extra fields named exactly as listed in requirements, for example zone_id.
Requires your API key as a Bearer token
Body field Description
productID string Required The productID from List Game Products.
Example: 101
player_id string Optional The player's ID. Needed by most games. It is one of the fields a line lists under requirements.
Example: 12345678
requestID string Optional Your own unique reference for this order, up to 100 characters. Use it later with Fetch Game Orders.
Example: game-1001
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

Other fields the product line asks for, one name=value on each line.

This is a real purchase. Sending it deducts money from your wallet and tops up the player's account or issues a gift card. Choose the cheapest product when you are testing.

About the response. orderStatus is completed, or processing while the order is still being delivered. Keep orderID: you need it to look the order up. For a gift card, codes holds one item for each code, with code, serial and expiry, and it can be empty until the order is completed. Treat codes like cash and never log them.

Request
curl --location 'https://api.gsubz.com/api/games/buy/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'productID="101"' \
--form 'player_id="12345678"' \
--form 'requestID="game-1001"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": "GM261007113015A1B2C3D4",
  "orderID": 15,
  "amount": 1520,
  "serviceID": "games",
  "amountPaid": 1520,
  "initialBalance": 100000,
  "finalBalance": 98480,
  "date": "2026-10-07T11:30:15+01:00",
  "api_response": "Your order is complete.",
  "requestID": "game-1001",
  "game": "Free Fire · Direct Topup Mena",
  "product": "100 Diamonds",
  "orderStatus": "completed",
  "playerName": "ProGamer99",
  "codes": []
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "PLAYER_NOT_FOUND",
  "api_response": "We could not find that player ID. Please check it and try again. You have not been charged."
}
POST

Fetch Game Orders

#

Returns your game orders, including orders bought on the website. Send a requestID, an orderID or a transactionID to get one order, or send none of them to list your last 50. An order that is still processing is checked again when you look it up (at most every 25 seconds), so this is also how you collect the result, and any gift-card codes, after a processing purchase if you missed the webhook.

Requires your API key as a Bearer token
Body field Description
requestID string Optional The requestID you sent when you bought.
Example: game-1001
orderID integer Optional The orderID from the purchase response.
Example: 15
transactionID string Optional The transactionID from the purchase response.
Example: GM261007113015A1B2C3D4
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. orderStatus is one of processing, completed or refunded. amountRefunded shows what was returned to your wallet, and amountPaid is what you paid after any refund. requestID is null for orders that were not placed through the API.

Request
curl --location 'https://api.gsubz.com/api/games/orders/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'requestID="game-1001"' \
--form 'orderID="15"' \
--form 'transactionID="GM261007113015A1B2C3D4"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "orders": [
    {
      "orderID": 15,
      "transactionID": "GM261007113015A1B2C3D4",
      "requestID": "game-1001",
      "game": "Free Fire · Direct Topup Mena",
      "product": "100 Diamonds",
      "amount": 1520,
      "amountPaid": 1520,
      "amountRefunded": 0,
      "orderStatus": "completed",
      "playerName": "ProGamer99",
      "codes": [],
      "date": "2026-10-07T11:30:15+01:00"
    }
  ]
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "No game order found for that reference."
}

Bulk SMS

POST

Send Bulk SMS

#

Sends one text message to up to 5,000 Nigerian numbers in a single request. Your wallet is charged first, the message is sent, and anything that could not be sent is refunded automatically.

Your message is checked before anything is charged, because the networks block certain content. These are refused: names of banks and payment companies, international brands such as WhatsApp or Facebook, OTP or verification-code wording, messages that look like bank credit or debit alerts, and any run of four or more digits in a row (write amounts with commas, for example 5,000; years like 2026 are fine). Numbers on the DND list are not delivered by the networks and are not refunded.
  • The field names from, to and msg are the standard names most SMS gateways use, so code written for another SMS service needs very little change. The message type (normal or unicode) is detected for you, so you never send type.
  • You pay per page, per recipient. One page is 160 characters (153 each once the message is longer), or 70 (67) if it has emoji or other special characters. The naira sign is sent as N so it does not turn the message into a special-character one. The price is currently ₦5 per page per recipient, and amount in the response shows exactly what was charged.
  • Numbers are cleaned and de-duplicated. Invalid or repeated numbers are skipped and counted in skipped. If some numbers cannot be sent, the request still returns successful with failed above zero, and those numbers are refunded. If nothing can be sent you get GATEWAY_ERROR and you are not charged.
  • Common failures, all with "status": "failed": INVALID_SENDER, MESSAGE_CONTENT_BLOCKED (with an issues list), NO_VALID_RECIPIENTS, TOO_MANY_RECIPIENTS and MESSAGE_TOO_LONG (code 206), and DUPLICATE_MESSAGE (code 406, the same message to the same list within two minutes and no requestID sent). Send a requestID to send the same message again on purpose.
Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
from string Required The sender name shown on the phone: 3 to 11 letters, with no spaces, numbers or symbols. Names of banks, payment companies, telecoms and government bodies cannot be used.
Example: MyShop
to string Required The phone numbers, separated by commas or new lines, up to 5,000. 080…, 234… and +234… are all accepted.
Example: 08031234567,08021234568
msg string Required The message text, up to 905 characters.
Example: Hello, your order is ready for pickup.
requestID string Optional Your own unique reference for this send, up to 100 characters. Send the same one again and you get the original result back, never a second send or charge. message_uuid is accepted as the same thing.
Example: sms-1001
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This sends real text messages. Your wallet is charged and the numbers you enter will receive the message. To test, put your own phone number in to.

About the response. recipients is how many valid, different numbers were found. sent and failed add up to that, and skipped counts invalid or repeated numbers that were left out. pages is the number of pages per recipient. amount is the full cost and amountPaid is what you were charged after any refund for numbers that were not sent.

Request
curl --location 'https://api.gsubz.com/api/sms/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'from="MyShop"' \
--form 'to="08031234567,08021234568"' \
--form 'msg="Hello, your order is ready for pickup."' \
--form 'requestID="sms-1001"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": 3530235131,
  "amount": 10,
  "serviceID": "bulk_sms",
  "amountPaid": 10,
  "initialBalance": 1000,
  "finalBalance": 990,
  "date": "2026-09-28T12:30:52+01:00",
  "api_response": "Your message was sent to 2 numbers.",
  "reference": "BSMSA260928123052FC8106",
  "requestID": "sms-1001",
  "sender": "MyShop",
  "recipients": 2,
  "sent": 2,
  "failed": 0,
  "skipped": 0,
  "pages": 1
}
Example error response 206
{
  "code": 206,
  "status": "failed",
  "description": "MESSAGE_CONTENT_BLOCKED",
  "api_response": "This message would be blocked by the networks, so it was not sent. The networks block messages that mention international brands such as WhatsApp or Facebook.",
  "issues": [
    "The networks block messages that mention international brands such as WhatsApp or Facebook."
  ]
}

Flights

GET

List Airports

#

Returns airports with their 3-letter code, name, city and country. Send q to search by city, airport name, code or country (the best 15 matches). Send nothing to get the popular airports, or all=true to download the whole list and keep it in your own cache. Use the code as origin and destination in Search Flights.

Requires your API key as a Bearer token
Query parameter Description
q string Optional Search text, for example lagos, abuja, LHR or London. Leave it out for the popular airports.
Example: lagos
all string Optional true returns every airport instead of the best matches.
Example: true
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. Airports are listed with the best match first.

Request
curl --location 'https://api.gsubz.com/api/flight/search/?q=lagos' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "count": 1,
  "airports": [
    { "code": "LOS", "name": "Murtala Muhammed International Airport", "city": "Lagos", "country": "Nigeria" }
  ]
}
Example error response 401
{
  "code": 401,
  "status": "failed",
  "description": "INVALID_API_OR_NOT_FOUND",
  "api_response": "This API key is not valid."
}
POST

Book a Flight

#

Books one flight for your customer and pays for it from your wallet. The price is locked first: send preview=true to get the final price (and a quoteID) without paying, then book with that quoteID, or book straight away with the token and searchID from Search Flights. Send the body as JSON (recommended) or as form fields.

A booking can still be processing. When orderStatus is processing, you have been charged and the airline is still issuing the ticket. It ends as completed (with the pnr and tickets) or refunded. We send you a webhook (flight.order.updated) when it changes, and you can always check it with Fetch Flight Orders. A refund goes back to your wallet automatically, and a booking is never refunded while its outcome is unclear.
  • Two steps. 1) preview=true with token and searchID returns the final price and a quoteID that stays valid for about 25 minutes (expiresIn). Nothing is charged. 2) Send the passengers and contact with that quoteID to book at exactly that price. A quote can be used once. Add maxAmount to refuse a booking that would cost more: you get PRICE_CHANGED and nothing is charged.
  • Always send a requestID. Send the same one again and you get the original booking back (code 406, INVALID_ARGUMENTS_DUPLICATE_REQUEST_ID) and never a second booking, so retrying after a timeout is safe. International trips need passport_number and passport_expiry for every passenger, and the passport must be valid after the last travel date. The ticket e-mail to your customer is yours to send: we do not e-mail them.
Requires your API key as a Bearer token
Body field Description
searchID string With token The searchID from Search Flights. Needed together with token.
Example: FS3A9C41D07B22E8F5A61
token string Without quoteID The token of the option your customer picked in Search Flights.
Example: eyJhbGciOi…
quoteID string Without token The quoteID from an earlier preview=true call. Books at that locked price.
Example: Q1b2c3d4
passengers array To book One item for each traveller, matching the adults, children and infants you searched. Each has type (adult, child or infant), title (Mr, Mrs, Ms, Miss or Master), first_name, last_name, gender (male or female), and optionally middle_name and country_code (2 letters, default NG). International trips also need passport_number and passport_expiry (YYYY-MM-DD). Names use letters only.
Example: [{"type":"adult","title":"Mr","first_name":"Ada","last_name":"Obi","gender":"male"}]
contact object To book Who the airline contacts: email and phone (080…, 234… or +234…).
Example: {"email":"[email protected]","phone":"08031234567"}
requestID string Optional Your own unique reference for this booking, up to 100 characters. Use it later with Fetch Flight Orders.
Example: flight-1001
maxAmount number Optional The most you will pay, in naira. If the price is higher you get PRICE_CHANGED and nothing is charged.
Example: 100000
preview boolean Optional true locks and returns the final price (as quoteID and amount) without booking or charging anything.
Example: true
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. orderStatus is completed (ticket issued: pnr and tickets are filled in), processing (charged, ticket not issued yet) or refunded. Keep transactionID: you need it to look the booking up. With preview=true the response has "preview": true, the final amount, a quoteID, expiresIn (seconds), the journeys, fareRules and penaltyRules, and amountPaid is 0. amountPaid is what you pay after any refund.

Request
curl --location 'https://api.gsubz.com/api/flight/book/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
    "searchID": "FS3A9C41D07B22E8F5A61",
    "token": "eyJhbGciOi…",
    "passengers": [
        {
            "type": "adult",
            "title": "Mr",
            "first_name": "Ada",
            "last_name": "Obi",
            "gender": "male"
        }
    ],
    "contact": {
        "email": "[email protected]",
        "phone": "08031234567"
    },
    "requestID": "flight-1001",
    "preview": true
}'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "transactionID": "TRV261017110002AB12CD34",
  "amount": 95000,
  "serviceID": "flight",
  "amountPaid": 95000,
  "initialBalance": 500000,
  "finalBalance": 405000,
  "date": "2026-10-17T11:00:02+01:00",
  "api_response": "Your booking is being processed and you have been charged. The result is sent to your webhook as flight.order.updated, or check it with Fetch Flight Orders.",
  "requestID": "flight-1001",
  "orderStatus": "processing",
  "tripType": "oneway",
  "origin": "LOS",
  "destination": "ABV",
  "departureDate": "2026-12-01",
  "returnDate": null,
  "airline": "Ibom Air",
  "journeys": [
    { "from": "LOS", "to": "ABV", "departsAt": "2026-12-01T08:00:00", "arrivesAt": "2026-12-01T09:10:00", "duration": "1h10", "stops": 0, "flightNumber": "QI 301", "baggage": "23KG baggage" }
  ],
  "passengers": [
    { "type": "Adult", "title": "Mr", "firstName": "Ada", "middleName": null, "lastName": "Obi", "gender": "Male", "countryCode": "NG" }
  ],
  "contact": { "email": "[email protected]", "phone": "+2348031234567" },
  "amountRefunded": 0,
  "pnr": null,
  "tickets": []
}
Example error response 406
{
  "code": 406,
  "status": "failed",
  "description": "PRICE_CHANGED",
  "api_response": "The price is now ₦98,500.00, above your maxAmount. Nothing was charged. Send the same request with the quoteID in this response to book at the new price.",
  "quoteID": "Q1b2c3d4",
  "currentAmount": 98500,
  "expiresIn": 1700
}
POST

Fetch Flight Orders

#

Returns your flight bookings made through the API. Send a requestID or a transactionID to get one booking, or send neither to list your last 50. A booking that is still processing is checked again when you look it up (at most every 25 seconds), so this is also how you collect the PNR and e-ticket numbers if you missed the webhook. It also answers GET.

Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
requestID string Optional The requestID you sent when you booked.
Example: flight-1001
transactionID string Optional The transactionID from the booking response.
Example: TRV261017110002AB12CD34
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. orderStatus is one of processing, completed or refunded. amountRefunded shows what was returned to your wallet, and amountPaid is what you paid after any refund. pnr and tickets are filled in once the ticket is issued. Without a reference the response also has count.

Request
curl --location 'https://api.gsubz.com/api/flight/orders/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'requestID="flight-1001"' \
--form 'transactionID="TRV261017110002AB12CD34"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "orders": [
    {
      "transactionID": "TRV261017110002AB12CD34",
      "requestID": "flight-1001",
      "serviceID": "flight",
      "orderStatus": "completed",
      "tripType": "oneway",
      "origin": "LOS",
      "destination": "ABV",
      "departureDate": "2026-12-01",
      "returnDate": null,
      "airline": "Ibom Air",
      "journeys": [
        { "from": "LOS", "to": "ABV", "departsAt": "2026-12-01T08:00:00", "arrivesAt": "2026-12-01T09:10:00", "duration": "1h10", "stops": 0, "flightNumber": "QI 301", "baggage": "23KG baggage" }
      ],
      "passengers": [
        { "type": "Adult", "title": "Mr", "firstName": "Ada", "middleName": null, "lastName": "Obi", "gender": "Male", "countryCode": "NG" }
      ],
      "contact": { "email": "[email protected]", "phone": "+2348031234567" },
      "amount": 95000,
      "amountRefunded": 0,
      "amountPaid": 95000,
      "pnr": "ABC123",
      "tickets": [
        { "name": "Ada Obi", "type": "ADT", "ticketNumber": "1234567890123" }
      ],
      "date": "2026-10-17T11:00:02+01:00"
    }
  ]
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "No flight booking found for that reference."
}

Store

GET

Get Product Details

#

Returns the full details of one product, with every price in naira. Use an id from Search Products. Official Store products (IDs that start with g) are free. Any other product costs ₦2, and you are charged only when the product is found.

Requires your API key as a Bearer token
Query parameter Description
id string Required The product id from a search result, for example 682718261723, or g000000001 for an Official Store product.
Example: 682718261723
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. priceTiers show the price for each minimum quantity. minPriceNgn and maxPriceNgn are the lowest and highest variant prices. skus are the variants (colour, size and so on): send the skuId as sku_id when you Place an Order. A variant's weight and size are null when unknown. media can hold image, video and youtube items (a youtube item has videoId, start and end in seconds). supplier.id is the ID to use with Get Supplier Products; it is null for Official Store products. Each variant's shippingNgn is the shipping fee we charge to Nigeria for 1 piece and for 5 pieces ordered together, by air and by sea (more pieces cost less per piece, because they ship together); every variant is priced when you request the product. shipping.estimated is true when those fees are filled in. shipping.seaOnly is true for goods that can only go by sea (power banks, sprays, perfumes). flatAirFeePerItemNgn is set for phones, tablets and laptops, which have a flat air fee per item. For the exact fee of any quantity mix, call Place an Order with preview=true. The rates and the variants' weights and volumes are also included. shipping is null when freeShipping is true. description is empty for most products. similar lists up to 20 similar products from our catalogue (id, title, image, priceNgn, totalSold); use the id with this endpoint for full details. It is an empty list for Official Store products and is included at no extra cost. The example is shortened.

Request
curl --location 'https://api.gsubz.com/api/store/product/?id=682718261723' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18460,
  "scope": "market",
  "amountPaid": 2,
  "initialBalance": 4994,
  "finalBalance": 4992,
  "date": "2026-10-07T11:25:03+01:00",
  "api_response": "Product details.",
  "product": {
    "id": "682718261723",
    "title": "Wireless Bluetooth Earbuds Noise Cancelling Headset",
    "media": [
      { "type": "video", "url": "https://video.example.com/earbuds.mp4" },
      { "type": "image", "url": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fa1.jpg" }
    ],
    "priceTiers": [
      { "minQty": 2, "priceNgn": 4850 },
      { "minQty": 100, "priceNgn": 4300 }
    ],
    "minPriceNgn": 4300,
    "maxPriceNgn": 5100,
    "moq": 2,
    "skus": [
      {
        "skuId": "5001",
        "label": "Black / Standard",
        "stock": 120,
        "priceNgn": 4850,
        "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fk1.jpg",
        "weightKg": 0.12,
        "lengthCm": 12,
        "widthCm": 8,
        "heightCm": 4,
        "shippingNgn": { "airFor1Pc": 4276, "airFor5Pcs": 14250, "seaFor1Pc": 990, "seaFor5Pcs": 3300 }
      }
    ],
    "specs": {
      "Battery": "300mAh",
      "Bluetooth": "5.3"
    },
    "description": "",
    "location": "Guangdong Shenzhen",
    "totalSold": 4321,
    "freeShipping": false,
    "supplier": {
      "id": "sp_Q3ZnR2Fh0uJp9mKcT1xYvWbEoLd8sA"
    },
    "shipping": {
      "airRatePerKgNgn": 21000,
      "seaRatePerCbmNgn": 450000,
      "weightsKg": [0.12],
      "volumesCbm": [0.000384],
      "estimated": true,
      "seaOnly": false,
      "flatAirFeePerItemNgn": null,
      "note": "Fees for any mix of quantities: POST /api/store/order/ with preview=true. The shipping fee charged is final."
    }
  }
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "Product not found. You were not charged.",
  "callID": 18461
}
GET

Get Supplier Products

#

Returns a page of products from one supplier, in the same format as Search Products. Get the supplier ID from supplier.id in Get Product Details. It costs ₦2, charged only when the page has products.

Requires your API key as a Bearer token
Query parameter Description
id string Required The supplier ID from supplier.id in Get Product Details. Always start with sp_.
Example: sp_Q3ZnR2Fh0uJp9mKcT1xYvWbEoLd8sA
page integer Optional The page number, starting at 1.
Example: 1
sort string Optional default, sales, price_up, price_down, time_up or time_down.
Example: sales
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This call costs ₦2. It is deducted from your wallet when the page has products.

About the response. The example is shortened to one product.

Request
curl --location 'https://api.gsubz.com/api/store/supplier/?id=sp_Q3ZnR2Fh0uJp9mKcT1xYvWbEoLd8sA&page=1' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18470,
  "scope": "market",
  "amountPaid": 2,
  "initialBalance": 4992,
  "finalBalance": 4990,
  "date": "2026-10-07T11:27:30+01:00",
  "api_response": "Supplier products.",
  "page": 1,
  "pageSize": 20,
  "count": 1,
  "hasMore": true,
  "items": [
    {
      "id": "770000000015",
      "title": "Cotton Casual Shirt",
      "fullTitle": "Cotton Casual Shirt Short Sleeve",
      "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fsh1.jpg",
      "priceNgn": 3100,
      "sold": 65,
      "freeShipping": false
    }
  ]
}
Example error response 206
{
  "code": 206,
  "status": "failed",
  "description": "INVALID_CONTENT",
  "api_response": "id must be a supplier id from a product (supplier.id).",
  "callID": 18471
}
GET

List Categories and Brands

#

Returns the categories shown on the Gsubz store and the Official Store brands. It is free. No parameters: it always returns everything in one response.

  • A category is only a group of related search words. To get a category's products, send its name as q to Search Products with scope=market. You are free to build your own categories from keywords instead. To get a brand's products, send its id as brand with scope=official.
Requires your API key as a Bearer token
No parameters. It always returns everything in one response — filter or sort on your side.
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. categories is a tree up to three levels deep: a category with no sub-categories has an empty children array. brands lists only brands that have products, and products is how many. The example is shortened.

Request
curl --location 'https://api.gsubz.com/api/store/categories/' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18480,
  "amountPaid": 0,
  "initialBalance": 4990,
  "finalBalance": 4990,
  "date": "2026-10-07T11:30:02+01:00",
  "api_response": "Categories and brands.",
  "categories": [
    {
      "name": "Women's Clothing",
      "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fc1.jpg",
      "children": [
        {
          "name": "Women's T-Shirts",
          "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fc2.jpg",
          "children": []
        },
        {
          "name": "Women's Casual Pants",
          "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fc3.jpg",
          "children": [
            {
              "name": "Casual Pants",
              "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fc4.jpg",
              "children": []
            }
          ]
        }
      ]
    }
  ],
  "brands": [
    {
      "id": 1,
      "name": "Apple",
      "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fapple.jpg",
      "products": 24
    }
  ]
}
GET

List Pickup Stations

#

Every Store order is delivered to a pickup station, where your customer collects it. This returns the stations by state, with the delivery fee for each parcel size. Send the state and the station name exactly as returned when you Place an Order. It is free.

Requires your API key as a Bearer token
Query parameter Description
action string Required Always stations.
Example: stations
state string Optional Only this state. Leave it out to get every state.
Example: Lagos
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. deliveryFee is what the order pays to reach that station, by parcel size. The size is decided by the parcel's total weight and total volume (the bigger one wins), using the limits in parcelSizes: for example 3 kg but 0.05 m³ is a medium parcel. days is the usual delivery time once the parcel leaves our Lagos warehouse. The example is shortened to one station.

Request
curl --location 'https://api.gsubz.com/api/store/order/?action=stations&state=Lagos' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18490,
  "scope": "stations",
  "amountPaid": 0,
  "initialBalance": 50000,
  "finalBalance": 50000,
  "date": "2026-10-13T10:02:11+01:00",
  "api_response": "Pickup stations.",
  "parcelSizes": {
    "small":  { "maxKg": 4,  "maxCbm": 0.0384 },
    "medium": { "maxKg": 12, "maxCbm": 0.1536 },
    "large":  { "maxKg": null, "maxCbm": null }
  },
  "states": [
    {
      "state": "Lagos",
      "stations": [
        {
          "name": "Ikota",
          "address": "Ikota Shopping Complex, Lekki",
          "landmark": "Near VGC",
          "phone": "08000000001",
          "hours": { "weekdays": "8am - 6pm", "weekends": "9am - 3pm" },
          "map": "https://maps.example.com/ikota",
          "deliveryFee": { "smallNgn": 2400, "mediumNgn": 4200, "largeNgn": 6800, "days": "2-4 days" }
        }
      ]
    }
  ]
}
POST

Place an Order

#

Places an order for one or more products and pays for it from your wallet. Prices, the service fee, shipping and the delivery fee are worked out exactly as on the Gsubz store. Send preview=true first to get the full price without paying. API orders are always packed without Gsubz branding, so you can ship to your own customers. Send the body as JSON (recommended) or as form fields.

reference is your own unique ID for the order. Sending the same reference again never creates or charges a second order: you get the first order back with "duplicate": true. That makes it safe to retry after a timeout.
  • What you pay now: the products, a service fee (5% of each product's total, at least ₦1,900 and at most ₦70,000 a product; none on Official Store products), the shipping to Nigeria, and the delivery fee to the pickup station. Shipping is worked out for every product and quantity when you order, and the fee you pay is final: there is no extra shipping fee later. In the rare case that a fee cannot be worked out, that item's shipping shows as pending: we send you a webhook with the fee, and you pay it with Pay Shipping. Items are processed only once their shipping is paid. shippingNotices in the quote lists any warning for the chosen method, for example goods that can only go by sea.
Requires your API key as a Bearer token
Body field Description
reference string Required Your own unique ID for this order: letters, numbers, . - _, up to 64 characters.
Example: ORDER-10045
items array Required The products. Each item has product_id (from Search Products), sku_id (a skuId from Get Product Details; Official Store products use their own skuId too), quantity, and optionally price: the naira unit price you expect. If the price has gone up, nothing is charged and you get PRICE_CHANGED with the new price. Up to 50 items. A product with a minimum order (moq) needs at least that many pieces across its variants.
Example: [{"product_id":"682718261723","sku_id":"5001","quantity":2,"price":4850}]
shipping_method string International products air or sea, for the whole order. Not needed when every item is an Official Store product (their shipping is already in the price).
Example: air
state string Required The pickup station's state, from List Pickup Stations.
Example: Lagos
station string Required The pickup station's name, from List Pickup Stations.
Example: Ikota
first_name string Required First name of the person who collects the order.
Example: Ada
last_name string Required Last name of the person who collects the order.
Example: Obi
phone string Required Their phone number. The pickup station contacts this number.
Example: 08031234567
preview boolean Optional true returns the full price (as quote) without placing or paying for anything.
Example: true
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. amountPaid is what this order took from your wallet. Each item has its own status: PAID (order placed), PROCESSING, SHIPPED, IN_NIGERIA, OUT_FOR_DELIVERY, DELIVERED, RETURNED or CANCELLED. shipping.status is paid, due (pay it with Pay Shipping), pending (not weighed yet) or included (Official Store). weightKg and volumeCbm are filled in once the item is weighed. With preview=true the response has "preview": true and a quote object (shipping method, pickup station, parcelSize with the estimated weight and volume, amounts with totalNgn, shippingNotices, and the priced items) instead of order, and amountPaid is 0.

Request
curl --location 'https://api.gsubz.com/api/store/order/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
    "reference": "ORDER-10045",
    "items": [
        {
            "product_id": "682718261723",
            "sku_id": "5001",
            "quantity": 2,
            "price": 4850
        }
    ],
    "shipping_method": "air",
    "state": "Lagos",
    "station": "Ikota",
    "first_name": "Ada",
    "last_name": "Obi",
    "phone": "08031234567",
    "preview": true
}'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18500,
  "scope": "place",
  "amountPaid": 30676,
  "initialBalance": 50000,
  "finalBalance": 19324,
  "date": "2026-10-13T10:05:40+01:00",
  "api_response": "Order placed.",
  "order": {
    "orderId": 5231,
    "reference": "ORDER-10045",
    "dropship": true,
    "createdAt": "2026-10-13T10:05:40+01:00",
    "cancellableUntil": "2026-10-13T12:05:40+01:00",
    "shippingMethod": "air",
    "recipient": { "firstName": "Ada", "lastName": "Obi", "phone": "08031234567" },
    "pickupStation": { "name": "Ikota", "address": "Ikota Shopping Complex, Lekki", "state": "Lagos" },
    "amounts": {
      "itemsNgn": 9700,
      "serviceFeeNgn": 1900,
      "shippingPaidNgn": 16676,
      "shippingDueNgn": 0,
      "deliveryNgn": 2400
    },
    "items": [
      {
        "itemId": 88120,
        "productId": "682718261723",
        "skuId": "5001",
        "title": "Wireless Bluetooth Earbuds Noise Cancelling Headset",
        "variation": "Black / Standard",
        "image": "https://gsubz.com/store/image_proxy.php?url=https%3A%2F%2Fimg.example.com%2Fk1.jpg",
        "quantity": 2,
        "unitPriceNgn": 4850,
        "lineTotalNgn": 9700,
        "serviceFeeNgn": 1900,
        "status": "PAID",
        "shipping": {
          "method": "air",
          "weightKg": null,
          "volumeCbm": null,
          "status": "paid",
          "unitNgn": 8338,
          "totalNgn": 16676,
          "paidNgn": 16676,
          "dueNgn": 0
        },
        "trackingNumber": null,
        "cancellable": true,
        "cancelledAt": null
      }
    ]
  }
}
Example error response 406
{
  "code": 406,
  "status": "failed",
  "description": "PRICE_CHANGED",
  "api_response": "The price of 1 item(s) went up. Nothing was charged. Check the new prices and send the order again.",
  "callID": 18501,
  "items": [
    { "product_id": "682718261723", "sku_id": "5001", "expectedPriceNgn": 4850, "currentPriceNgn": 4990 }
  ]
}
GET

Get Orders

#

Returns one order when you send order_id or reference, in the same format as Place an Order. Without them it returns your API orders, newest first, 20 at a time. It is free. Use it to check an order after a timeout, or if you missed a webhook.

Requires your API key as a Bearer token
Query parameter Description
order_id integer Optional The orderId from Place an Order.
Example: 5231
reference string Optional Or your own reference.
Example: ORDER-10045
page integer Optional Page number when listing, starting at 1.
Example: 1
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. order has exactly the fields shown in Place an Order (shortened here). Without order_id or reference the response has page, pageSize, count, hasMore and an orders list instead.

Request
curl --location 'https://api.gsubz.com/api/store/order/?order_id=5231&reference=ORDER-10045' \
--header 'Authorization: Bearer YOUR_API_KEY'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18510,
  "scope": "orders",
  "amountPaid": 0,
  "initialBalance": 19324,
  "finalBalance": 19324,
  "date": "2026-10-14T09:00:00+01:00",
  "api_response": "Order details.",
  "order": {
    "orderId": 5231,
    "reference": "ORDER-10045",
    "items": []
  }
}
Example error response 404
{
  "code": 404,
  "status": "failed",
  "description": "CONTENT_NOT_FOUND",
  "api_response": "Order not found.",
  "callID": 18511
}
POST

Cancel an Order

#

Cancels an order and refunds your wallet at once. You can cancel within 2 hours of placing the order, and only items that are still PAID (not yet being processed). Leave out item_id to cancel the whole order: this works only when no item is being processed yet. Otherwise cancel items one by one. Each cancelled item refunds its price, its service fee and any shipping paid. The delivery fee is refunded when the last item of the order is cancelled.

Requires your API key as a Bearer token
Body field Description
action string Required Always cancel.
Example: cancel
order_id integer Or reference The order to cancel. You can send reference instead.
Example: 5231
reference string Optional Your own reference, instead of order_id.
Example: ORDER-10045
item_id integer Optional Cancel only this item (itemId). Leave it out to cancel the whole order.
Example: 88120
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This really cancels. The items are refunded to your wallet and cannot be restored by the API.

About the response. order is the updated order, in the same format as Place an Order (shortened here).

Request
curl --location 'https://api.gsubz.com/api/store/order/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'action="cancel"' \
--form 'order_id="5231"' \
--form 'item_id="88120"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18520,
  "scope": "cancel",
  "amountPaid": 0,
  "initialBalance": 19324,
  "finalBalance": 50000,
  "date": "2026-10-13T10:40:12+01:00",
  "api_response": "1 item(s) cancelled. ₦30,676.00 was refunded to your wallet.",
  "refundedNgn": 30676,
  "cancelled": [
    { "itemId": 88120, "refundNgn": 30676, "itemNgn": 9700, "serviceFeeNgn": 1900, "shippingNgn": 16676, "deliveryNgn": 2400 }
  ],
  "order": { "orderId": 5231, "reference": "ORDER-10045", "items": [] }
}
Example error response 406
{
  "code": 406,
  "status": "failed",
  "description": "CANCEL_NOT_ALLOWED",
  "api_response": "Orders can only be cancelled within 2 hours of ordering.",
  "callID": 18521
}
POST

Pay Shipping

#

When we weigh an item whose shipping was pending, or the weight turns out higher than listed, its shipping.status becomes due and you get a webhook with the new weight, size and fee. This pays everything due on the order from your wallet (or only one item with item_id). Items move to processing once their shipping is paid. Nothing waits on a deadline: an item stays on hold until it is paid.

Requires your API key as a Bearer token
Body field Description
action string Required Always pay_shipping.
Example: pay_shipping
order_id integer Or reference The order. You can send reference instead.
Example: 5231
reference string Optional Your own reference, instead of order_id.
Example: ORDER-10045
item_id integer Optional Pay only this item. Leave it out to pay everything due on the order.
Example: 88121
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

This pays real money from your wallet for the shipping that is due.

About the response. amountPaid is the shipping taken from your wallet. order is the updated order (shortened here).

Request
curl --location 'https://api.gsubz.com/api/store/order/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'action="pay_shipping"' \
--form 'order_id="5231"'
Example response 200 OK
{
  "code": 200,
  "status": "successful",
  "callID": 18530,
  "scope": "pay_shipping",
  "amountPaid": 4356,
  "initialBalance": 19324,
  "finalBalance": 14968,
  "date": "2026-10-16T14:20:00+01:00",
  "api_response": "Shipping paid for 1 item(s).",
  "paid": [ { "id": 88121, "amount": 4356 } ],
  "order": { "orderId": 5231, "reference": "ORDER-10045", "items": [] }
}
Example error response 406
{
  "code": 406,
  "status": "failed",
  "description": "NOTHING_DUE",
  "api_response": "No shipping fee is due on this order right now.",
  "callID": 18531
}

Transactions

POST

Fetch Transaction Status

#

Check the status and response of a purchase using the requestID you sent when you made it, or the transactionID GSUBZ returned. Use this whenever a purchase request times out or returns no response, before you try again. Electricity purchases also return their token, and social media orders return their live progress.

A transaction can return HTTP 200 and still have failed. Always check the status field, not just the response code.
  • Send either requestID or transactionID: whichever you have. Only your own transactions are searched. If you send neither, the request is refused with code 400.
  • Electricity. The response carries token, the meter token. If the token was not available when you bought, it is fetched for you now, so a purchase whose token you never received can be recovered by calling this endpoint. If the token is still not ready, token is left out: try again in a minute. A failed or refunded purchase never has a token.
  • Social media. The response carries order: the live progress of the order, with status, start_count (the count when the order started) and remains (how many are still to be delivered). It is left out if the progress cannot be read right now.
Requires your API key as a Bearer token
Body field Description
api string Required Your API key. Send the same key you use in the Authorization header.
Example: YOUR_API_KEY
requestID string Or transactionID The requestID you passed during the purchase. Send this or transactionID.
Example: 7wbd7wbdw7d72g6vd
transactionID string Optional The transactionID from the purchase response. Send this or requestID.
Example: 3574357094
Try it live

Sent only to GSUBZ, through this page's server. We never store it. It stays in this browser tab until you close it.

About the response. transaction_id is GSUBZ's reference and amount is what the purchase cost you, in naira. Electricity adds "token": "47488383838383838383833". Social media adds "order": { "status": "In progress", "start_count": "0", "remains": "850" }. Other services return neither.

Request
curl --location 'https://api.gsubz.com/api/verify/' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--form 'api="YOUR_API_KEY"' \
--form 'requestID="7wbd7wbdw7d72g6vd"'
Example response 200 OK
{
  "code": "200",
  "status": "success",
  "description": "TRANSACTION_SUCCESSFUL",
  "transaction_id": "3574357094",
  "amount": "1100",
  "api_response": "Dear Customer, You have successfully shared 1GB Data to 2349063648020. Your SME data balance is 28955.68GB expires 30/01/2024. Thankyou"
}
Example error response 404
{
  "code": "404",
  "description": "CONTENT_NOT_FOUND_API_OR_NOT_FOUND",
  "status": "TRANSACTION_FAILED"
}