NDM X Studio Top UP api âš¡ Developer Portal
NDM X Studio Top UP api API
Free Fire auto top-up for Unipin vouchers and Garena Shells across BD, SG, MY, and Indonesia. Send a request, get a webhook callback (or an instant sync response) with per-item success/failure detail. This page covers authentication, every endpoint, every callback format, and every error code the API returns.
Base URL
http://your.vouchershop.autotopup.api.com
Authentication
Every request must include your API key in the Authorization header. No Bearer prefix — send the key as-is.
Authorization: your_api_key_here
Errors & Status Codes
Auth, limit, and validation failures return JSON with an error message and a machine-readable code.
Authentication errors
Token validity, expiry & access control
Authorization header
Limit & server errors
Balance, capacity & internal availability
/topup instead
Request validation errors
Malformed payload, region & field checks
package required for Shell orders
Unipin Voucher Top-up
Redeems one or more Unipin voucher codes for a Free Fire player. This is the async endpoint — it accepts the order, responds immediately with processing, then sends the final result to your url as a webhook callback.
Body parameters
| Field | Type | Required |
|---|---|---|
| orderid | string | required |
| playerid | string | required |
| code | string | required |
| url | string | required |
playerid — the Free Fire player UID being topped up.
code — one or more Unipin voucher codes, comma-separated (max 5). Each code is
SERIAL PIN.url — your webhook URL. The order result is POSTed here when processing finishes.
Example request
curl -X POST http://your.vouchershop.autotopup.api.com/topup \
-H "Authorization: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"orderid": "order-001",
"playerid": "123456789",
"code": "BDMB-T-S-01885045 6591-4164-9992-5148,BDMB-Q-S-12512238 3357-3436-4346-4621",
"url": "https://your-webhook.com/callback"
}'
Immediate response
The server accepts the order and starts processing in the background.
status: processing
Callback — all success
Sent to your url once every voucher in the batch has been redeemed.
{
"status": "success",
"orderid": "test-001",
"content": {
"batch": [
{
"uc": "BDMB-Q-S-12513859 5265-6592-7735-1778",
"ok": true,
"detail": "✅ Success"
},
{
"uc": "BDMB-Q-S-12513264 6642-2292-1792-2551",
"ok": true,
"detail": "✅ Success"
}
],
"callback_url": "https://testdummy.onrender.com/health"
},
"nickname": "KNGᴇꟙᗙᴀá´á´˜ÉªÊ€á´‡"
}
Callback — all failed
{
"status": "failed",
"orderid": "test-001",
"content": {
"batch": [
{
"uc": "BDMB-Q-S-12513859 5265-6592-7735-1778",
"ok": false,
"detail": "⌠Consumed Voucher"
},
{
"uc": "BDMB-Q-S-12513264 6642-2292-1792-2551",
"ok": false,
"detail": "⌠Consumed Voucher"
}
],
"callback_url": "https://testdummy.onrender.com/health"
},
"nickname": "KNGᴇꟙᗙᴀá´á´˜ÉªÊ€á´‡"
}
Callback — partial success
Some vouchers redeemed, others failed. Check each batch item's ok field individually.
{
"status": "partial",
"orderid": "test-001",
"content": {
"batch": [
{
"uc": "BDMB-Q-S-12513859 5265-6592-7735-1778",
"ok": true,
"detail": "✅ Success"
},
{
"uc": "BDMB-Q-S-12513264 6642-2292-1792-2551",
"ok": false,
"detail": "⌠Consumed Voucher"
}
],
"callback_url": "https://testdummy.onrender.com/health"
},
"nickname": "KNGᴇꟙᗙᴀá´á´˜ÉªÊ€á´‡"
}
Possible detail values
detail enum
3 rows
| Detail | Meaning |
|---|---|
| ⌠Consumed Voucher | Voucher was already used |
| Uid is invalid | The provided Player ID doesn't exist |
| Only BD region supported. Your region: SG | This shop only accepts Bangladesh-server UIDs |
Unipin Voucher Top-up — Instant
Same Unipin redemption, but synchronous: the full result comes back in the HTTP response itself. No url field, no callback — useful when you would rather wait on the request than handle a webhook.
Example request
Note the codes use a colon SERIAL:PIN format on this endpoint.
curl -X POST http://your.vouchershop.autotopup.api.com/topup-instant \
-H "Authorization: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"orderid": "order-002",
"playerid": "123456789",
"code": "BDMB-T-S-01885045:6591-4164-9992-5148,BDMB-Q-S-12512238:3357-3436-4346-4621,BDMB-I-S-03420017:2334-2751-3366-1131,BDMB-I-S-03421301:6497-3777-3756-4271,BDMB-I-S-03422906:1449-1937-9239-3661"
}'
Response — all success
{
"status": "success",
"orderid": "order-002",
"content": {
"batch": [
{ "uc": "BDMB-T-S-01885045 6591-4164-9992-5148", "ok": true, "detail": "✅ Success" },
{ "uc": "BDMB-Q-S-12512238 3357-3436-4346-4621", "ok": true, "detail": "✅ Success" },
{ "uc": "BDMB-I-S-03420017 2334-2751-3366-1131", "ok": true, "detail": "✅ Success" },
{ "uc": "BDMB-I-S-03421301 6497-3777-3756-4271", "ok": true, "detail": "✅ Success" },
{ "uc": "BDMB-I-S-03422906 1449-1937-9239-3661", "ok": true, "detail": "✅ Success" }
]
},
"nickname": "PlayerName"
}
Response — all failed / partial
Same batch shape as the async endpoint — see the /topup examples above for the all-failed and partial-success formats. The same detail values apply (Consumed Voucher, invalid UID, region mismatch).
Supported Vouchers
Each Unipin denomination has both a voucher and gift-card variant, both accepted by code.
| Value | Voucher prefix | Gift card prefix |
|---|---|---|
| 20UC / 25 Diamond | BDMB-T-S-xxxxxxxx | UPBD-Q-S-xxxxxxxx |
| 36UC / 50 Diamond | BDMB-U-S-xxxxxxxx | UPBD-R-S-xxxxxxxx |
| 80UC / 115 Diamond | BDMB-J-S-xxxxxxxx | UPBD-G-S-xxxxxxxx |
| 160UC / 240 Diamond | BDMB-I-S-xxxxxxxx | UPBD-F-S-xxxxxxxx |
| 161UC / Weekly | BDMB-Q-S-xxxxxxxx | UPBD-N-S-xxxxxxxx |
| 405UC / 610 Diamond | BDMB-K-S-xxxxxxxx | UPBD-H-S-xxxxxxxx |
| 800UC / Monthly | BDMB-S-S-xxxxxxxx | UPBD-P-S-xxxxxxxx |
| 810UC / 1240 Diamond | BDMB-L-S-xxxxxxxx | UPBD-I-S-xxxxxxxx |
| 1625UC / 2530 Diamond | BDMB-M-S-xxxxxxxx | UPBD-J-S-xxxxxxxx |
| 2000UC | Wallet-loadable UC — no fixed prefix | |
8 chars after BDMB- to detect the voucher variant programatically. The final S indicates region-locked (BD market).
Garena Shell Top-up
Tops up Garena Shell on the SG, MY, BD, or Indonesia shop backend. Same /topup endpoint as Unipin — the code field switches it into shell mode. Async: responds immediately, then calls your url with the result.
Body parameters
| Field | Type | Required |
|---|---|---|
| orderid | string | required |
| playerid | string | required |
| code | string | required |
| package | string | required |
| qty | integer | required |
| username | string | required |
| password | string | required |
| autocode | string | required |
| url | string | required |
shell (bdgamebazar.com), sgshell (shop.garena.sg), myshell (shop.garena.my), or indoshell (kiosgamer.co.id).package — the package code for that shop (see the reference table below).
qty — quantity to purchase.
username / password — your Garena shop account credentials.
autocode — your secret OTP/auth key for that shop account.
Example request
curl -X POST http://your.vouchershop.autotopup.api.com/topup \
-H "Authorization: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"orderid": "shell-001",
"playerid": "123456789",
"code": "shell",
"package": "lvl6",
"qty": 1,
"username": "your_username",
"password": "your_password",
"autocode": "your_secret_key",
"url": "https://your-webhook.com/callback"
}'
Immediate response
status: accepted
Callback — single item, success
{
"status": "success",
"orderid": "ORDER123",
"content": {
"batch": [
{
"package": "LITE",
"ok": true,
"detail": "Success"
}
]
},
"nickname": "PlayerName"
}
Callback — single item, failed
{
"status": "failed",
"orderid": "ORDER123",
"content": {
"batch": [
{
"package": "LITE",
"ok": false,
"detail": "Insufficient Garena shells"
}
]
},
"nickname": "PlayerName"
}
Callback — multiple shells, all success
{
"status": "success",
"orderid": "ORDER123",
"content": {
"batch": [
{"package": "LITE", "ok": true, "detail": "Success"},
{"package": "LITE", "ok": true, "detail": "Success"},
{"package": "LITE", "ok": true, "detail": "Success"},
{"package": "LITE", "ok": true, "detail": "Success"},
{"package": "LITE", "ok": true, "detail": "Success"}
]
},
"nickname": "PlayerName"
}
Callback — multiple shells, partial / all failed
When any item fails, status is "failed" at the top level even if some items succeeded — check each batch entry's ok field for the real per-item outcome.
{
"status": "failed",
"orderid": "ORDER123",
"content": {
"batch": [
{"package": "LITE", "ok": false, "detail": "Insufficient Garena shells"},
{"package": "LITE", "ok": false, "detail": "Insufficient Garena shells"},
{"package": "LITE", "ok": false, "detail": "Insufficient Garena shells"},
{"package": "LITE", "ok": false, "detail": "Insufficient Garena shells"},
{"package": "LITE", "ok": false, "detail": "Insufficient Garena shells"}
]
},
"nickname": "PlayerName"
}
Garena Shell — Instant Sync
Same Garena Shell payload as the async /topup endpoint, but synchronous. Drop the url field — the result comes back immediately in the HTTP response, no webhook callback needed.
Example request
curl -X POST http://your.vouchershop.autotopup.api.com/topup-instant \
-H "Authorization: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"orderid": "shell-001",
"playerid": "123456789",
"code": "shell",
"package": "lvl6",
"qty": 1,
"username": "your_username",
"password": "your_password",
"autocode": "your_secret_key"
}'
No url parameter. Response is immediate (no webhook). Formats are identical to the async callback examples above (single success/failed, multiple success/partial/failed). If server is busy, returns HTTP 503.
Response — single shell, success
{
"status": "success",
"orderid": "shell-001",
"content": {
"batch": [
{
"package": "LVL6",
"ok": true,
"detail": "Success"
}
]
},
"nickname": "PlayerName"
}
Response — single shell, failed
{
"status": "failed",
"orderid": "shell-001",
"content": {
"batch": [
{
"package": "LVL6",
"ok": false,
"detail": "Wrong OTP"
}
]
},
"nickname": "PlayerName"
}
Response — multiple shells (qty > 1)
{
"status": "success",
"orderid": "shell-001",
"content": {
"batch": [
{"package": "LVL6", "ok": true, "detail": "Success"},
{"package": "LVL6", "ok": true, "detail": "Success"},
{"package": "LVL6", "ok": false, "detail": "Insufficient Garena shells"}
]
},
"nickname": "PlayerName"
}
Response — server busy
If the instant endpoint is overloaded, use async /topup instead.
{
"error": "Server busy — use /topup for queued processing.",
"code": "SERVER_BUSY"
}
Shop & Package Reference
sgshell shop.garena.sg backend
| Category | Packages |
|---|---|
| Membership | weekly, monthly, Lite, 3D, 7D, 30D |
| Level Up | lvl6, lvl10, lvl15, lvl20, lvl25, lvl30, lvlall |
| Diamonds | 25, 100, 310, 520, 1060, 2180, 5600, 11500 |
indoshell kiosgamer.co.id backend
| Category | Packages |
|---|---|
| Membership | weekly, monthly |
| Booyah Pass | bp |
| Diamonds | 5, 50, 70, 140, 355, 720, 7290 |
| Level Up | lvl6, lvl10, lvl15, lvl20, lvl25, lvl30, lvlall |
myshell shop.garena.my backend
| Category | Packages |
|---|---|
| Membership | weekly, monthly |
| Diamonds | 25, 100, 310, 520, 1060, 2180, 5600, 11500 |
| Other | Lite, 3D, 7D, 30D, lvl6, lvl10, lvl15, lvl20, lvl25, lvl30 |
shell bdgamebazar.com backend
| Category | Packages |
|---|---|
| Membership | Lite, 3D, 7D, 30D |
| Level Up | 108588 (Lvl 6), 108589 (Lvl 10), 108590 (Lvl 15), 108591 (Lvl 20), 108592 (Lvl 25), 108593 (Lvl 30) |
Package names returned in callbacks
| Shop | Package names |
|---|---|
| BD Shell | LITE, EVO3, EVO7, EVO30, LVL6, LVL10, LVL15, LVL20, LVL25, LVL30 |
| SG / MY Shell | LITE, EVO3, EVO7, EVO30, 25, 100, 310, 520, 1060, 2180, 5600, 11500, Weekly, Monthly |
| Indo Shell | 5, 50, 70, 140, 355, 720, 7290, 36500, 73100, Weekly, Monthly, BP |
| All regions | LVL6, LVL10, LVL15, LVL20, LVL25, LVL30 (Level Up Pass) |
package values you will receive in the POST callback body — match them in your DB lookup, not the input codes.
Shell Detail Messages
Possible values for the detail field on shell top-up responses.
detail enum values
8 values
| Detail |
|---|
| Insufficient garena shells |
| Wrong OTP |
| UID is invalid |
| Inaccurate region |
| UID region mismatch |
| Garena server error or wrong shell account |
| Garena transaction error |
| Level up pass not eligible |
detail field in your webhook handler.
Search Previous Orders
Look up any past order by order ID, player ID, or voucher code prefix.
By order ID
curl -X GET "https://your.vouchershop.autotopup.api.com/search?orderid=ORDER123" \ -H "Authorization: your_token_here"
By player ID
curl -X GET "https://your.vouchershop.autotopup.api.com/search?playerid=123456789" \ -H "Authorization: your_token_here"
By voucher code
curl -X GET "https://your.vouchershop.autotopup.api.com/search?code=BDMB-T" \ -H "Authorization: your_token_here"
Example response — Unipin voucher order
{
"count": 1,
"results": [
{
"orderid": "test-001",
"playerid": "2716319203",
"order_type": "voucher",
"status": "success",
"player_name": "PlayerName",
"elapsed": 3.21,
"success_count": 2,
"total_count": 2,
"source": "topup",
"created_at": "2026-06-27T09:00:00",
"result": {
"results": [
{
"serial": "BDMB-Q-S-12513859",
"pin": "5265-6592-7735-1778",
"success": true,
"message": "",
"player_name": "PlayerName",
"product": "Weekly Membership",
"node": "VPS-01"
},
{
"serial": "BDMB-Q-S-12513264",
"pin": "6642-2292-1792-2551",
"success": true,
"message": "",
"player_name": "PlayerName",
"product": "Weekly Membership",
"node": "VPS-01"
}
]
}
}
]
}
Example response — Garena Shell order
{
"count": 1,
"results": [
{
"orderid": "ORDER123",
"playerid": "2716319203",
"order_type": "shell",
"status": "success",
"player_name": "PlayerName",
"elapsed": 4.32,
"success_count": 1,
"total_count": 1,
"source": "topup",
"created_at": "2026-06-27T09:00:00",
"result": {
"results": [
{
"package": "LITE",
"success": true,
"message": "",
"node": "VPS-01"
}
]
}
}
]
}