Toolverio Reseller API Get API access

Toolverio Reseller API

Sell our digital products from your own Telegram bot or website. You pay from a prepaid USDT API balance and get the items back in the same request.

Base URL
https://api.toolverio.com
All requests and responses are JSON (UTF-8). All money values are numbers in USDT.

Quickstart

  1. Open @ToolverioBot and tap 🔑 Reseller API, then Request Access.
  2. When approved, tap 🔑 Create API Key and save the key (it is shown once).
  3. Add USDT to your bot wallet, then tap 💵 Top Up API Balance.
  4. List products and place your first order:
curl https://api.toolverio.com/v1/products -H "Authorization: Bearer tvr_YOUR_KEY"

curl -X POST https://api.toolverio.com/v1/orders \
  -H "Authorization: Bearer tvr_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-order-1001" \
  -d '{"product_id": "p12", "quantity": 1}'

Getting access

Everything is managed in the Telegram bot, screen 🔑 Reseller API: Account, Status, API Balance, Discount, API Orders, API Key and Low-Balance Alert, with the buttons Top Up API Balance, Transfer to Wallet, My Prices, API Orders, API Docs, Regenerate Key, Revoke Key and Low Balance Alert. New requests are approved by our team.

Balance & top-ups

Your API balance is separate from your bot wallet. Add money to the wallet (Binance Pay or USDT BEP20), then move any amount to the API balance with Top Up API Balance. You can move any amount back with Transfer to Wallet at any time. There is no minimum or maximum.

If a product can not be delivered (for example it sold out), the full amount goes back to your API balance automatically.

Authentication

Send your key in the Authorization header on every request:

Authorization: Bearer tvr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys start with tvr_. Regenerate or revoke them in the bot. X-API-Key: tvr_... also works.

Never share your API key and never put it in a public website or app. Anyone with the key can spend your API balance.

Idempotency (never pay twice)

Every POST /v1/orders needs an Idempotency-Key header: any unique string up to 64 characters, for example your own order id. If your request times out, send it again with the same key: you get the same order back and you are never charged twice. Using the same key with a different body returns 409 idempotency_conflict.

Order statuses

StatusMeaning
processingPaid, being prepared (usually a few seconds). Poll GET /v1/orders/{code}.
deliveredDone. Your items are in items.
pendingManual delivery by our team. Items appear when ready.
refundedCould not be delivered. The total went back to your API balance.

Delivery types

Each product has delivery: instant (items come back in the order) or manual (our team delivers, status pending until then).

Required fields

Some products are activated on the buyer's own account. They list what we need in required_fields (for example ["Email"]). Send them in fields:

{"product_id": "p31", "quantity": 1, "fields": {"Email": "buyer@mail.com"}}

Errors

{"ok": false, "error": {"code": "insufficient_balance", "message": "API balance is too low."}}
HTTPcodeMeaning
401invalid_keyKey missing or wrong
403account_pendingAccess not approved yet
403account_disabledAccess disabled, contact support
404product_not_foundNo product with that id
404order_not_foundNo order found
400invalid_requestBad JSON, missing parameter or missing Idempotency-Key
400qty_out_of_rangeQuantity below min_qty or above max_qty
400missing_fieldsrequired_fields not sent
402insufficient_balanceTop up your API balance
409out_of_stockNot enough stock right now
409idempotency_conflictKey reused with a different body
429rate_limitedToo many requests, see Retry-After
500internal_errorRetry with the same Idempotency-Key

Rate limits

60 requests per minute per key. Every response has X-RateLimit-Limit and X-RateLimit-Remaining; a 429 has Retry-After (seconds). 5 wrong keys in a minute from one IP block that IP for 15 minutes.

GET /v1/balance

GET/v1/balance
curl https://api.toolverio.com/v1/balance -H "Authorization: Bearer tvr_YOUR_KEY"

{"ok": true, "balance": 12.5, "currency": "USDT"}

GET /v1/products

GET/v1/products

All products with your price (your discount is already applied).

{"ok": true, "products": [
  {"id": "p12", "name": "Gemini AI Pro 18 Month", "description": "...", "category": "AI Tools",
   "emoji": "🤖", "unit_price": 0.42, "currency": "USDT", "stock": 120,
   "min_qty": 1, "max_qty": 100, "delivery": "instant", "required_fields": [],
   "bulk_prices": [{"min_qty": 10, "unit_price": 0.40}], "in_stock": true}
]}
FieldTypeDescription
idstringUse it as product_id
unit_pricenumberYour price per unit in USDT
stocknumber or nullnull = unlimited
min_qty / max_qtynumberAllowed quantity per order
deliverystringinstant or manual
required_fieldsarraySend these in fields
bulk_pricesarrayCheaper unit price from min_qty units

GET /v1/products/{id}

GET/v1/products/p12
{"ok": true, "product": { ...same fields... }}

POST /v1/orders

POST/v1/orders
BodyTypeRequiredDescription
product_idstringyesFrom /v1/products
quantityintegeryesBetween min_qty and max_qty
fieldsobjectif listedValues for required_fields

Header Idempotency-Key is required.

curl -X POST https://api.toolverio.com/v1/orders \
  -H "Authorization: Bearer tvr_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-order-1001" \
  -d '{"product_id": "p12", "quantity": 2}'
import requests

r = requests.post("https://api.toolverio.com/v1/orders",
    headers={"Authorization": "Bearer tvr_YOUR_KEY", "Idempotency-Key": "my-order-1001"},
    json={"product_id": "p12", "quantity": 2}, timeout=30)
data = r.json()
if data["ok"]:
    print(data["order"]["status"], data["order"]["items"])
else:
    print(data["error"]["code"], data["error"]["message"])
const r = await fetch("https://api.toolverio.com/v1/orders", {
  method: "POST",
  headers: {"Authorization": "Bearer tvr_YOUR_KEY", "Content-Type": "application/json",
            "Idempotency-Key": "my-order-1001"},
  body: JSON.stringify({product_id: "p12", quantity: 2})
});
const data = await r.json();
console.log(data.ok ? data.order.items : data.error);
$ch = curl_init("https://api.toolverio.com/v1/orders");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer tvr_YOUR_KEY", "Content-Type: application/json",
                         "Idempotency-Key: my-order-1001"],
  CURLOPT_POSTFIELDS => json_encode(["product_id" => "p12", "quantity" => 2])]);
$data = json_decode(curl_exec($ch), true);

Response 201:

{"ok": true, "order": {
  "code": "TVR-8F3K2M7Q", "status": "delivered", "product_id": "p12",
  "product_name": "Gemini AI Pro 18 Month", "quantity": 2, "unit_price": 0.42, "total": 0.84,
  "currency": "USDT", "items": ["https://one.google.com/...", "https://one.google.com/..."],
  "note": "How to use: open the link and confirm.",
  "created_at": "2026-10-15T10:21:04Z", "delivered_at": "2026-10-15T10:21:05Z"},
 "balance_after": 11.66}

GET /v1/orders

GET/v1/orders?limit=50&cursor=TVR-...
{"ok": true, "orders": [ ...newest first... ], "next_cursor": "TVR-..." }

GET /v1/orders/{code}

GET/v1/orders/TVR-8F3K2M7Q
{"ok": true, "order": { ...order... }}

GET /v1/orders/by-idempotency/{key}

GET/v1/orders/by-idempotency/my-order-1001

Find an order by your own Idempotency-Key (404 if none). Useful after a timeout.

Guide: retry safely

Network errors happen. Always reuse the same Idempotency-Key for the same customer order:

for attempt in range(3):
    try:
        r = requests.post(URL + "/v1/orders", headers={**H, "Idempotency-Key": order_id},
                          json=body, timeout=30)
        break
    except requests.RequestException:
        time.sleep(2)      # same key = never charged twice

Guide: processing orders

Most orders come back delivered. If you get processing, check every 3 seconds for up to 2 minutes:

while order["status"] == "processing":
    time.sleep(3)
    order = requests.get(f"{URL}/v1/orders/{order['code']}", headers=H).json()["order"]

Guide: Telegram resale bot

import requests, uuid
from telegram.ext import Application, CommandHandler

URL, KEY = "https://api.toolverio.com", "tvr_YOUR_KEY"
H = {"Authorization": f"Bearer {KEY}"}

async def products(update, context):
    items = requests.get(URL + "/v1/products", headers=H, timeout=20).json()["products"]
    await update.message.reply_text("\n".join(f"{p['id']} - {p['name']} - ${p['unit_price']}"
                                              for p in items if p["in_stock"]))

async def buy(update, context):            # /buy p12 1   (charge your own customer first!)
    pid, qty = context.args[0], int(context.args[1])
    r = requests.post(URL + "/v1/orders", timeout=30,
                      headers={**H, "Idempotency-Key": str(uuid.uuid4())},
                      json={"product_id": pid, "quantity": qty}).json()
    if not r["ok"]:
        return await update.message.reply_text("Error: " + r["error"]["message"])
    await update.message.reply_text("\n".join(r["order"]["items"]) or "Your order is being prepared.")

app = Application.builder().token("YOUR_BOT_TOKEN").build()
app.add_handler(CommandHandler("products", products))
app.add_handler(CommandHandler("buy", buy))
app.run_polling()
Need help? Message us in @ToolverioBot (🎧 Support).