Reseller API (API v2)
The standard SMM API v2 your customers connect their panels to; every action, parameter, response and error message.
Overview
Every panel ships with the standard API v2 used across SMM panels. Your customers can add you as a "provider" in their own panel and resell your services. Customers create keys on Customer panel → API & Reseller (up to 5 active keys each).
| Endpoint | POST https://yourpanel.com/api/v2 (no language prefix) |
| Body | application/x-www-form-urlencoded, multipart/form-data or application/json |
| Key | key field in the body, or the X-Api-Key header |
| Key format | tb_ + 48 hex characters |
| Currency | Amounts are always USD |
GET requests return 405.
Rate limits
Per 60-second window: 120 requests per IP and 180 per key. Exceeding them returns HTTP 429, {"error":"Too many requests"} and a Retry-After header. All other errors are HTTP 200 with {"error":"..."}.
services
curl -X POST https://yourpanel.com/api/v2 -d key=tb_xxx -d action=services
[
{"service":1,"name":"Instagram Followers","type":"Default","category":"Instagram / Followers",
"rate":"0.5","min":"10","max":"10000","refill":true,"cancel":false,"dripfeed":false}
]
rate: the customer's own price (discounts included) per 1000. For package types it is the package price.- Provider brands are stripped from names and categories. The list is cached for 60 seconds.
balance
{"balance":"12.5","currency":"USD"}
add
| Parameter | Description |
|---|---|
service | Service ID |
link | Target link |
quantity | Quantity (not needed for package types) |
runs, interval | Drip-feed: runs (2–100) and interval (1–1440 minutes). Total = quantity × runs. Send both together. |
| Type-specific | See the table below |
Success: {"order":12345}
Errors: Incorrect service ID, Incorrect quantity, Incorrect runs (2-100), Incorrect interval (1-1440 minutes), Service is temporarily unavailable, Quantity must be between {min} and {max}, Drip-feed is not available for this service, Incorrect link, Not enough funds on balance, Missing {param}.
Service types
| Type | Quantity | Extra parameters |
|---|---|---|
| Default | quantity | — (drip-feed allowed) |
| Package | always 1 | — |
| SEO | quantity | keywords |
| Custom Comments | number of comments lines | comments |
| Custom Comments Package | 1 | comments |
| Mentions | quantity | usernames |
| Mentions with Hashtags | quantity | usernames, hashtags |
| Mentions Custom List | number of usernames lines | usernames |
| Mentions Hashtag | quantity | hashtag |
| Mentions User Followers | quantity | username |
| Mentions Media Likers | quantity | media |
| Comment Likes | quantity | username |
| Comment Replies | number of comments lines | username, comments |
| Poll | quantity | answer_number |
| Invites from Groups | quantity | groups |
| Web Traffic | quantity | optional country, device, type_of_traffic, google_keyword, referring_url |
| Subscriptions | posts × max | username, min, max, posts; optional old_posts, delay, expiry |
List parameters (comments, usernames…) are sent one per line (\n).
status
Single order (order=ID):
{"charge":"0.27819","start_count":"3572","status":"Partial","remains":"157","currency":"USD"}
Mass status (orders=1,2,3, max 100):
{"1":{"charge":"0.5","start_count":"0","status":"Completed","remains":"0","currency":"USD"},
"2":{"error":"Incorrect order ID"}}
Statuses: Pending, In progress, Completed, Partial, Canceled. charge is net of refunds. A status call triggers a background provider sync at most once a minute per user.
refill and refill_status
| Request | Response |
|---|---|
action=refill&order=ID | {"refill":"77"} |
action=refill&orders=1,2 | [{"order":1,"refill":77},{"order":2,"refill":{"error":"..."}}] |
action=refill_status&refill=77 | {"status":"Completed"} |
action=refill_status&refills=77,78 | [{"refill":77,"status":"Pending"},{"refill":78,"status":{"error":"Refill not found"}}] |
Refill statuses: Pending, In progress, Completed, Rejected, Error. Possible errors: Refill is not available for this service, Refill is available only for completed orders, A refill is already in progress, Refill can be requested once every 24 hours, Refill period ({n} days) has ended.
cancel
action=cancel&orders=1,2 (max 100):
[{"order":1,"cancel":1},{"order":2,"cancel":{"error":"Cancel is not available for this service"}}]
Example clients
<?php
function api(array $data) {
$ch = curl_init('https://yourpanel.com/api/v2');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($data + ['key' => 'tb_xxx']), CURLOPT_RETURNTRANSFER => true]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return $res;
}
$order = api(['action' => 'add', 'service' => 1, 'link' => 'https://instagram.com/account', 'quantity' => 1000]);
$status = api(['action' => 'status', 'order' => $order['order']]);
const api = (body) =>
fetch("https://yourpanel.com/api/v2", {
method: "POST",
headers: { "Content-Type": "application/json", "X-Api-Key": process.env.PANEL_KEY },
body: JSON.stringify(body),
}).then((r) => r.json());
const { order } = await api({ action: "add", service: 1, link: "https://t.me/channel", quantity: 500 });
Instead of polling statuses you can use webhooks.