GameRovel API
Base URL https://api.gamerovel.com/v1 · JSON in, JSON out · amounts are strings in USDT.
Authentication
Create a key in the portal (API keys). Send it on every request:
Authorization: Bearer gr_live_xxxxxxxxxxxxxxxxxxxxxxxx
Keys are shown once. Keep them on your server — never in a browser or app. Limit: 120 requests per minute per key (60 new orders per minute).
Idempotency
Send Idempotency-Key: <your order id> with every new order. If your request times out, send it again with the same key: you get the first order back (HTTP 200) — it is never delivered twice and never charged twice.
GET /v1/products
Your price list right now (prices follow the supplier cost).
{ "data": [ { "code": "stars_500", "name": "Telegram Stars 500", "price": "7.48", "currency": "USDT", "available": true }, … ] }GET /v1/balance
{ "balance": "412.30", "currency": "USDT", "daily_limit": "600.00", "used_today": "141.20" }POST /v1/orders
The price is taken from your balance when the order is created. If delivery fails, it goes back automatically and you receive order.refunded.
| Field | Type | Description |
|---|---|---|
| product | string | stars_50 … stars_10000 · premium_3m · premium_6m · premium_12m (or "stars" + quantity) |
| username | string | Telegram @username that receives it |
| reference | string? | Your own order number (returned in webhooks) |
Response · 201 (200 when the Idempotency-Key was already used)
{
"id": "ord_8F3A21C9K2PQ",
"status": "processing",
"product": "stars_500",
"quantity": 500,
"username": "telegram_user",
"reference": "shop-20931",
"price": "7.48",
"currency": "USDT",
"balance_left": "412.30"
}Statuses
refunded = not delivered (e.g. username not found); the price is back on your balance and reason says why.
GET /v1/orders/{id}
One order, same fields as above.
GET /v1/orders
Newest first. Query: status (processing · delivered · refunded), limit (1–200), before (an order id, for the next page).
Errors
| HTTP | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing or wrong API key |
| 402 | insufficient_balance | Top up first — nothing was charged |
| 403 | account_paused | Your account is paused |
| 422 | invalid_product · invalid_username | Check the request |
| 429 | daily_limit · rate_limited | Daily spend limit reached / too many requests |
| 503 | temporarily_unavailable · product_unavailable | Orders paused — nothing was charged, try later |
Every error is JSON: { "error": "insufficient_balance", "message": "…" }
Webhooks
Set your https address in the portal. We POST JSON for order.delivered, order.refunded, balance.added and ping. Answer with any 2xx; otherwise we retry with growing delays for about a day.
X-GameRovel-Event: order.delivered
X-GameRovel-Signature: t=1731600000,v1=<hex>
{ "id": "evt_…", "event": "order.delivered", "created_at": "…", "data": { …order… } }Check the signature: v1 = HMAC_SHA256(your webhook secret, t + "." + raw body), hex. Reject it if it does not match or if t is older than 5 minutes.
// Node.js
const [t, v1] = header.split(',').map(s => s.split('=')[1]);
const ok = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex') === v1;Crypto top-ups
In the portal choose a coin and an amount. You get an address and an exact amount (the last digits identify your payment). Send exactly that amount from any wallet or exchange — our system reads the blockchain and adds it after the confirmations below. Valid for 60 minutes; a payment up to 24 h late is still matched.
| Coin | Confirmations | Credited |
|---|---|---|
| USDT · TRC20 (TRON) | confirmed block (~1 min) | the USDT amount received |
| Bitcoin | 2 | the USDT amount shown, at the rate fixed when you opened the top-up |
| Litecoin | 4 | the USDT amount shown, at the rate fixed when you opened the top-up |
Sent a different amount by mistake? It is not lost — contact us with the transaction id and we add it by hand.