SMSPING · DEVELOPERS

SMS-Activate compatible API

If your code or tool was written for SMS-Activate's handler_api.php, you can point it at SMSPing by changing the base URL and the API key. The supported actions take the same parameters and return the same response strings. SMSPing lists 150+ countries and 1,300+ services.

Change one line

Old: https://api.sms-activate.org/stubs/handler_api.php
New: https://smsping.net/stubs/handler_api.php

Send api_key and action as query parameters (GET) or as a form or JSON body (POST), the same way you did before. Use the SMS-Activate numeric country IDs (for example 16 United Kingdom, 187 USA, 6 Indonesia) and service codes (for example tg Telegram, wa WhatsApp, go Google). Call getCountries and getServicesList for the full lists we map.

getNumber and getNumberV2 buy a number and deduct real balance from your SMSPing account.

Get an API key

  1. Create an account or sign in at smsping.net.
  2. Add balance. We mainly accept USDT (TRC20, ERC20 and BEP20); TRX, ETH and BNB are also supported. The minimum top-up is $10.
  3. Open Account Settings, then API Management, and generate a key. It starts with psk_ and is shown in full once.
  4. Keep the key on your server, in an environment variable such as SMSPING_API_KEY. Never put it in browser code or a public repository.

Supported actions

ActionKey neededResponse
getBalanceYesACCESS_BALANCE:12.40 (USD)
getNumberYesACCESS_NUMBER:1000123:447700900123. Parameters: service, country, optional maxPrice. Picks the cheapest in-stock offer.
getNumberV2YesJSON with activationId, phoneNumber, activationCost, countryCode, activationTime, activationEndTime
getStatusYesSTATUS_WAIT_CODE, STATUS_OK:12345 or STATUS_CANCEL
getStatusV2YesJSON with sms (dateTime, code, text) or null; call is always null
setStatusYesstatus=8 cancel and refund → ACCESS_CANCEL; 6 finish → ACCESS_ACTIVATION; 1 → ACCESS_READY; 3 → ACCESS_RETRY_GET
getActiveActivationsYesJSON list of your waiting and received activations
getPricesYesJSON {country: {service: {cost, count}}}. Pass country, service or both.
getNumbersStatusYesJSON such as {"tg_0": "100"} for one country
getCountriesNoJSON keyed by SMS-Activate country ID, for the countries we list
getServicesListNoJSON {status, services: [{code, name}]} with SMS-Activate service codes

Errors come back as plain text with HTTP 200, as SMS-Activate clients expect: NO_KEY, BAD_KEY, BAD_ACTION, BAD_SERVICE, BAD_COUNTRY, BAD_STATUS, NO_NUMBERS, NO_BALANCE, NO_ACTIVATION, WRONG_MAX_PRICE, CHANNELS_LIMIT, BANNED, ERROR_SQL.

Python example

import os, time, requests

BASE = "https://smsping.net/stubs/handler_api.php"   # was https://api.sms-activate.org/stubs/handler_api.php
KEY = os.environ["SMSPING_API_KEY"]                   # psk_... from Account Settings > API Management


def sa(action, **params):
    r = requests.get(BASE, params={"api_key": KEY, "action": action, **params}, timeout=30)
    r.raise_for_status()
    return r.text


print(sa("getBalance"))                               # ACCESS_BALANCE:12.40

resp = sa("getNumber", service="tg", country=16)      # Telegram, United Kingdom; spends balance
if not resp.startswith("ACCESS_NUMBER:"):
    raise SystemExit(resp)                            # NO_NUMBERS, NO_BALANCE, BAD_SERVICE, ...
_, activation_id, phone = resp.split(":")
print("Number:", phone)

for _ in range(120):                                  # local 10-minute limit
    status = sa("getStatus", id=activation_id)
    if status.startswith("STATUS_OK:"):
        print("Code:", status.split(":", 1)[1])
        sa("setStatus", id=activation_id, status=6)   # finish
        break
    if status != "STATUS_WAIT_CODE":
        raise SystemExit(status)
    time.sleep(5)
else:
    print(sa("setStatus", id=activation_id, status=8))  # ACCESS_CANCEL, balance refunded

Run it with pip install requests and SMSPING_API_KEY=psk_... python sms_activate_compat.py.

Node.js example

// Node.js 18+ (built-in fetch)
const BASE = "https://smsping.net/stubs/handler_api.php"; // was https://api.sms-activate.org/stubs/handler_api.php
const KEY = process.env.SMSPING_API_KEY;                  // psk_... from Account Settings > API Management

async function sa(action, params = {}) {
  const url = new URL(BASE);
  url.search = new URLSearchParams({ api_key: KEY, action, ...params });
  const res = await fetch(url);
  return (await res.text()).trim();
}

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

console.log(await sa("getBalance"));                    // ACCESS_BALANCE:12.40

const v2 = await sa("getNumberV2", { service: "wa", country: 187 }); // WhatsApp, USA; spends balance
if (!v2.startsWith("{")) throw new Error(v2);           // NO_NUMBERS, NO_BALANCE, ...
const { activationId, phoneNumber } = JSON.parse(v2);
console.log("Number:", phoneNumber);

for (let i = 0; i < 120; i++) {                          // local 10-minute limit
  const status = await sa("getStatus", { id: activationId });
  if (status.startsWith("STATUS_OK:")) {
    console.log("Code:", status.slice(10));
    await sa("setStatus", { id: activationId, status: 6 });
    process.exit(0);
  }
  if (status !== "STATUS_WAIT_CODE") throw new Error(status);
  await sleep(5000);
}
console.log(await sa("setStatus", { id: activationId, status: 8 })); // ACCESS_CANCEL, refunded

Save as compat.mjs and run SMSPING_API_KEY=psk_... node compat.mjs.

Differences and limits

  • Not supported: rentals (getRent*), voice-call verification, multi-service numbers (getMultiServiceNumber), additional-service and forwarding actions. These return BAD_ACTION.
  • operator, phoneException and forward are accepted but ignored. getNumber picks the cheapest offer that is in stock.
  • getPrices needs a key and at least one of country or service; with neither it returns BAD_SERVICE.
  • Countries and services that SMSPing does not list return BAD_COUNTRY or BAD_SERVICE.
  • setStatus=1 and 3 are acknowledged; the number keeps waiting for SMS either way.
  • Prices are in USD. Times are UTC in ISO 8601 format.
  • Each account can make 60 requests per minute. Beyond that the endpoint answers ERROR_SQL; wait and retry. Poll getStatus every 5 seconds or slower.
  • Call the endpoint from your server. Browser requests from other websites are rejected.
  • Prefer the native JSON API? See the Python and Node.js tutorials.

Help and FAQ

Do I need to rewrite my SMS-Activate client?

No for the supported actions. Change the base URL to https://smsping.net/stubs/handler_api.php and use an SMSPing API key. Requests and responses keep the SMS-Activate format.

Where do I get the api_key?

Sign in to SMSPing and generate a key in Account Settings under API Management. The full key is shown once. Keys start with psk_.

Is a canceled activation refunded?

Yes. setStatus=8 on an activation with no SMS cancels it and refunds the charge once to your SMSPing balance. Repeating the cancel does not refund twice.

How often should I call getStatus?

Every 5 seconds or slower. Each account has a limit of 60 requests per minute, and the compatible endpoint counts toward it.

Ready to switch?

Sign in to generate an API key, then change the base URL in your existing SMS-Activate code. Before buying, confirm that your chosen number type is accepted by the target service.

Open SMSPing