API v2 · Docs

SMM Panel API

Connect your panel, bot or script to 9SMM.COM. List services, place orders, track delivery, request refills and cancellations, and read your balance through one endpoint in the standard SMM panel format.

Overview

Endpoint

https://9smm.com/api/v2

Method

POST, application/x-www-form-urlencoded or JSON

Authentication

key parameter in the request body

Response

JSON. Errors: HTTP 200 with {"error": "..."}

Rate limit

1,200 requests per minute per key

Currency

USD for rates, charges and balance

Every request goes to the same URL with an action parameter that says what to do. Parameter names, response fields and status strings follow the v2 format used across SMM panels, so an existing reseller script normally works after you change the API URL and key.

Quick start

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=balance

Get an API key

  1. Create an account and add funds to your balance.
  2. Open Profile and click Generate API key in the API access card.
  3. Copy the key straight away. It starts with smm_ and is shown in full only once.

Each account has one active key. Regenerate key issues a new one and the old key stops working immediately, which is what to do if a key leaks. Orders placed through the API appear on your Orders page like any other order.

Code samples: PHP, Node.js, Python

Complete scripts that check your balance, count services, place an order and read its status. They use only each language's standard library. Set SMM_API_KEY in your environment (or paste the key into the file), and change the service ID and link before running, because the add step places a real order.

smm_api.php

<?php
// SMM panel API v2 client — PHP 7.4+ with the cURL extension, no dependencies.
const API_URL = 'https://9smm.com/api/v2';

$apiKey = getenv('SMM_API_KEY') ?: 'YOUR_API_KEY';

function smm_api(string $apiKey, array $params)
{
    $ch = curl_init(API_URL);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query(['key' => $apiKey] + $params),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $body = curl_exec($ch);
    if ($body === false) {
        $err = curl_error($ch);
        curl_close($ch);
        throw new RuntimeException('Network error: ' . $err);
    }
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $data = json_decode($body, true);
    if (!is_array($data)) {
        throw new RuntimeException("Unexpected response (HTTP $httpCode)");
    }
    // Errors arrive as HTTP 200 with {"error": "..."}; only the rate limit uses HTTP 429.
    if (isset($data['error'])) {
        throw new RuntimeException($data['error']);
    }
    return $data;
}

try {
    $balance = smm_api($apiKey, ['action' => 'balance']);
    echo "Balance: {$balance['balance']} {$balance['currency']}\n";

    $services = smm_api($apiKey, ['action' => 'services']);
    echo 'Services available: ' . count($services) . "\n";

    // Replace the service ID and link with your own: this places a real order
    // and charges your balance.
    $order = smm_api($apiKey, [
        'action'   => 'add',
        'service'  => 1,
        'link'     => 'https://www.instagram.com/your_profile/',
        'quantity' => 1000,
    ]);
    echo "Order placed: {$order['order']}\n";

    $status = smm_api($apiKey, ['action' => 'status', 'order' => $order['order']]);
    echo "Status: {$status['status']}, remains: {$status['remains']}, charge: {$status['charge']}\n";
} catch (RuntimeException $e) {
    echo 'API error: ' . $e->getMessage() . "\n";
    exit(1);
}

Run: SMM_API_KEY=smm_... php smm_api.php

Actions

services

List every active service with its current rate and limits.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesservices

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=services

Response

[
  {
    "service": 1,
    "name": "Instagram Followers",
    "type": "Default",
    "category": "Instagram — Followers",
    "rate": "0.90",
    "min": 10,
    "max": 100000,
    "refill": true,
    "cancel": true,
    "dripfeed": true
  }
]
  • rate is the price in USD per 1,000 units. The order charge is rate × quantity ÷ 1,000.
  • category combines platform and category ("Instagram — Followers") so identical category names on different platforms stay distinguishable.
  • type is one of Default, Custom Comments, Subscriptions or Drip-feed.
  • refill, cancel and dripfeed tell you which follow-up actions the service accepts.

add

Place a new order. The charge is taken from your balance immediately.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesadd
serviceYesService ID from the services list.
linkYesLink to the profile, post or video.
quantityYesAmount to deliver, within the service's min and max. Not needed for Custom Comments.
commentsNoCustom Comments services only: one comment per line (separated by \n). Quantity is the number of lines; each comment must be under 500 characters.
runsNoDrip-feed: split the order into 2–100 runs. Quantity is the total across all runs.
intervalNoDrip-feed: minutes between runs, 0–1440.

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=add \
  -d service=1 \
  --data-urlencode "link=https://www.instagram.com/your_profile/" \
  -d quantity=1000

Response

{ "order": 23501 }

Drip-feed: 5,000 in 5 runs, one hour apart

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=add \
  -d service=1 \
  --data-urlencode "link=https://www.instagram.com/your_profile/" \
  -d quantity=5000 \
  -d runs=5 \
  -d interval=60

Response

{ "order": 23502 }
  • The returned order ID is the same number you see on the Orders page, and it is what status, refill and cancel expect.
  • Drip-feed only works on services with dripfeed: true, and each run (quantity ÷ runs) must itself fall within the service's min and max.
  • You can't have two active orders for the same link on the same service. The second one is rejected with Incorrect link until the first finishes.

status

Check one order, or up to 100 orders in a single request.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesstatus
orderNoOne order ID.
ordersNoComma-separated order IDs, max 100. Use instead of order.

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=status \
  -d order=23501

Response

{
  "charge": "0.90",
  "start_count": 3572,
  "status": "In progress",
  "remains": 157,
  "currency": "USD"
}

Several orders at once

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=status \
  -d orders=23501,23502,99999

Response

{
  "23501": { "charge": "0.90", "start_count": 3572, "status": "Completed", "remains": 0, "currency": "USD" },
  "23502": { "charge": "4.50", "start_count": 0, "status": "Pending", "remains": 5000, "currency": "USD" },
  "99999": { "error": "Incorrect order ID" }
}
  • status is exactly one of: Pending, In progress, Processing, Completed, Partial, Canceled.
  • Until delivery starts, remains equals the ordered quantity and start_count is 0.
  • In a multi-order request an unknown ID gets its own error entry; the other orders are still returned.

refill

Request a refill for a completed or partial order.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesrefill
orderNoOne order ID.
ordersNoComma-separated order IDs, max 100. Use instead of order.

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=refill \
  -d order=23501

Response

{ "refill": "23501" }

Several orders at once

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=refill \
  -d orders=23501,23510

Response

[
  { "order": 23501, "refill": 23501 },
  { "order": 23510, "error": "Refill not available" }
]
  • A refill is accepted when the service has refill: true, the order is Completed or Partial, it is still inside the service's refill period (counted from the order date), and no refill has been requested for it before.
  • The refill ID is the order ID. Pass it to refill_status.

refill_status

Check the progress of a refill you requested.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesrefill_status
refillYesRefill ID returned by refill (same as the order ID).

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=refill_status \
  -d refill=23501

Response

{ "status": "In progress" }
  • status is one of: Pending, In progress, Completed, Rejected.

cancel

Request cancellation of up to 100 orders.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYescancel
ordersYesComma-separated order IDs, max 100. A single order= is accepted too.

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=cancel \
  -d orders=23501,23502

Response

[
  { "order": 23501, "cancel": 1 },
  { "order": 23502, "cancel": { "error": "Cancel not available" } }
]
  • Cancellation is accepted when the service has cancel: true, the order is still Pending, In progress or Processing, and it hasn't been requested before.
  • cancel: 1 means the request was recorded. Keep polling status to see the final result.

balance

Get your current account balance.

ParameterRequiredDescription
keyYesYour API key (starts with smm_).
actionYesbalance

Request

curl -X POST https://9smm.com/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=balance

Response

{ "balance": "100.84", "currency": "USD" }
  • Balance and charges are always in USD, whatever currency you view the website in.

Errors

Errors are returned with HTTP 200 and a body such as {"error": "Incorrect order ID"}. Check for the error field on every response. The messages below are exact, so you can match on them.

errorWhen it happens
Invalid API keyThe key is missing or wrong, was replaced by a newer key, or the account is not active.
Rate limit exceededToo many requests for this key in the last minute. Returned with HTTP 429.
No action specifiedThe action parameter is empty.
Invalid actionThe action is not one of the seven listed on this page.
Incorrect service IDThe service ID is not a number, the service isn't available, or you asked for drip-feed on a service without it.
Incorrect linkThe link is empty, or you already have an active order for this link on this service.
Incorrect quantityQuantity is missing or outside the service's min–max, a drip-feed run is outside those limits, or interval is outside 0–1440.
Incorrect commentscomments was sent but every line is empty.
Not enough funds on balanceYour balance doesn't cover the order charge.
Order failedAny other rejection, for example more than 100 runs or a comment over 500 characters.
Incorrect order IDThe order ID doesn't exist on your account or isn't a number.
Too many orders (max 100)More than 100 IDs in orders.
Refill not availableThe order doesn't meet the refill conditions described under refill.
Cancel not availableThe order doesn't meet the cancel conditions described under cancel.
Incorrect refill IDNo refill was requested for that order, or the ID isn't yours.
Internal errorSomething failed on our side. Retry later; contact support if it persists.

Rate limits and good practice

  • Each key can make 1,200 requests in any rolling minute. Above that the API answers HTTP 429 with {"error": "Rate limit exceeded"}; wait a few seconds and retry.
  • Poll order progress with orders= (up to 100 IDs per request) instead of one request per order.
  • Cache the services list and refresh it periodically rather than on every order.
  • If an add request times out, check status or your Orders page before sending it again.
  • Keep the key on your server. Never put it in browser JavaScript or a mobile app.

API FAQ

Is this API compatible with other SMM panels?

Yes. It uses the standard v2 format that most SMM panels and reseller scripts expect: the same action names, parameter names, response fields and status strings. Existing software usually only needs the new API URL and your key.

How do I get an API key?

Create a free 9SMM.COM account, open Profile in your dashboard and click Generate API key in the API access card. The full key is shown only once, so store it safely. Regenerating creates a new key and stops the old one immediately.

Can I send JSON instead of form data?

Yes. Send application/x-www-form-urlencoded (the standard) or a JSON body with the same parameter names. GET requests with query parameters are also accepted, but POST keeps your key out of server logs.

Why do errors come back with HTTP 200?

That is the SMM panel convention: many existing clients only read the response body and would crash on a 4xx status before seeing the message. Always check for an error field. The one exception is the rate limit, which returns HTTP 429.

What currency are balance and prices in?

USD. Rates in the services list are per 1,000 units, and balance and order charges are reported in USD even if you view the website in another currency.

What happens if my add request times out?

Don't resend it blindly. Call status or check the Orders page first. A second active order for the same link on the same service is rejected with Incorrect link, which protects you from most accidental duplicates.

SMM Panel API — Endpoints, Errors & Code Samples · 9SMM.COM