U
UniPin TopUp API
Garena Free Fire — Bangladesh
API v1 · Live

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.

MethodEndpointDescription
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.

POST

/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

FieldTypeDescription
orderidstringYour own order reference. Echoed back untouched.
playeridstringThe Free Fire player ID to top up.
codestring · array One voucher code, or several. Accepts a comma-separated string or a JSON array. Maximum 5 codes per order.
tokenstringOptional 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.

POST

/topup

Same fields as /topup-sync, plus url — the address the result is posted to. The request returns immediately; processing continues in the background.

FieldTypeDescription
orderidstringYour own order reference.
playeridstringThe Free Fire player ID to top up.
codestring · arrayUp to 5 voucher codes.
urlstringYour callback URL. Must be http:// or https://.
tokenstringOptional 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 — every code redeemed partial — some redeemed failed — none redeemed

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.

GET

/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.

OutcomeCredits used
UniPin voucher or Up Gift Card redeemed1 per code
Code rejected — already used, invalid serial or PIN1 per code (configurable)
Invalid Player ID0 — never charged
Region rejected, bad request, quota exhausted0 — 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.

PackageUniPin prefixUp Gift prefixMethod
25 DiamondBDMB-TUPBD-QBoth
50 DiamondBDMB-UUPBD-RBoth
115 DiamondBDMB-JUPBD-GBoth
240 DiamondBDMB-IUPBD-FBoth
610 DiamondBDMB-KUPBD-HBoth
1240 DiamondBDMB-LUPBD-IBoth
2530 DiamondBDMB-MUPBD-JBoth
Weekly MembershipBDMB-QUPBD-NBoth
Monthly MembershipBDMB-SUPBD-PBoth
# 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.

CodeMessageWhen 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"
}