API · v2

PerfectPanel-compatible. Out of the box.

The SDK you already wrote for another panel works here without a single rewrite — same POST, same form-encoded body, same JSON. Seven canonical actions cover services, orders, refills, cancels and wallet balance — no rewrites, no surprises.

  • Sub-150 ms p99
  • HMAC-grade key auth
  • 100% PerfectPanel-compatible
Endpoint
POSThttps://smmhub.io/api/v2

All requests are POST with application/x-www-form-urlencoded payloads. Responses are JSON.

Getting started

Up and running in three requests

The whole API is a flat list of `action` values posted to one URL. Below you'll find authentication, conventions, and a 60-second smoke test.

1. Get an API key

Sign up, then head to Account → API in the dashboard. Generate a key, copy it, and never put it on the client side. Rotate any time — old keys die immediately.

2. Smoke test with cURL

Paste this in your terminal — replace YOUR_API_KEY with the one you just generated. If you see your wallet balance, you're done.

curl -X POST "https://smmhub.io/api/v2" \
  -d "key=YOUR_API_KEY" \
  -d "action=balance"

3. The conventions worth knowing

  • HTTP

    One verb: POST. One URL: /api/v2.

  • Body

    Form-encoded (application/x-www-form-urlencoded). No JSON bodies.

  • Auth

    Always include key as a body field — no headers needed.

  • Response

    Always JSON. Errors return a top-level error field.

  • Batching

    Where supported, comma-separate IDs (max 100). Always prefer batch.

  • Idempotency

    add is not idempotent — store the returned order ID before retry.

Services

List the live catalog with prices, limits, and refill flags.

POST/api/v2action=services

Service list

Returns the full live catalog with rate, min/max, and refill/cancel capabilities. Cache it on your side for at least 60 seconds — we update prices in real time.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be the literal string services.

Notes

  • Rates are per 1,000 units in your wallet currency.
  • The type field tells you which add variant to use: Default, Package, or Custom Comments.
curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=services"
[
{
"service": 1042,
"name": "Instagram Followers — Real & Active",
"type": "Default",
"category": "Instagram › Followers",
"rate": "0.85",
"min": "50",
"max": "100000",
"refill": true,
"cancel": true
},
{
"service": 2207,
"name": "TikTok Views — High Quality",
"type": "Default",
"category": "TikTok › Views",
"rate": "0.05",
"min": "100",
"max": "10000000",
"refill": false,
"cancel": true
}
]
Orders

Place orders, look up status, and cancel in flight.

POST/api/v2action=add

Add order

Place a new order. There are three variants depending on the service `type` you saw in the catalog. Pick the matching tab.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be add.

  • servicenumberrequired

    Service ID from the catalog.

  • linkstringrequired

    Public link the order will be delivered to.

  • quantitynumberrequired

    How many units to deliver. Must respect the service min/max.

  • runsnumberoptional

    Optional. Split delivery into N runs for drip-feed effect.

  • intervalnumberoptional

    Optional. Minutes between runs when runs is set.

Notes

  • Store the returned order ID — it's the only handle for status, refill, and cancel.
  • We deduct from your wallet immediately. If the order is later cancelled, the balance is refunded atomically.
curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=add" \
-d "service=1042" \
-d "link=https://instagram.com/your_handle" \
-d "quantity=1000" \
-d "runs=5" \
-d "interval=60"
{
"order": 1832047
}
POST/api/v2action=status

Order status

Look up a single order. Use the multi-status endpoint when polling.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be status.

  • ordernumberrequired

    Order ID returned by add.

Notes

  • Status values: Pending, In progress, Processing, Completed, Partial, Canceled.
  • When status is Partial, remains tells you what didn't deliver. We refund partials automatically.
curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=status" \
-d "order=1832047"
{
"charge": "0.85000",
"start_count": "12450",
"status": "In progress",
"remains": "240",
"currency": "USD"
}
POST/api/v2action=status

Multiple orders status

Batch up to 100 IDs in one call. Use this for polling — easier on us, easier on you.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be status.

  • orderslistrequired

    Up to 100 order IDs separated by commas.

curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=status" \
-d "orders=1832047,1832048,1832049"
{
"1832047": {
"charge": "0.85000",
"start_count": "12450",
"status": "Completed",
"remains": "0",
"currency": "USD"
},
"1832048": {
"error": "Incorrect order ID"
},
"1832049": {
"charge": "1.44219",
"start_count": "234",
"status": "In progress",
"remains": "10",
"currency": "USD"
}
}
POST/api/v2action=cancel

Cancel orders

Request cancellation for orders that have not yet been delivered. We refund the charged amount within seconds of acceptance.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be cancel.

  • orderslistrequired

    Up to 100 order IDs separated by commas.

Notes

  • Cancel is best-effort. Once an order has fully started, we honour the work in flight and refund only the un-started remainder.
curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=cancel" \
-d "orders=1832047,1832048"
[
{ "order": 1832047, "cancel": 1 },
{ "order": 1832048, "cancel": { "error": "Order already completed" } }
]
Refills

Trigger and track lifetime refills programmatically.

POST/api/v2action=refill

Create refill

Trigger a refill on an eligible order. Most services with `refill: true` get this for free for the first 365 days — but you can re-fire it any time.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be refill.

  • ordernumberrequired

    Order ID to refill.

curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=refill" \
-d "order=1832047"
{
"refill": "8821"
}
POST/api/v2action=refill

Create multiple refills

Batch refill up to 100 orders.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be refill.

  • orderslistrequired

    Up to 100 order IDs separated by commas.

curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=refill" \
-d "orders=1832047,1832048,1832049"
[
{ "order": 1832047, "refill": 8821 },
{ "order": 1832048, "refill": 8822 },
{ "order": 1832049, "refill": { "error": "Order not eligible for refill" } }
]
POST/api/v2action=refill_status

Refill status

Check whether a refill has been processed.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be refill_status.

  • refillnumberrequired

    Refill ID returned by refill.

Notes

  • Refill status values: Pending, In progress, Completed, Rejected.
curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=refill_status" \
-d "refill=8821"
{
"status": "Completed"
}
POST/api/v2action=refill_status

Multiple refill status

Batch refill status for up to 100 IDs.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be refill_status.

  • refillslistrequired

    Up to 100 refill IDs separated by commas.

curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=refill_status" \
-d "refills=8821,8822,8823"
[
{ "refill": 8821, "status": "Completed" },
{ "refill": 8822, "status": "In progress" },
{ "refill": 8823, "status": { "error": "Refill not found" } }
]
Account

Inspect your wallet balance and currency.

POST/api/v2action=balance

Wallet balance

Read your current wallet balance and currency.

Parameters

  • keystringrequiredfixed

    Your private API key from Account → API.

  • actionstringrequiredfixed

    Must be balance.

curl -X POST "https://smmhub.io/api/v2" \
-d "key=YOUR_API_KEY" \
-d "action=balance"
{
"balance": "247.30418",
"currency": "USD"
}
Errors & limits

When something doesn't go right

Common errors

All errors come back as JSON with an error field. Match on the message, not the HTTP status.

  • "Invalid API key"

    Wrong or rotated key. Generate a fresh one in Account → API.

  • "Insufficient balance"

    Wallet would go below zero. Top up before retrying.

  • "Incorrect order ID"

    The ID doesn't exist on your account or has been archived.

  • "Service is not active"

    The catalog ID was paused or removed. Refresh the catalog.

  • "Quantity is too low / too high"

    The requested amount is outside the service min/max.

  • "Refill not available"

    Either the service does not support refill, or the lifetime window has expired.

  • "Rate limit exceeded"

    Slow down — fair-use is roughly 60 requests/minute per key. Use batch endpoints.

Fair-use & rate limits

We don't publish hard limits — fair-use applies to every key. As a rule of thumb:

  • Polling: batch up to 100 IDs and poll every 30–60 seconds — never in a tight loop.
  • Catalog: cache the services response for at least 60 seconds. We update prices in real time but daily change is small.
  • Bursts: short spikes are fine. If you sustain >60 req/s on a single key for more than a minute, you'll start getting Rate limit exceeded.
  • Need higher limits? Reach out on Telegram — we lift them per account, not per request.