Orders & status

pid always comes from GET /products. GET = read, POST = write with a JSON body where shown.

GET vs POST (rules)

GET: no body. Query string only when we show it (e.g. /history?limit=20). POST: Content-Type: application/json when a body is listed.

Goal Method & path
Service lines & field requirements GET /services
Catalog (GWPIDs, prices, stock where applicable) GET /products or /catalog
Public IP the API sees GET /my-ip
Balance in USD (read only) GET /balance
Order history (newest first) or paginated GET /history?limit=
One order by id (poll status) GET /orders/:orderId
Place an order POST /orders
PUBG / ML verify, PUBG redeem (see ref) POST /pubgvvfy, /mlvfy, /rdmpubg

GWPID (pid) — always from the catalog

Call GET /products (or GET /catalog). Each line exposes an id — that string is the GWPID. Pass it as pid (or PID in some parsers). The token format is deployment-specific; the examples below are structural only: copy real id values from your products array in production.

Do not fabricate PIDs Use a live id from the catalog. Ad-hoc slugs (e.g. a custom “pack name” string) are not accepted unless that exact key exists in the current catalog and stock rules.

Example 1 — userId only (e.g. PUBG)

Service slug: pubgGET /services lists userId (Player ID) only, alongside the implicit pack in pid.

Request body (replace pid with a real id from your catalog, e.g. 60 UC line):

{
  "pid": "GWP60",
  "userId": "51234567890",
  "trxid": "INV-10001"
}
curl -X POST "https://api.gwultimatebot.com/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"pid":"GWP60","userId":"51234567890","trxid":"INV-10001"}'

Player ID must be a valid PUBG Mobile–style numeric id as accepted by the bot for that product.

Example 2 — userId + zoneId (e.g. Mobile Legends — Global)

Service slug: mobilelegendrequired includes userId and zoneId.

{
  "pid": "GWML86",
  "userId": "123456789",
  "zoneId": "1234",
  "trxid": "ML-ORD-2001"
}
curl -X POST "https://api.gwultimatebot.com/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"pid":"GWML86","userId":"123456789","zoneId":"1234","trxid":"ML-ORD-2001"}'

Example 3 — userId + serverId (e.g. Genshin — Global)

Service slug: genshin — you must pass serverId (redeemable region). Common values include asia, america, europe, tw_hk_mo (or labels like Asia, NA as supported by the resolver — see POST /orders).

{
  "pid": "GWGI6480",
  "userId": "800012345",
  "serverId": "asia",
  "trxid": "GI-ORD-3001"
}
curl -X POST "https://api.gwultimatebot.com/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"pid":"GWGI6480","userId":"800012345","serverId":"asia","trxid":"GI-ORD-3001"}'

Other slug values that use serverId (e.g. Honkai, ZZZ, WUWA) follow the same body shape; always confirm allowed serverId in GET /services (when present, the API includes serverIdOptions).

Game keys & gift cards

These lines require pid + quantity (and not a separate cart quantity in the same way as top-up — the API enforces that only these kinds accept quantity on POST /orders).

{
  "pid": "GWGKPU60",
  "quantity": 2,
  "trxid": "GK-BULK-4001"
}

pid must be the exact id for a game-key or gift-card line from GET /products (format is GW + line code + pack token).

Quantity If you pass quantity for services that are not game keys or gift cards, the API returns QUANTITY ONLY FOR GAMEKEY OR GIFTCARD (400).

Place an order, read errors, poll status

1) Check balance (optional)

GET /balance — 200

curl -X GET "https://api.gwultimatebot.com/balance" -H "X-API-Key: YOUR_API_KEY"

{ "success": true, "balanceUsd": 12.5, "currency": "USD" }

There is no POST /balance or “add balance” API; fund the wallet in Telegram only.

2) Place order — success path

POST /orders — 200 (body shape = invoice / status)

curl -X POST "https://api.gwultimatebot.com/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"pid":"GWP60","userId":"51234567890","trxid":"INV-10001"}'

{
  "orderCreated": true,
  "orderId": "GWAPI-PU-2A3B-9F0C1D",
  "status": "processing",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "userId": "51234567890"
}

Keep orderId to poll. Same trxid = same order if you retry a failed call.

3) Place order — common error (example)

POST /orders — 4xx (shape varies)

{
  "success": false,
  "error": "UNKNOWN PID"
}

// 400: invalid or unknown catalog id (use GET /products id)

{
  "success": false,
  "error": "INSUFFICIENT BALANCE"
}
// 200 with cancelled invoice when wallet cannot cover
{
  "orderCreated": false,
  "status": "cancelled",
  "game": "pubg",
  "error": "INSUFFICIENT BALANCE"
}

Map error in your client; 4xx/5xx carry the same success: false pattern; see Error catalog.

4) List recent orders (optional panel)

GET /history?limit=10 — 200

curl -G "https://api.gwultimatebot.com/history" \
  -H "X-API-Key: YOUR_API_KEY" --data-urlencode "limit=10"

{
  "success": true,
  "count": 10,
  "orders": [
    { "orderId": "GWAPI-PU-…", "status": "completed", "game": "pubg", "amountUsd": 0.99, ... }
  ]
}

5) Poll a single id until done

GET /orders/{orderId} — 200 or 404

curl -X GET "https://api.gwultimatebot.com/orders/GWAPI-PU-2A3B-9F0C1D" \
  -H "X-API-Key: YOUR_API_KEY"

// Later — terminal success
{
  "orderId": "GWAPI-PU-2A3B-9F0C1D",
  "status": "completed",
  "game": "pubg",
  "amountUsd": 0.99,
  "durationSec": 12
}

// 404
{ "success": false, "error": "ORDER NOT FOUND" }

Repeat the GET (with backoff) until status is completed or cancelled — the same as the status table.

Order status

Invoice responses from POST /orders and GET /orders/<id> use a normalized lifecycle for display:

Status Meaning
pending Order is accepted and queued; not final.
processing Work in progress (activation, supplier, or polling still running).
completed Success terminal state; delivery or activation finished.
cancelled Failure or cancellation; use error and refunded when present.

Typical success fields: orderId (public id like GWAPI-… when available), game (slug), packName, amountUsd, durationSec, and identifiers you sent (userId, zoneId, serverId). For game keys / gift cards, codes may be present when delivery completes.

// Example: processing
{
  "orderCreated": true,
  "orderId": "GWAPI-PU-ABC123-XYZ999",
  "status": "processing",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "userId": "51234567890"
}

// Example: completed
{
  "orderCreated": true,
  "orderId": "GWAPI-PU-ABC123-XYZ999",
  "status": "completed",
  "game": "pubg",
  "amountUsd": 0.99,
  "durationSec": 8
}

// Example: failed before or at terminal cancel
{
  "orderCreated": false,
  "status": "cancelled",
  "game": "pubg",
  "error": "INSUFFICIENT BALANCE"
}

Tips

  1. New order → new trxid. Reuse the same trxid only when you mean the same purchase.
  2. GET /history for a list; GET /orders/<id> to poll one id.
  3. Balance is read-only. Need more? Top up in Telegram.
  4. Done = completed or cancelledtable. New charge needs a new trxid after a cancel you didn’t mean to replay.
GW Ultimate