GW Ultimate API
Docs

Reference

Base URL: https://api.sonofutred.com. Every request needs X-API-Key or Authorization: Bearer <key>.

API URL Prefix every path with https://api.sonofutred.com (example: POST https://api.sonofutred.com/orders).

Catalog — GET /services

Games and what each one needs in the order body (userId, zoneId, serverId, …). Unavailable games don’t show up.

Response: { "success": true, "services": [ ... ] }

Each service includes: productName, slug, gameName, required (array of field + label), status. Some lines may also include serverIdOptions or regionOptions when a server/region is required. Pack ids: Games & PIDs.

curl -X GET "https://api.sonofutred.com/services" -H "X-API-Key: YOUR_API_KEY"

GET /products and /catalog

Alias: GET /catalog returns the same payload as GET /products.

The product database for ordering: one row per active pack with a stable id (GWPID). That value is what you pass as pid on POST /orders. Rows include slug, gameName, serviceName, price, stock where applicable, etc.

For gamekey and giftcard (and PUBG stock packs), each row also includes quantity = live available stock, plus inStock, quantityMin, and quantityMax (capped by stock, max 500 per order).

curl -X GET "https://api.sonofutred.com/products" -H "X-API-Key: YOUR_API_KEY"

// gamekey / giftcard example
{
  "success": true,
  "products": [
    {
      "id": "GWPK60",
      "slug": "gamekeypubg",
      "gameName": "Game Keys — PUBG Mobile",
      "serviceName": "60UC",
      "category": "gamekeypubg",
      "price": 0.858,
      "quantityMin": 1,
      "quantityMax": 42,
      "inStock": true,
      "quantity": 42,
      "status": "active"
    }
  ]
}
id → pid Copy products[i].id from this response into the order body as pid (or PID).

GET /my-ip

Your public IP as our side sees it.

curl -X GET "https://api.sonofutred.com/my-ip" -H "X-API-Key: YOUR_API_KEY"

// { "success": true, "ip": "203.0.113.4" }

GET /balance GET

Check your account balance (USD). Read-only; top up in Telegram.

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

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

POST /orders POST

Submit / create an order. Game is picked from the pid (catalog id). On success you get the same invoice shape as GET /orders/:orderId.

Body (unified)

Field Notes
pid / PID Required. GWPID from GET /productsid.
trxid (or trxId, idtrx, idTrx) Your id for the order. New purchase → new trxid.
userId / userID Required for most games (player / uid / Riot ID / live-app id / Zepeto username as defined by the line).
zoneId Required for ML-style lines (numeric zone).
serverId Required for GI / HSR / ZZZ / WUWA / IDV / Once Human region and similar. Once Human also accepts region shortcuts (eu, na, …).
quantity Only for gamekey and giftcard kinds (1–500 per order). Over 500 → rejected with QUANTITY EXCEEDS MAX (no silent cap).
idempotencyKey / idempotency Optional; if omitted, trxid is used for idempotency as implemented.
curl -X POST "https://api.sonofutred.com/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"pid":"GWPUBG60","userId":"51234567890","trxid":"ORD-1001"}'

Responses — submit / processing / completed

orderCreated: true means the order was accepted. Poll GET /orders/:orderId while status is processing. Stop on completed or cancelled. Empty fields may be omitted.

Accepted — still processing (200)

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "processing",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 1,
  "userId": "51234567890"
}

Completed (200) — instant fulfillment, or after polling

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "completed",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 34,
  "userId": "51234567890"
}

Gamekey / gift card completed (200) — includes delivered codes

{
  "orderCreated": true,
  "orderId": "GW-API-GK-A1B2C3-D4E5F6A7",
  "status": "completed",
  "game": "gamekey",
  "packName": "60 UC Code",
  "amountUsd": 0.95,
  "durationSec": 2,
  "codes": ["XXXX-XXXX-XXXX", "YYYY-YYYY-YYYY"]
}

Rejected at submit (400) — no order created

{
  "orderCreated": false,
  "status": "cancelled",
  "game": "pubg",
  "error": "INSUFFICIENT BALANCE"
}

Other submit failures

// 400
{ "success": false, "error": "INVALID BODY" }
{ "success": false, "error": "INVALID REQUEST" }
{ "success": false, "error": "UNKNOWN PID" }
{ "success": false, "error": "INVALID PACK" }
{ "success": false, "error": "GAME DISABLED" }

// 403 — trxid owned by another API user
{ "success": false, "code": "FORBIDDEN", "error": "FORBIDDEN" }

// 429 — same order still in flight
{ "success": false, "code": "DUPLICATE_IN_FLIGHT", "error": "DUPLICATE_IN_FLIGHT" }

// 503
{ "success": false, "code": "MAINTENANCE", "error": "MAINTENANCE" }
{ "success": false, "code": "API_ORDER_DISABLED", "error": "API_ORDER_DISABLED" }

Idempotent replay (200) — same trxid again

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "completed",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 120,
  "userId": "51234567890",
  "idempotentReplay": true
}

Walkthrough: Orders & status. Fixed subscription / special / CN PIDs: Games & PIDs.

Downtime: you may get 503 and MAINTENANCE or API_ORDER_DISABLED — see errors.

GET /history GET

Your last purchased history — recent orders for your account, newest first. Same invoice shape as GET /orders/:orderId (and successful POST /orders). Single-order lookup: GET /orders/:orderId.

Query: simple limit

Default limit=30 (min 1, max 200).

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

// 200
{
  "success": true,
  "count": 25,
  "orders": [ { "orderId": "GW-API-PBG-…", "status": "completed", "game": "pubg", ... }, ... ]
}

Query: pagination

Pass page to switch to paged mode (optional pageSize, default 20, max 50). Response includes total and hasMore.

curl -G "https://api.sonofutred.com/history" \
  -H "X-API-Key: YOUR_API_KEY" \
  --data-urlencode "page=1" \
  --data-urlencode "pageSize=20"
Id lookup Use a specific public or internal id with GET /orders/:orderId after POST /orders (see Guides: lifecycle & examples).

GET /orders/:orderId GET

Check status for one order on your account. Same invoice fields as a successful POST /orders.

curl -X GET "https://api.sonofutred.com/orders/GW-API-PBG-A1B2C3-D4E5F6A7" \
  -H "X-API-Key: YOUR_API_KEY"

Still processing (200)

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "processing",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 45,
  "userId": "51234567890"
}

Completed (200)

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "completed",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 52,
  "userId": "51234567890"
}

Cancelled / failed after placement (200)

{
  "orderCreated": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "cancelled",
  "game": "pubg",
  "packName": "60 UC",
  "amountUsd": 0.99,
  "durationSec": 18,
  "userId": "51234567890",
  "error": "INVALID PLAYER",
  "refunded": true
}

Not found (404)

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

404 if the id does not belong to your account or does not exist.

Redeem & verify

These endpoints charge a small fee from your wallet (or use free ML quota). They do not place a catalog top-up order. Always send a unique trxid; replaying the same trxid returns the cached result with idempotentReplay: true (no second charge). Empty fields may be omitted.

Endpoint Price
POST /pubgvvfy $0.0017 per call
POST /mlvfy First 20/day free, then $0.02 per call
POST /rdmpubg $0.0017 per call
HTTP 200 ≠ always success For verify/redeem, check success in the body. A lookup/redeem failure can still return 200 with success: false and status: "cancelled" (fee may already be deducted).

POST /pubgvvfy

Resolve / verify a PUBG player id (in-game name check) without placing an order.

{
  "playerId": "51234567890",
  "trxid": "CHK-PUBG-001"
}
curl -X POST "https://api.sonofutred.com/pubgvvfy" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"playerId":"51234567890","trxid":"CHK-PUBG-001"}'

Also accepts playerID, userId / userID in place of playerId. PUBG UID should be numeric and start with 5.

Success (200)

{
  "success": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "completed",
  "playerId": "51234567890",
  "playerName": "PlayerName",
  "deductedBalance": 0.0017,
  "durationSec": 2
}

Player not found (200) — fee deducted

{
  "success": false,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "cancelled",
  "playerId": "51234567890",
  "deductedBalance": 0.0017,
  "durationSec": 2,
  "error": "PLAYER NOT FOUND"
}

Invalid player id (400)

{
  "success": false,
  "error": "INVALID PLAYER ID"
}

Insufficient balance (400)

{
  "success": false,
  "error": "INSUFFICIENT BALANCE"
}

Invalid body / missing fields (400)

{
  "success": false,
  "error": "INVALID BODY"
}
// or
{
  "success": false,
  "error": "INVALID REQUEST"
}

Idempotent replay (200)

{
  "success": true,
  "orderId": "GW-API-PBG-A1B2C3-D4E5F6A7",
  "status": "completed",
  "playerId": "51234567890",
  "playerName": "PlayerName",
  "deductedBalance": 0.0017,
  "durationSec": 2,
  "idempotentReplay": true
}

POST /mlvfy

Mobile Legends user + zone verification (region / profile + first-time bonus tiers).

{
  "userId": "123456789",
  "zoneId": "1234",
  "trxid": "CHK-ML-001"
}
curl -X POST "https://api.sonofutred.com/mlvfy" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"userId":"123456789","zoneId":"1234","trxid":"CHK-ML-001"}'

Aliases: userID, zoneID, trxId. Both ids must be digits.

Success (200)

{
  "success": true,
  "orderId": "GW-API-ML-1A2B3C-4D5E6F78",
  "status": "completed",
  "userId": "123456789",
  "zoneId": "1234",
  "playerName": "PlayerName",
  "region": "Philippines",
  "firstTimeBonus": [
    { "tier": "50+50", "status": "available" },
    { "tier": "150+150", "status": "already_claimed" },
    { "tier": "250+250", "status": "available" },
    { "tier": "500+500", "status": "unknown" }
  ],
  "deductedBalance": 0,
  "freeUsedToday": 3,
  "freeLimitDaily": 20,
  "freeLeftToday": 17,
  "durationSec": 3
}

firstTimeBonus[].status: available · already_claimed · unknown. After free quota, deductedBalance is 0.02.

Region check failed (200) — may still deduct paid fee when over free quota

{
  "success": false,
  "orderId": "GW-API-ML-9Z8Y7X-6W5V4U32",
  "status": "cancelled",
  "userId": "123456789",
  "zoneId": "0000",
  "firstTimeBonus": [
    { "tier": "50+50", "status": "unknown" },
    { "tier": "150+150", "status": "unknown" },
    { "tier": "250+250", "status": "unknown" },
    { "tier": "500+500", "status": "unknown" }
  ],
  "deductedBalance": 0.02,
  "freeUsedToday": 21,
  "freeLimitDaily": 20,
  "freeLeftToday": 0,
  "durationSec": 2,
  "error": "REGION CHECK FAILED"
}

Invalid request / body (400)

{
  "success": false,
  "error": "INVALID REQUEST"
}
// or
{
  "success": false,
  "error": "INVALID BODY"
}

Insufficient balance (400) — paid checks only

{
  "success": false,
  "error": "INSUFFICIENT BALANCE"
}

POST /rdmpubg — PUBG redemption

Redeem a UC voucher/code onto a PUBG player.

{
  "playerId": "51234567890",
  "code": "ABCD-EFGH-IJKL",
  "trxid": "RDM-001"
}
curl -X POST "https://api.sonofutred.com/rdmpubg" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"playerId":"51234567890","code":"ABCD-EFGH-IJKL","trxid":"RDM-001"}'

Also accepts playerID, userId / userID for the player field.

Success (200)

{
  "success": true,
  "orderId": "GW-API-PBG-B3C4D5-E6F7A890",
  "status": "completed",
  "playerId": "51234567890",
  "name": "PlayerName",
  "ucAmount": 660,
  "productName": "660 UC",
  "deductedBalance": 0.0017,
  "durationSec": 45
}

Redemption failed (200) — fee deducted

{
  "success": false,
  "orderId": "GW-API-PBG-C7D8E9-F0A1B234",
  "status": "cancelled",
  "playerId": "51234567890",
  "deductedBalance": 0.0017,
  "durationSec": 12,
  "error": "REDEMPTION FAILED"
}

Invalid request / body (400)

{
  "success": false,
  "error": "INVALID REQUEST"
}
// or
{
  "success": false,
  "error": "INVALID BODY"
}

Insufficient balance (400)

{
  "success": false,
  "error": "INSUFFICIENT BALANCE"
}
GW Ultimate