UniPin TopUp API
Automated Free Fire diamond and membership top-up for the Bangladesh region, paid with UniPin Vouchers and Up Gift Cards. Send a player ID and the voucher code — the denomination and the payment method are read straight off the serial, so there is no package ID to choose.
Overview
Two ways to place an order. Sync holds the connection open and returns the result directly. Callback accepts the order immediately with 202 Accepted and posts the result to a URL you provide once the vouchers have been processed.
| Method | Endpoint | Description |
|---|---|---|
| POST | /topup-sync | Place an order and wait for the result. |
| POST | /topup | Place an order, receive 202, get the result posted to your callback URL. |
| GET | /status/{apikey} | Check your credit balance and account state. |
Region restricted. Orders are only accepted for Bangladesh players. Any other region is rejected with Only For BD Region! and is never charged.
Authentication
Every request needs your API token, a UUID issued with your account. Send it in any one of three ways — the server checks the header first, then the query string, then the body.
Header
Authorization: Bearer <token>
Query string
?token=<token>
JSON body
"token": "<token>"
The Bearer prefix is optional in the header, and any body field holding a UUID is accepted, so an existing apikey field keeps working.
curl -X POST https://your-domain.com/topup-sync \ -H "Authorization: Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"orderid":"ORD-1001","playerid":"850059596","code":"BDMB-T-S-02762503 6451-1144-9921-7716"}'
Keep your token private. It is the only thing protecting your credits. Tokens are compared in constant time, never appear in a response body, and repeated failures get the source IP banned — see Error Codes.
/topup-sync
Places the order and returns the full result in the same response. Use this when your client can wait — a single voucher typically takes a few seconds.
Request body
| Field | Type | Description |
|---|---|---|
| orderid | string | Your own order reference. Echoed back untouched. |
| playerid | string | The Free Fire player ID to top up. |
| code | string · array | One voucher code, or several. Accepts a comma-separated string or a JSON array. Maximum 5 codes per order. |
| token | string | Optional here if you sent the token in the header or query string. |
Single voucher
{
"orderid": "ORD-1001",
"playerid": "850059596",
"code": "BDMB-T-S-02762503 6451-1144-9921-7716"
}Multiple vouchers
{
"orderid": "ORD-1002",
"playerid": "850059596",
"code": [
"BDMB-T-S-02762503 6451-1144-9921-7716",
"UPBD-Q-S-02762504 1111-2222-3333-4444"
]
}Response — 200 OK
{
"status": "success",
"orderid": "ORD-1002",
"username": "NabilFF",
"total": 2,
"success": 1,
"failed": 1,
"batch": [
{ "uc": "BDMB-T-S-02762503 6451-1144-9921-7716", "ok": false, "detail": "Used Uc Code" },
{ "uc": "UPBD-Q-S-02762504 1111-2222-3333-4444", "ok": true, "detail": "Success" }
],
"time_taken": "9.42s",
"copyright": "Xtreme Dev"
}status is "success" whenever the order ran, even if some codes inside it failed — read the per-code ok flags in batch for the real outcome. Order-level problems come back as {"error": "...", "status": "error"} with an HTTP error code. time_taken and copyright are reported on order results — this response and the callbacks below — and nowhere else.
/topup
Same fields as /topup-sync, plus url — the address the result is posted to. The request returns immediately; processing continues in the background.
| Field | Type | Description |
|---|---|---|
| orderid | string | Your own order reference. |
| playerid | string | The Free Fire player ID to top up. |
| code | string · array | Up to 5 voucher codes. |
| url | string | Your callback URL. Must be http:// or https://. |
| token | string | Optional if sent in the header or query string. |
curl -X POST https://your-domain.com/topup \ -H "Authorization: Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"orderid":"ORD-1003","playerid":"850059596","code":"BDMB-T-S-02762503 6451-1144-9921-7716","url":"https://your-site.com/callback"}'
Immediate response — 202 Accepted
{
"status": "accepted",
"orderid": "ORD-1003",
"message": "Order queued. Result will be posted to your callback URL."
}Reply 2xx from your callback endpoint to acknowledge. A failed delivery is retried up to 3 times.
Callback Payloads
Three outcomes are posted to your url. A single-code order is never partial — it is either success or failed.
Success
{
"status": "success",
"orderid": "ORD-1001",
"nickname": "NabilFF",
"content": "✅ Success",
"batch": [
{
"uc": "BDMB-T-S-...",
"ok": true,
"detail": "✅ Success"
}
],
"time_taken": "4.71s",
"copyright": "Xtreme Dev"
}Partial
{
"status": "partial",
"orderid": "ORD-1002",
"nickname": "NabilFF",
"content": {
"batch": [
{
"uc": "BDMB-T-S-...",
"ok": true,
"detail": "✅ Success"
},
{
"uc": "UPBD-Q-S-...",
"ok": false,
"detail": "❌ Used Uc Code"
}
]
},
"time_taken": "9.42s",
"copyright": "Xtreme Dev"
}Failed
{
"status": "failed",
"orderid": "ORD-1004",
"nickname": null,
"content": "❌ Invalid Player ID",
"batch": [],
"time_taken": "1.12s",
"copyright": "Xtreme Dev"
}content carries the headline result: the string "✅ Success" when everything redeemed, the batch object when the order was partial, and "❌ <reason>" when nothing did. The top-level batch array is always present.
/status/{apikey}
Returns your account state and remaining credits. Pass your own token as the path segment.
curl https://your-domain.com/status/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx{
"status": "success",
"data": {
"name": "Default Shop",
"account_status": "active",
"credits": {
"max_limit": 1000,
"limit_left": 742,
"used_this_month": 258
},
"expiry_date": null,
"is_expired": false
}
}expiry_date is null on accounts with no expiry.
Credits
Credits are consumed per code, not per request. An order that never reached the redemption step costs nothing.
| Outcome | Credits used |
|---|---|
| UniPin voucher or Up Gift Card redeemed | 1 per code |
| Code rejected — already used, invalid serial or PIN | 1 per code (configurable) |
| Invalid Player ID | 0 — never charged |
| Region rejected, bad request, quota exhausted | 0 — never charged |
max_limit
Total credits on the account.
limit_left
Remaining balance. Orders stop at zero with 402.
used_this_month
Usage counter, reset at the start of each month.
Packages
The denomination is read from the voucher serial — send the code as it is and the right package is chosen automatically. Both payment methods are supported for every package.
| Package | UniPin prefix | Up Gift prefix | Method |
|---|---|---|---|
| 25 Diamond | BDMB-T | UPBD-Q | Both |
| 50 Diamond | BDMB-U | UPBD-R | Both |
| 115 Diamond | BDMB-J | UPBD-G | Both |
| 240 Diamond | BDMB-I | UPBD-F | Both |
| 610 Diamond | BDMB-K | UPBD-H | Both |
| 1240 Diamond | BDMB-L | UPBD-I | Both |
| 2530 Diamond | BDMB-M | UPBD-J | Both |
| Weekly Membership | BDMB-Q | UPBD-N | Both |
| Monthly Membership | BDMB-S | UPBD-P | Both |
# both of these redeem the 25 Diamond package BDMB-T-S-02762503 6451-1144-9921-7716 # UniPin Voucher UPBD-Q-S-02762504 1111-2222-3333-4444 # Up Gift Card
Error Codes
Errors return {"error": "...", "status": "error"} with the matching HTTP status. Nothing is charged unless the order reached redemption.
| Code | Message | When it happens |
|---|---|---|
| 401 | Missing / Invalid API token | No token was sent, or it does not match an account. |
| 402 | Limit exhausted / quota expired | The account is out of credits or has passed its expiry date. |
| 403 | IP banned / too many invalid attempts | Too many failed authentications from your IP. The ban lifts automatically. |
| 400 | Missing required fields | orderid, playerid or code was not sent. |
| 400 | Max 5 codes per order | More than 5 codes were sent in one request. Split them across orders. |
| 400 | Invalid Player ID | The player ID could not be resolved on Garena. Never charged. |
| 400 | Only For BD Region! | The player account is not in the Bangladesh region. Never charged. |
| 400 | Invalid callback URL | The url is missing, not http(s), or points at a private address. |
| 429 | Rate limit exceeded | Too many requests in a minute. Slow down and retry. |
| 500 | Service temporarily unavailable | Garena blocked the request or the handshake failed on our side. Retry shortly. Never charged. |
| 500 | Database / Internal error | Something failed on our side. Retry the order. |
{
"error": "Missing / Invalid API token",
"status": "error"
}