API Guide
One endpoint, two behaviors. Send player_id and the voucher is bought and redeemed straight into the game account automatically. Leave it out and you get a normal voucher code to redeem by hand — same request, same response shape, same everything else.
★ See it in action
What happens after POST /v1/order — this loops automatically, no clicking needed.
1 Get your API key
Send this command to the bot in a private DM, or inside your own dedicated group:
Gapikey
- If it's your first time, a key is generated automatically.
- If you already have one, the same key is shown again.
- The message self-destructs after 2 minutes — copy your key somewhere safe.
- Sent from any other/shared group, the bot deletes your message and DMs you instead, so your key never leaks to other members.
Reset / rotate your key
Gapikeyreset
This immediately deactivates your old key and issues a new one. Update it anywhere you had it saved.
2 Authentication
Every request must include these headers:
X-API-Key: YOUR_API_KEY
Content-Type: application/json
| Header | Value |
|---|---|
X-API-Key | your key, from §1 |
Content-Type | application/json |
Missing or invalid keys return 401 Unauthorized.
3 Two ways to order
There's only one endpoint. What it does depends on a single field — whether you include player_id or not:
player_id?Normal Voucher Order
You get back a voucher code. The end user redeems it inside the game themselves.
Auto Top-Up
Our system buys the voucher and redeems it straight into that Free Fire account. Nothing for the user to do.
item format, same way you check the result. The only difference is one optional field.4 Place an order
This call always responds instantly — it never waits on the supplier. You get an order_id with status pending back immediately, and the real result arrives afterwards — see §6 and §7.
Request body — Normal Voucher Order
{
"item": "80:1",
"wallet": "bd",
"callback_url": "https://yourdomain.com/webhook",
"metadata": { "your_ref": "INV-1001" }
}
Request body — Auto Top-Up (add player_id)
{
"item": "80:1",
"wallet": "bd",
"player_id": "12345678",
"callback_url": "https://yourdomain.com/webhook",
"metadata": { "your_ref": "INV-1001" }
}
| Field | Type | Required | Notes |
|---|---|---|---|
item | string | ✅ | Format: uctype:qty — see below |
wallet | string | ✅ | bd, bd_baki, usd, or usd_baki |
player_id | string | optional | Present → Auto Top-Up. Absent → Normal Voucher Order |
callback_url | string | optional | Final result gets POSTed here — see §7 |
metadata | object | optional | Your own JSON, echoed back untouched in the status/callback response |
The item format
Example: "item": "80:2,160:1" orders 2× the 80 package and 1× the 160 package in a single call — one order_id, one final result for the whole basket.
Instant response — 200 OK
{
"success": true,
"order_id": "ORD123456",
"status": "pending"
}
5 Auto Top-Up fee
Sending player_id adds one small fee per order, on top of the voucher price:
| Wallet | Fee |
|---|---|
bd / bd_baki | ৳0.50 BDT |
usd / usd_baki | $0.005 USD |
- The fee is folded into the
totalfield of the final result. - If a voucher fails and gets refunded, the fee is not refunded.
- Normal Voucher Orders have no fee at all — the fee only applies when
player_idis sent.
6 Order status & final result
Poll this any time — e.g. if you didn't set a callback_url, or as a backup. Recommended interval: every 3 seconds.
Final response — success
{
"status": "success",
"orderid": "ORD123456",
"player_id": "12345678",
"player_name": "PlayerName",
"wallet": "bd",
"total": 100.50,
"balance_after": 899.50,
"due_after": 0.00,
"fail_reason": null,
"elapsed_sec": 34.7,
"timestamp": "2026-07-24T10:00:00Z",
"metadata": { "your_ref": "INV-1001" },
"voucher_detail": {
"api_status": "success",
"items": [
{
"status": "success",
"code": "BDMB-XXXXXXXX",
"product": "80UC",
"unit_price": 50.00,
"fail_reason": ""
}
],
"summary": { "total": 1, "success": 1, "consumed": 0, "failed": 0 }
}
}
On a Normal Voucher Order (no player_id), this same shape comes back — just without player_id/player_name. Read the code straight from voucher_detail.items[].code and hand it to your user to redeem.
Status values
| status | Meaning |
|---|---|
| pending | Still processing — not final yet |
| success | All packages topped up / delivered successfully |
| partial | Some packages succeeded, the rest were refunded |
| failed | No package succeeded |
Voucher item status — inside voucher_detail.items[]
| status | Meaning |
|---|---|
| success | Voucher redeemed successfully |
| consumed | That specific code was already used previously |
| failed | Could not redeem — see its own fail_reason |
7 Callbacks (webhooks)
If you set callback_url, the API POSTs the exact same final-result payload shown in §6 to that URL automatically — no polling needed.
What your endpoint must do
- Respond with any 2xx status code to acknowledge receipt.
- Respond within ~10 seconds.
- Anything else — timeout, non-2xx, connection error — is treated as failed delivery and retried.
Retry timeline (exponential backoff)
Up to 6 attempts, capped at 120s between attempts. After the last failed attempt, fall back to GET /v1/order/{order_id} to fetch the result directly.
orderid more than once.8 Telegram notification
Whether the order finishes as Success, Partial, or Failed, the Telegram bot automatically sends you a notification with:
- Order ID
- Player ID & Player Name (Auto Top-Up only)
- Order status
- Package summary
- Voucher status per item
- Total amount & fee
- Wallet balance before / after
- Processing time
This is fully automatic — no setup needed on your end beyond having an API key tied to your Telegram account.
9 Errors & status codes
POST /v1/order only ever validates the request itself — it never returns the order's own success/failure (that comes later, via §6/§7). Error format:
{
"success": false,
"message": "Invalid wallet. Valid options: bd, bd_baki, usd, usd_baki"
}
| Status | Meaning |
|---|---|
| 400 | Missing/invalid field — bad item format, unknown uctype, qty out of range, bad wallet, invalid callback_url, malformed metadata, or invalid JSON body |
| 401 | Missing or invalid API key |
| 404 | (status-check only) order_id not found, or belongs to a different account |
| 429 | Rate limit exceeded |
| 500 | Internal server error — safe to retry |
10 Code examples
Same request, three languages. Switch tabs below.
import time
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.gameflexbd.online/v1"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
payload = {
"item": "80:1",
"wallet": "bd",
"player_id": "12345678", # remove this line for a Normal Voucher Order
"callback_url": "https://yourdomain.com/webhook",
"metadata": { "your_ref": "INV-1001" }
}
response = requests.post(f"{BASE_URL}/order", headers=headers, json=payload)
result = response.json()
print(result)
if result.get("success"):
order_id = result["order_id"]
while True:
status = requests.get(f"{BASE_URL}/order/{order_id}", headers=headers).json()
print(status["status"])
if status["status"] in ["success", "partial", "failed"]:
print(status)
break
time.sleep(3)
1. Place the order
curl -X POST https://api.gameflexbd.online/v1/order \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"item": "80:1",
"wallet": "bd",
"player_id": "12345678",
"callback_url": "https://yourdomain.com/webhook"
}'
2. Check status
curl -X GET https://api.gameflexbd.online/v1/order/ORD123456 \
-H "X-API-Key: YOUR_API_KEY"
3. Or a multi-package Normal Voucher Order (no player_id)
curl -X POST https://api.gameflexbd.online/v1/order \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"item": "80:2,160:1",
"wallet": "bd",
"callback_url": "https://yourdomain.com/webhook"
}'
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
public class GameFlexOrder {
static final String API_KEY = "YOUR_API_KEY";
static final String BASE_URL = "https://api.gameflexbd.online/v1";
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String body = """
{
"item": "80:1",
"wallet": "bd",
"player_id": "12345678",
"callback_url": "https://yourdomain.com/webhook",
"metadata": {"your_ref": "INV-1001"}
}""";
HttpRequest placeOrder = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/order"))
.header("X-API-Key", API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> res = client.send(placeOrder, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body()); // { "success": true, "order_id": "...", "status": "pending" }
// naive order_id extraction — use a real JSON library (Jackson / Gson) in production
String orderId = res.body().split("\"order_id\":\"")[1].split("\"")[0];
while (true) {
HttpRequest poll = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/order/" + orderId))
.header("X-API-Key", API_KEY)
.GET()
.build();
HttpResponse<String> status = client.send(poll, HttpResponse.BodyHandlers.ofString());
System.out.println(status.body());
if (status.body().contains("\"success\"") || status.body().contains("\"partial\"") || status.body().contains("\"failed\"")) {
break;
}
Thread.sleep(Duration.ofSeconds(3).toMillis());
}
}
}
11 After you place an order
Three ways to get the final result — use whichever fits your integration:
- Callback — set
callback_urland the result is POSTed to you automatically (see §7). - Status check — poll
GET /v1/order/{order_id}(see §6). - Telegram — the bot also sends you the full result automatically (see §8), whether or not you set a callback.