Rexo Prime Reseller API
Put our live catalogue of AI tools and digital subscriptions inside your own bot, website or app. You make the sale; we handle stock, charging and delivery.
From zero to first delivery
Six steps. The first three take a minute in Telegram; the rest is your code.
Get your key
In @rexoprimeshop_bot tap Bot API → Get API Key, or sign in on the website and open Account → API. The key starts with tgb_.
Lock the key away
Save it as REXOPRIME_API_KEY in your server's secrets. Never put it in a browser or mobile app, a public repository or a URL.
Fund your wallet
Top up in the bot or on the website (Binance Pay, USDT, bKash or card), from 0.10 USDT. Every API order is paid from this balance.
Load live products
GET /products gives every product you can buy by API: its id, your price, stock, quantity limits and what the buyer has to give.
Create the order
POST /purchase with the product, the quantity and one unique client_order_id per customer order, plus the buyer's details when the product asks.
Deliver the result
Send every line of delivered_items to your buyer. Not delivered yet? Ask GET /orders/{order_id} until final is true, or use the webhook.
Connect your codebase
The whole flow: products, wallet, a safe purchase, and waiting for a delivery that is not instant. Keep the key server-side.
const API = "https://rexoprime.com/api/telegram-buyer";
const KEY = process.env.REXOPRIME_API_KEY!; // server-side only
async function rexo(path: string, init: RequestInit = {}) {
const res = await fetch(API + path, {
...init,
headers: { "X-API-Key": KEY, "Content-Type": "application/json", ...init.headers },
});
const data = await res.json();
if (!res.ok || data.success === false) throw new Error(data.status ?? data.message ?? `HTTP ${res.status}`);
return data;
}
// 1. live products (your price in USDT) and your wallet
const { products } = await rexo("/products");
const { balance } = await rexo("/balance");
// 2. buy -- send the SAME client_order_id again if you retry this customer order
let order = await rexo("/purchase", {
method: "POST",
body: JSON.stringify({
product_id: products[0].id,
quantity: 1,
client_order_id: `tg_${chatId}_${paymentId}`,
// customer_payload: { custom_details: "buyer@gmail.com" }, // when requiresCustomerDetails
}),
});
// 3. not delivered yet? ask again until it is
for (let i = 0; i < 24 && order.delivery_status !== "delivered" && !order.final; i++) {
await new Promise((r) => setTimeout(r, (order.poll_after_seconds || 5) * 1000));
order = await rexo(`/orders/${order.order_id}`);
}
if (order.delivery_status === "delivered") {
for (const line of order.delivered_items) await deliverToCustomer(line);
} else {
// "manual": delivered by hand later -- check again from a background job.
// "failed": order.refunded tells you the money is back on your wallet.
}
import os, time, requests
API = "https://rexoprime.com/api/telegram-buyer"
HEADERS = {"X-API-Key": os.environ["REXOPRIME_API_KEY"]} # server-side only
def rexo(method, path, **kw):
r = requests.request(method, API + path, headers=HEADERS, timeout=60, **kw)
data = r.json()
if not r.ok or data.get("success") is False:
raise RuntimeError(data.get("status") or data.get("message") or "HTTP %s" % r.status_code)
return data
products = rexo("GET", "/products")["products"] # your price in USDT
balance = rexo("GET", "/balance")["balance"]
# send the SAME client_order_id again if you retry this customer order
order = rexo("POST", "/purchase", json={
"product_id": products[0]["id"],
"quantity": 1,
"client_order_id": "order-1001",
# "customer_payload": {"custom_details": "buyer@gmail.com"}, # when requiresCustomerDetails
})
for _ in range(24): # not delivered yet? ask again
if order.get("delivery_status") == "delivered" or order.get("final"):
break
time.sleep(order.get("poll_after_seconds") or 5)
order = rexo("GET", "/orders/%s" % order["order_id"])
if order.get("delivery_status") == "delivered":
for line in order["delivered_items"]:
deliver_to_customer(line)
KEY="tgb_your_key_here"
B="https://rexoprime.com/api/telegram-buyer"
# products with your price, and your wallet
curl -s -H "X-API-Key: $KEY" "$B/products"
curl -s -H "X-API-Key: $KEY" "$B/balance"
# buy (send the same client_order_id again if you retry)
curl -s -X POST "$B/purchase" -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"product_id": 13, "quantity": 1, "client_order_id": "order-1001"}'
# an order that was not delivered at once: by number or by order code
curl -s -H "X-API-Key: $KEY" "$B/orders/1234"
curl -s -H "X-API-Key: $KEY" "$B/orders/REXO7K3M9QP2"
!Most products come back delivered in the purchase answer itself. A few are bought from a supplier first and take a little longer (processing), and some are finished by hand (manual). The purchase call waits up to 12 seconds for you; ?wait=0 answers at once and ?wait=55 waits longest.
Four calls. One predictable flow.
All paths hang off https://rexoprime.com/api/telegram-buyer. Every answer is JSON with "success": true or false.
| Call | What it does |
|---|---|
GET/products | Every product you can buy by API, with your price in USDT, stock and limits. |
GET/balance | Your wallet (balance) and your key's limits (api_profile). |
POST/purchase | Buy. Paid from your wallet; the goods come back in delivered_items. |
GET/orders/{order_id} | One order's state and goods. Also by order code: /orders/REXO7K3M9QP2. |
POST/webhook | Optional: get a signed callback when an order is delivered. |
Safe retries
Send one client_order_id per customer order and the same one on every retry. A repeat answers "duplicate": true with the first order: nothing is bought or charged twice. (idempotency_key and an Idempotency-Key header work the same.)
USDT pricing
price in /products is exactly what you pay, your reseller discount included. Every order uses your prepaid wallet; add your own margin when you sell.
120 reads / 40 orders a minute
The limit applies per key. After a 429, wait before you try again, and keep the same client_order_id.
What you send with an order
| Field | When | What it is |
|---|---|---|
product_id | always | The id from /products. |
quantity | always | Within the product's min_purchase_quantity / max_purchase_quantity (0 = no limit). |
client_order_id | always | Your id for this customer order, the same on every retry. |
customer_payload.custom_details | requiresCustomerDetails | The buyer's answer to customer_details_prompt (their email, a profile link…), exactly as typed. It is checked before anything is charged. |
username | requiresTelegramUsername | Telegram Premium and Stars: the recipient's @username. For Stars, quantity is the number of Stars (from 50). |
What an order tells you
delivery_status | final | Meaning |
|---|---|---|
delivered | true | Done. The goods are in delivered_items, one line per unit. |
processing | false | Paid; being bought or checked. Ask again after poll_after_seconds. |
manual | false | Paid; our team delivers it by hand. Check again every few minutes. |
failed | true | It will not be delivered. refunded: true and refund_amount say the money is back on your wallet. |
Delivery and refunds
Only products we deliver automatically are sold by API. If a paid order cannot be delivered, we deliver it by hand or refund it in full to your wallet, and the order says so. A refused call (no stock, low balance, missing details) is never charged.
Webhook
POST /webhook {"webhook_url": "https://…"} returns a signing secret once. Each callback carries X-Signature: sha256=HMAC_SHA256(secret, raw_body); check it, and expect a delivery to arrive more than once.
Everything else (resale names and prices, all fields, examples) is in the full reference; the machine-readable spec is in Swagger (openapi.json).
Build it with your AI coding tool
Open your project, choose your assistant and paste the prepared prompt. It carries the API and the safety rules that matter: the key stays on the server, retries never buy twice, every result is handled.
Claude
Ask Claude to read your existing bot or app before changing it.
Show the prompt
First read my existing bot / app and tell me where checkout and delivery happen. Then make the change in small steps and show me the diff before you finish.
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Gemini
Give Gemini this prompt with your server-side project open.
Show the prompt
My server-side project is open. Find the checkout and delivery code first, then add the integration.
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Codex
Use it from the repository root so Codex can test the full flow.
Show the prompt
Work from the repository root. Add the integration, write tests that mock the answers below (delivered at once; processing, then delivered; 409; 429; a repeat) and run them.
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Lovable
Best for adding the reseller flow to a full-stack web app.
Show the prompt
Add this reseller flow to my full-stack web app. Every API call must run on the server (a backend route or an Edge Function), never in the React client.
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Replit
Save the key in Secrets before asking the Agent to connect it.
Show the prompt
The key is saved in Replit Secrets as REXOPRIME_API_KEY. Connect it in the server code of this Repl.
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Other AI tools
Works with any coding assistant that can edit your server.
Show the prompt
Connect this project to the Rexo Prime reseller API, so a customer who pays us gets the product delivered automatically.
API
- Base URL: https://rexoprime.com/api/telegram-buyer
- Auth header: X-API-Key: <key>. The key is in the environment variable REXOPRIME_API_KEY. Use it only on the server: never in a browser or mobile app, never in a URL, never in logs.
- GET /products -> {"products": [...]}. Per product: id, name, price (USDT, what we pay), stock, infinite_stock, min_purchase_quantity and max_purchase_quantity (0 = no limit), requiresCustomerDetails, customer_details_prompt, requiresTelegramUsername.
- GET /balance -> {"balance": number}, in USDT.
- POST /purchase with JSON {"product_id": number, "quantity": number, "client_order_id": string, "customer_payload": {"custom_details": string}} -> {"order_id", "orderCode", "delivery_status": "delivered" or "processing", "delivered_items": [one string per unit], "poll_after_seconds"}.
- GET /orders/{order_id} -> {"delivery_status": "processing" | "manual" | "delivered" | "failed", "final", "delivered_items", "refunded", "refund_amount", "message", "poll_after_seconds"}.
- Errors are JSON {"success": false, "message": string, "status": string}: 400 bad input (status custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required), 401 invalid key, 403 not allowed (manual_delivery_not_available), 404 product not found, 409 insufficient_balance / out_of_stock / product_not_available / limit_exceeded / daily_spend_limit_reached, 429 too many requests, 503 API switched off.
Rules
1. Give every customer order one client_order_id, save it with the order, and send the same id on every retry, after a timeout too. A repeat answers {"duplicate": true, "order_id": N} and is never charged twice.
2. When requiresCustomerDetails is true, ask the customer customer_details_prompt and send the answer exactly as typed in customer_payload.custom_details. For Telegram Premium / Stars send the recipient's @username as "username".
3. Deliver every line of delivered_items. While delivery_status is "processing", call GET /orders/{order_id} after poll_after_seconds. "manual" means it is delivered by hand later: check again every few minutes from a background job until final is true. A "failed" order is never delivered later; refunded: true means the money is back on our wallet.
4. On 409 insufficient_balance show the customer "temporarily unavailable" and alert the admin to top up; never retry in a loop. On 429 wait, then retry with the same client_order_id.
5. Read products and prices from /products and refresh them regularly instead of hard-coding ids or prices; add our own margin on top of price.
6. Finish with a low-value test order that runs the whole flow, and show me how to run it.Launch checklist
- The API key is stored in your server's secrets
- Products and balance load successfully
- Every checkout has its own stable
client_order_id - Delivered, processing, manual and failed results are handled
400,409,429and503answers have clear fallbacks- A low-value test order reads back through your customer screens (some products cost a few cents)
When a request stops
The HTTP code says what kind of problem it is; status in the answer names it. Every refusal below charges nothing.
custom_details_required, custom_details_invalid_email, custom_details_invalid_link, telegram_username_required, or a quantity outside the product's limits. Ask the buyer again and resend.
The key is wrong or was replaced by a new one, or the base URL is not https://rexoprime.com: our keys work only here.
manual_delivery_not_available (that product is delivered by hand and not sold by API), a product your key may not buy, or a paused key.
The product is off sale or the id is wrong. Reload /products.
insufficient_balance: top up your wallet. out_of_stock / product_not_available: try later or another product. limit_exceeded / daily_spend_limit_reached: your key's limits.
More than 120 reads or 40 orders a minute on one key. Wait, then retry with the same client_order_id.
Paid and on its way through our team. Keep checking GET /orders/{order_id} every few minutes, or wait for the webhook.
Our API is paused for a moment. Try again later; nothing was charged.
Ready for your first API order?
Get your key in Telegram, fund the wallet, and use the examples above to connect your store.