Back to GsmWhale
API Reference · v2

Give your resellers an API of their own.

Every GsmWhale shop exposes one order endpoint. Your clients point their existing software at your domain, authenticate with a JWT or a legacy key, and it works — place an order, poll its status, read the result. No adapter to write on either side.

3 Auth styles
6 Actions
1 Endpoint
<2.4s Avg turnaround
POST https://your-domain.com/api/v1/orders
JWT signed HS256 Legacy key compatible FastAPI ready
curl · bearer sample
curl -X POST 'https://your-domain.com/api/v1/orders' \
  -H 'Authorization: Bearer <JWT>' \
  -H 'Content-Type: application/json' \
  -d '{"action":"placeimeiorder","parameters":{"id":42,"imei":"352099001761481","qnt":1}}'
Order status lifecycle

Every order moves through the same rail.

Place it, poll it, read the result. The status values are stable across all three API styles — build one state machine and it works everywhere.

Pending

Waiting for processing

Processing

Validated, queued, running

In Progress

Service executing

Completed

Code / reply delivered

Partial

One result delivered

Failed

Service returned an error

Rejected

Order denied

Refunded

Credit returned to wallet

01 Bearer Token (JWT)

One signed token drives the whole rail.

The JWT Auth Engine verifies every JSON call — HS256 signature, 15-minute expiry, scoped claims — then walks the order rail from place to reply. No adapter, one header.

HS256 signed 15 min expiry scoped tokens 4 order actions

JWT Auth Engine

hs256 · scope · rail

Live
API Client POST /orders
Auth Engine JWT verified
Order Rail place → poll

PendingIn ProgressSuccess

Authorization: Bearer <JWT>
API features & support

Four order actions, every one verified.

The engine checks the token once, then picks the right scope — place, bulk, poll.

  • Authorization: Bearer on every request
  • HS256 signature, 15-minute expiry, silent refresh
  • Scoped tokens from Settings → API Keys
  • REST mirrors: account · products · order
POST /api/v1/orders · Authorization: Bearer <JWT>
placeimeiorder

Submit a single order line with IMEI + fields.

placeimeiorderbulk

Batch submit many lines in one call.

getimeiorder

Poll a single order for status and result.

getimeiorderbulk

Poll many orders in one request.

response · 200 OK
{ "ORDER": { "ORDERID": "4821", "STATUS": "Pending", "REPLY": null } }
Pending Processing In Progress Completed Partial Failed Rejected Refunded
curl · place order
curl -X POST 'https://your-domain.com/api/v1/orders' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1Ni...' \
  -H 'Content-Type: application/json' \
  -d '{"action":"placeimeiorder","parameters":{"id":42,"imei":"352099001761481","qnt":1}}'
Supported actions 4 actions
placeimeiorder placeimeiorderbulk getimeiorder getimeiorderbulk
02 PHP Form-URLEncoded

The relay your legacy software already speaks.

The Form Relay accepts the Dhru Fusion v6.1 action set over form-encoded POSTs, keeps the XML parameter payload as-is, and walks it onto the same order rail. Switch keys, not code.

Dhru compatible 6 actions username + apiaccesskey
API features, support & details

Six actions. One form. No SDK.

Authenticate with username + apiaccesskey, pick requestformat=JSON, and the action field shapes the call.

  • All 6 Dhru Fusion v6.1 actions supported
  • Single and bulk submit for Fusion 31–59 APIs
  • XML parameters payload kept as-is
  • Reseller keys swap in without code changes
POST /api/index.php · username + apiaccesskey
accountinfo

Balance and currency for the key.

imeiservicelist

Service list (same as server service list).

placeimeiorder

Place a single order line.

placeimeiorderbulk

Batch submit many lines in one call.

getimeiorder

Order details — status, reply, date.

getimeiorderbulk

Batch poll many orders in one request.

response · 200 OK
{ "ORDER": { "ORDERID": "4821", "STATUS": "Pending" } }
error · shape
{ "ERROR": [ { "MESSAGE": "Validation failed" } ] }
Pending Processing In Progress Completed Partial Failed Rejected Refunded
php · place order
$data = [
    'username'      => 'client_42',
    'apiaccesskey'  => 'YOUR_API_ACCESS_KEY',
    'requestformat' => 'JSON',
    'action'        => 'placeimeiorder',
    'parameters'    => '<PARAMETERS><IMEI>352099001761481</IMEI>'
                     . '<ID>42</ID><QNT>1</QNT></PARAMETERS>'
];

$ch = curl_init('https://your-domain.com/api/index.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);

$response = json_decode(curl_exec($ch), true);
echo "Order id: " . $response['ORDER']['ORDERID'];
parameters · xml
<PARAMETERS>
  <IMEI>352099001761481</IMEI>
  <ID>42</ID>
  <QNT>1</QNT>
  <CUSTOMFIELD>eyJtb2RlbCI6IlNNLUE1MzUifQ==</CUSTOMFIELD>
</PARAMETERS>
Supported actions 6 actions
accountinfo imeiservicelist placeimeiorder placeimeiorderbulk getimeiorder getimeiorderbulk

PHP Form Relay

form · xml · rail

Live
PHP Client http_build_query
Form Relay action mapped
Order Rail place → poll

PendingIn ProgressSuccess

POST /api/index.php · requestformat=JSON
03 Python Fast API

A typed shim between your scripts and the rail.

The FastAPI shim runs as an httpx client: POST the order, poll the status forward, read the typed reply — in one small loop, no hidden state.

pip install httpx 6 actions poll every 3s

FastAPI shim

httpx · typed · rail

Live
Python Client httpx.post
FastAPI route JWT verified
Order Rail poll → replay

PendingIn ProgressSuccess

POST api/v1/orders · GET order?order_uuid=
API features & details

Place, poll, read — the whole loop.

One typed httpx client walks the full lifecycle — non-2xx raises, poll until the status settles.

  • All 6 actions via httpx + the bearer token
  • raise_for_status() on every non-2xx call
  • Poll every 3s until Completed / Failed / Rejected
POST api/v1/orders · GET order?order_uuid=
accountinfo

Balance and currency for the key.

imeiservicelist

Service list (same as server service list).

placeimeiorder

Place a single order line.

placeimeiorderbulk

Batch submit many lines in one call.

getimeiorder

Order details — status, reply, date.

getimeiorderbulk

Batch poll many orders in one request.

response · completed
{
  "ORDER": {
    "ORDERID": "4821",
    "STATUS": "Completed",
    "REPLY": "29% © 100% Complete"
  }
}
GET order?order_uuid= typed responses raise_for_status Completed Failed Rejected Processing Pending
python · place + poll
import httpx, time

API = "https://your-domain.com/api/v1/orders"
TOKEN = "eyJhbGciOiJIUzI1Ni..."  # Bearer token from Settings → API Keys

def place_order(price_id: int, imei: str) -> dict:
    r = httpx.post(
        API,
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={"action": "placeimeiorder",
              "parameters": {"id": price_id, "imei": imei, "qnt": 1}},
        timeout=30,
    )
    r.raise_for_status()
    return r.json()["ORDER"]

def wait_status(order_id: str) -> dict:
    while True:
        r = httpx.get(
            API,
            params={"action": "getimeiorder", "order_id": order_id},
            headers={"Authorization": f"Bearer {TOKEN}"},
        )
        order = r.json()["ORDER"]
        if order["STATUS"] in ("Completed", "Failed", "Rejected"):
            return order
        time.sleep(3)
Supported actions 6 actions
accountinfo imeiservicelist placeimeiorder placeimeiorderbulk getimeiorder getimeiorderbulk
04 GsmWhale REST API

The raw endpoint. One JSON rail.

REST Core takes Bearer-authenticated JSON against POST /api/v1/orders — the same order rail the other three engines ride, exposed raw.

Bearer auth JSON in / out status-typed replies 8 order statuses
REST reference & mirrors

Mirrors, typed like the engines.

Bearer-authenticated JSON against four REST mirrors — account, products, orders and order — sharing one typed reply shape.

  • Authorization: Bearer header on every call
  • JSON in, JSON out — no XML parameters here
  • Typed replies — ORDER / ERROR settle by status
  • Mirrors we host: account · products · orders
body · POST /api/v1/orders Bearer · application/json
action string placeimeiorder · placeimeiorderbulk · getimeiorder · getimeiorderbulk
parameters.id int service / price id from the products mirror
parameters.imei string device IMEI to activate
parameters.qnt int quantity, defaults to 1
POST /api/v1/orders · GET /api/v1/order?order_uuid=
GET /api/v1/account

Balance and currency for the key.

GET /api/v1/products

Service list as JSON rows.

POST /api/v1/orders

Place an order — single or bulk.

GET /order?order_uuid=

Poll a single order — status + reply.

response · 200 OK
{ "ORDER": { "ORDERID": "4821", "STATUS": "Pending", "REPLY": null } }
error · shape
{ "ERROR": [ { "MESSAGE": "Validation failed" } ] }
Pending Processing In Progress Completed Partial Failed Rejected Refunded
curl · place order
curl -X POST 'https://your-domain.com/api/v1/orders' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1Ni...' \
  -H 'Content-Type: application/json' \
  -d '{"action":"placeimeiorder","parameters":{"id":42,"imei":"352099001761481","qnt":1}}'
curl · poll order
curl -X GET 'https://your-domain.com/api/v1/order?order_uuid=4821' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1Ni...'

# → { "ORDER": { "ORDERID": "4821", "STATUS": "In Progress", "REPLY": "29% © 100% Complete" } }
REST mirrors 4 endpoints
account products orders order

Bearer auth, JSON only — the same order rail, unmediated.

REST Core

bearer · json · rail

Live
Client App POST /orders
REST API JWT verified
Order Rail HS256
PendingIn ProgressSuccess
Bearer · JSON 8 states
POST /api/v1/orders · Authorization: Bearer <JWT>
API Provider List

Every supplier API you already use, wired in.

Pick a provider to see how GsmWhale talks to its API — supported actions, delivery model and the quick links to manage the connection.

Click any provider to see integration details on the right.

Error handling

Failures come back in one shape.

A bad key, an unknown action, a service the account cannot order, or not enough credit — every failure returns a consistent message, whatever the API style.

401 Missing / expired bearer token or bad key
400 Validation failed — missing field or bad IMEI
402 Not enough credit to cover the order
404 Unknown action, or order id not found
error response
{
  "ERROR": [
    { "MESSAGE": "Validation failed" }
  ]
}

Wrap every call so a non-2xx status raises before you read the body. The MESSAGE is always human-readable and stable across releases.

The full reference lives in the knowledge base.

Field-by-field responses, every status value an order can hold, and worked examples — and your resellers can read them without an account.