v1.1.0

Номера и коды — из вашего кода

Покупайте виртуальные номера, получайте коды и управляйте заказами обычными HTTP-запросами. Ответы — JSON. Баланс и цены те же, что в Telegram-боте, включая ваши личные скидки.

Базовый адресhttps://volksms.space
⚡ БыстроПокупка и статус заказа за один запрос.
🔔 ВебхукиКод сам придёт на ваш сервер — опрашивать не нужно.
🛡 Возврат денегНет кода за отведённое время — заказ отменяется, деньги возвращаются.

Быстрый старт

Получите токен

В Telegram-боте отправьте /api (или нажмите «API» в меню) → «Создать токен». Токен показывается один раз — сохраните его. Можно держать до 5 токенов.

Пополните баланс

Деньги общие с ботом: пополнять можно в боте. Баланс в долларах США.

Проверьте токен

Любой запрос с заголовком Authorization:

curl "https://volksms.space/v1/me" -H "Authorization: Bearer YOUR_TOKEN"
Купите номер и заберите код

Готовый скрипт — в разделе «Готовые примеры», а любой метод можно сразу испытать кнопкой «Попробовать запрос» прямо на этой странице.

Авторизация

Передавайте токен в заголовке каждого запроса (кроме этой страницы, /health и /openapi.json).

Authorization: Bearer YOUR_TOKEN

Также принимается заголовок X-API-Key: YOUR_TOKEN.

🔑
Токен даёт доступ к вашему балансу. Не публикуйте его и не вставляйте в клиентский код сайтов и приложений. Если токен утёк — отзовите его в боте (/api) и создайте новый.

Формат ответов

Все ответы — JSON в UTF-8. Цены и баланс — числа в долларах США, время — Unix-время в секундах (UTC). Успех:

{
  "ok": true,
  "data": {
    "...": "..."
  }
}

Ошибка — HTTP-статус тоже не 200, а в error.code лежит стабильный код, по которому удобно писать логику:

{
  "ok": false,
  "error": {
    "code": "insufficient_balance",
    "message": "Не хватает средств",
    "need": 0.45,
    "balance": 0.1
  }
}

Жизненный цикл заказа

У заказа всегда один статус из списка ниже.

waiting→code_received→completed
waiting→cancelledилиexpired· деньги возвращены
СтатусЧто значит
waitingНомер куплен, ждём код. Можно отменить (после 2 минут) — деньги вернутся.
code_receivedКод пришёл и лежит в code. Дальше — finish, либо repeat, если нужен ещё один код.
completedЗаказ завершён.
cancelledЗаказ отменён, деньги возвращены.
expiredКод не пришёл за отведённое время: заказ отменён автоматически, деньги возвращены.

Объект заказа:

{
  "id": "ord_3f9a1c7b2d4e",
  "service": "Telegram",
  "service_id": "tg",
  "phone": "79991234567",
  "price": 0.45,
  "status": "code_received",
  "codes": [
    "48213"
  ],
  "code": "48213",
  "created_at": 1760000000,
  "expires_at": 1760001200,
  "can_cancel": false,
  "cancel_available_in": 0
}

Аккаунт

GET/v1/me
Кто я

Информация о владельце токена: ID аккаунта, баланс, данные токена.

curl -X GET "https://volksms.space/v1/me" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/me", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/me`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "user_id": 123456789,
    "balance": 12.5,
    "token": {
      "id": 7,
      "name": "Токен 1",
      "prefix": "vsk_a1b2c3",
      "webhook": null
    }
  }
}
Попробовать запрос
GET/v1/balance
Баланс

Текущий баланс в долларах. Баланс общий с Telegram-ботом: пополнять его можно в боте.

curl -X GET "https://volksms.space/v1/balance" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/balance", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/balance`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "balance": 12.5,
    "currency": "USD"
  }
}
Попробовать запрос

Каталог

GET/v1/services
Список сервисов

Все сервисы, которые можно купить через API, с вашей ценой за один номер (учитываются ваши личные цены/скидки, если они есть). Поле price — null, если сервиса сейчас нет в наличии.

Параметры
ИмяГдеТипОбязат.Описание
searchquerystringнетЧасть названия, например tele.
availablequerybooleanнет1 — показать только то, что есть в наличии.
curl -X GET "https://volksms.space/v1/services" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/services", headers=HEADERS, params={"available": 1})
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/services?available=1`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "services": [
      {
        "id": "tg",
        "name": "Telegram",
        "category": "Мессенджеры",
        "price": 0.45,
        "in_stock": true
      }
    ],
    "count": 1
  }
}
Попробовать запрос
GET/v1/services/{service}
Один сервис

Цена и наличие одного сервиса. {service} — его id из списка или точное название.

Параметры
ИмяГдеТипОбязат.Описание
servicepathstringдаID или название сервиса.
curl -X GET "https://volksms.space/v1/services/tg" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/services/tg", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/services/tg`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "id": "tg",
    "name": "Telegram",
    "category": "Мессенджеры",
    "price": 0.45,
    "in_stock": true
  }
}
Попробовать запрос

Заказы

POST/v1/orders
Купить номер(а)

Покупает номер и сразу списывает деньги с баланса. Код придёт позже: следите за заказом через GET /v1/orders/{id} или подключите вебхук. Если за 20 минут код не пришёл, заказ автоматически отменяется, а деньги возвращаются.
Можно купить сразу несколько: quantity от 1 до 30. Куплено может оказаться меньше запрошенного — за непроданные деньги не списываются (смотрите bought и error в ответе).

Параметры
ИмяГдеТипОбязат.Описание
servicebodystringдаID или название сервиса.
quantitybodyintegerнетСколько номеров купить (1–30). По умолчанию 1.
curl -X POST "https://volksms.space/v1/orders" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"service": "tg", "quantity": 1}'
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.post(f"{BASE}/v1/orders", headers=HEADERS, json={"service": "tg", "quantity": 1})
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders`, { method: "POST", headers: { Authorization: "Bearer YOUR_TOKEN", "Content-Type": "application/json" }, body: JSON.stringify({"service": "tg", "quantity": 1}) });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 201
{
  "ok": true,
  "data": {
    "orders": [
      {
        "id": "ord_3f9a1c7b2d4e",
        "service": "Telegram",
        "service_id": "tg",
        "phone": "79991234567",
        "price": 0.45,
        "status": "waiting",
        "codes": [],
        "code": null,
        "created_at": 1760000000,
        "expires_at": 1760001200,
        "can_cancel": false,
        "cancel_available_in": 120
      }
    ],
    "requested": 1,
    "bought": 1,
    "charged": 0.45,
    "balance": 12.05
  }
}
Попробовать запрос
⚠️
Это настоящий запрос: номер будет куплен, деньги спишутся с баланса.
GET/v1/orders
Список заказов

Ваши заказы, сделанные через API, от новых к старым.

Параметры
ИмяГдеТипОбязат.Описание
statusquerystringнетФильтр: waiting, code_received, completed, cancelled, expired.
limitqueryintegerнетСколько вернуть (1–100). По умолчанию 20.
offsetqueryintegerнетСколько пропустить — для постраничного чтения.
curl -X GET "https://volksms.space/v1/orders" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/orders", headers=HEADERS, params={"status": "waiting", "limit": 20})
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders?status=waiting&limit=20`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "orders": [
      {
        "id": "ord_3f9a1c7b2d4e",
        "service": "Telegram",
        "service_id": "tg",
        "phone": "79991234567",
        "price": 0.45,
        "status": "code_received",
        "codes": [
          "48213"
        ],
        "code": "48213",
        "created_at": 1760000000,
        "expires_at": 1760001200,
        "can_cancel": false,
        "cancel_available_in": 0
      }
    ],
    "count": 1,
    "limit": 20,
    "offset": 0
  }
}
Попробовать запрос
GET/v1/orders/{id}
Статус заказа и код

Состояние заказа. Когда придёт код, status станет code_received, а код появится в code (и в списке codes, если их несколько). Опрашивайте не чаще раза в 3–5 секунд, либо используйте вебхук.

Параметры
ИмяГдеТипОбязат.Описание
idpathstringдаID заказа (ord_…).
curl -X GET "https://volksms.space/v1/orders/ord_3f9a1c7b2d4e" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.get(f"{BASE}/v1/orders/ord_3f9a1c7b2d4e", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders/ord_3f9a1c7b2d4e`, { method: "GET", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "id": "ord_3f9a1c7b2d4e",
    "service": "Telegram",
    "service_id": "tg",
    "phone": "79991234567",
    "price": 0.45,
    "status": "code_received",
    "codes": [
      "48213"
    ],
    "code": "48213",
    "created_at": 1760000000,
    "expires_at": 1760001200,
    "can_cancel": false,
    "cancel_available_in": 0
  }
}
Попробовать запрос
POST/v1/orders/{id}/cancel
Отменить заказ

Отменяет заказ, если код ещё не пришёл, и возвращает деньги на баланс. Отмена обычных номеров доступна через 2 минуты после покупки (до этого вернётся ошибка too_early с полем retry_after).

Параметры
ИмяГдеТипОбязат.Описание
idpathstringдаID заказа.
curl -X POST "https://volksms.space/v1/orders/ord_3f9a1c7b2d4e/cancel" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.post(f"{BASE}/v1/orders/ord_3f9a1c7b2d4e/cancel", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders/ord_3f9a1c7b2d4e/cancel`, { method: "POST", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "id": "ord_3f9a1c7b2d4e",
    "status": "cancelled",
    "refunded": 0.45,
    "balance": 12.5
  }
}
Попробовать запрос
⚠️
Заказ будет отменён, деньги вернутся на баланс.
POST/v1/orders/{id}/repeat
Ждать ещё один код

Если по номеру уже пришёл код, а нужен ещё один (например, повторная отправка), вызовите этот метод: заказ снова перейдёт в ожидание новых кодов до конца 20 минут с момента покупки. Новый код добавится в codes.

Параметры
ИмяГдеТипОбязат.Описание
idpathstringдаID заказа.
curl -X POST "https://volksms.space/v1/orders/ord_3f9a1c7b2d4e/repeat" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.post(f"{BASE}/v1/orders/ord_3f9a1c7b2d4e/repeat", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders/ord_3f9a1c7b2d4e/repeat`, { method: "POST", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "id": "ord_3f9a1c7b2d4e",
    "service": "Telegram",
    "service_id": "tg",
    "phone": "79991234567",
    "price": 0.45,
    "status": "code_received",
    "codes": [
      "48213"
    ],
    "code": "48213",
    "created_at": 1760000000,
    "expires_at": 1760001200,
    "can_cancel": false,
    "cancel_available_in": 0
  }
}
Попробовать запрос
⚠️
Заказ снова начнёт ждать новые коды.
POST/v1/orders/{id}/finish
Завершить заказ

Сообщает, что код получен и номер больше не нужен: заказ закрывается (статус completed). Освобождает ресурсы, рекомендуется вызывать после получения кода. Если не вызвать — заказ закроется сам к концу срока.

Параметры
ИмяГдеТипОбязат.Описание
idpathstringдаID заказа.
curl -X POST "https://volksms.space/v1/orders/ord_3f9a1c7b2d4e/finish" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.post(f"{BASE}/v1/orders/ord_3f9a1c7b2d4e/finish", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/orders/ord_3f9a1c7b2d4e/finish`, { method: "POST", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "id": "ord_3f9a1c7b2d4e",
    "service": "Telegram",
    "service_id": "tg",
    "phone": "79991234567",
    "price": 0.45,
    "status": "completed",
    "codes": [
      "48213"
    ],
    "code": "48213",
    "created_at": 1760000000,
    "expires_at": 1760001200,
    "can_cancel": false,
    "cancel_available_in": 0
  }
}
Попробовать запрос
⚠️
Заказ будет закрыт.

Вебхук

PUT/v1/webhook
Задать вебхук

Адрес, на который мы сами отправим POST, когда по заказу придёт код или заказ отменится. Так не нужно постоянно опрашивать статус. В ответе — секрет для проверки подписи (показывается только сейчас). Подробности — в разделе «Вебхуки».

Параметры
ИмяГдеТипОбязат.Описание
urlbodystringдаПубличный http(s)-адрес. Адреса внутренних сетей не принимаются.
curl -X PUT "https://volksms.space/v1/webhook" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/sms"}'
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.put(f"{BASE}/v1/webhook", headers=HEADERS, json={"url": "https://example.com/hooks/sms"})
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/webhook`, { method: "PUT", headers: { Authorization: "Bearer YOUR_TOKEN", "Content-Type": "application/json" }, body: JSON.stringify({"url": "https://example.com/hooks/sms"}) });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "url": "https://example.com/hooks/sms",
    "secret": "whsec_3b1f…"
  }
}
Попробовать запрос
⚠️
Адрес вебхука будет заменён, секрет сменится.
DELETE/v1/webhook
Убрать вебхук

Отключает отправку уведомлений.

curl -X DELETE "https://volksms.space/v1/webhook" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.delete(f"{BASE}/v1/webhook", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/webhook`, { method: "DELETE", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "url": null
  }
}
Попробовать запрос
⚠️
Вебхук будет отключён.
POST/v1/webhook/test
Проверить вебхук

Отправляет на ваш адрес тестовое событие ping и показывает, что ответил ваш сервер.

curl -X POST "https://volksms.space/v1/webhook/test" \
  -H "Authorization: Bearer YOUR_TOKEN"
import requests

BASE = "https://volksms.space"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

r = requests.post(f"{BASE}/v1/webhook/test", headers=HEADERS)
data = r.json()
if not data["ok"]:
    raise RuntimeError(data["error"])
print(data["data"])
const BASE = "https://volksms.space";

const res = await fetch(`${BASE}/v1/webhook/test`, { method: "POST", headers: { Authorization: "Bearer YOUR_TOKEN" } });
const data = await res.json();
if (!data.ok) throw new Error(data.error.message);
console.log(data.data);
Ответ 200
{
  "ok": true,
  "data": {
    "delivered": true,
    "http_status": 200
  }
}
Попробовать запрос
Ничего не найдено — попробуйте другой запрос.

Вебхуки

Зарегистрируйте адрес через PUT /v1/webhook — мы сами отправим на него POST с JSON, когда что-то случится с заказом. Опрашивать статус тогда не нужно.

eventКогда
order.codeПришёл новый код (поле code).
order.cancelledЗаказ отменён, деньги возвращены.
order.expiredКод не пришёл вовремя, заказ отменён, деньги возвращены.
pingТест из POST /v1/webhook/test.
Пример события order.code
{
  "event": "order.code",
  "code": "48213",
  "order": {
    "id": "ord_3f9a1c7b2d4e",
    "service": "Telegram",
    "service_id": "tg",
    "phone": "79991234567",
    "price": 0.45,
    "status": "code_received",
    "codes": [
      "48213"
    ],
    "code": "48213",
    "created_at": 1760000000,
    "expires_at": 1760001200,
    "can_cancel": false,
    "cancel_available_in": 0
  }
}
Пример события order.cancelled
{
  "event": "order.cancelled",
  "reason": "cancelled",
  "order": {
    "id": "ord_3f9a1c7b2d4e",
    "service": "Telegram",
    "service_id": "tg",
    "phone": "79991234567",
    "price": 0.45,
    "status": "cancelled",
    "codes": [],
    "code": null,
    "created_at": 1760000000,
    "expires_at": 1760001200,
    "can_cancel": false,
    "cancel_available_in": 120
  }
}
ЗаголовокЗначение
X-EventНазвание события.
X-Signaturesha256=<hex> — HMAC-SHA256 от сырого тела запроса с вашим секретом.
✅
Обязательно проверяйте подпись и считайте её от сырых байт тела, а не от пересобранного JSON. Отвечайте кодом 2xx в течение 10 секунд — иначе мы повторим отправку до 4 раз (через 3, 6 и 12 секунд). События могут прийти повторно, поэтому обрабатывайте их идемпотентно — по order.id и code.
import hashlib, hmac
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = "whsec_..."   # секрет из ответа PUT /v1/webhook
seen = set()


@app.post("/hooks/sms")
def hook():
    raw = request.get_data()
    expected = "sha256=" + hmac.new(SECRET.encode(), raw, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-Signature", "")):
        abort(401)
    ev = request.get_json()
    key = (ev.get("event"), ev["order"]["id"], ev.get("code"))
    if key not in seen:                      # события могут прийти повторно
        seen.add(key)
        if ev["event"] == "order.code":
            print("Код по заказу", ev["order"]["id"], ":", ev["code"])
    return "ok"
const crypto = require("crypto");
const express = require("express");
const app = express();
const SECRET = "whsec_...";   // секрет из ответа PUT /v1/webhook

app.post("/hooks/sms", express.raw({ type: "*/*" }), (req, res) => {
  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const got = req.get("X-Signature") || "";
  if (got.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected)))
    return res.sendStatus(401);
  const ev = JSON.parse(req.body);
  if (ev.event === "order.code") console.log("Код:", ev.code, "заказ:", ev.order.id);
  res.send("ok");
});
app.listen(3000);
<?php
$secret = "whsec_...";   // секрет из ответа PUT /v1/webhook
$raw = file_get_contents("php://input");
$expected = "sha256=" . hash_hmac("sha256", $raw, $secret);
if (!hash_equals($expected, $_SERVER["HTTP_X_SIGNATURE"] ?? "")) { http_response_code(401); exit; }
$ev = json_decode($raw, true);
if ($ev["event"] === "order.code") { error_log("Код {$ev['code']} по заказу {$ev['order']['id']}"); }
echo "ok";

Ошибки

Смотрите на error.code, а не на текст сообщения: тексты могут уточняться.

HTTPcodeЗначение
400invalid_jsonТело запроса — не корректный JSON.
400invalid_paramНеверное значение параметра (в сообщении указано, какого).
401unauthorizedНет токена, он неверный или отозван.
402insufficient_balanceНе хватает денег. В ответе есть поля need и balance.
403access_closedМагазин временно закрыт для клиентов.
404service_not_foundТакого сервиса нет.
404order_not_foundЗаказ не найден (или он не ваш).
409out_of_stockСервиса сейчас нет в наличии.
409no_numbersСвободных номеров сейчас нет — деньги не списаны, попробуйте позже.
409too_many_activeСлишком много заказов ждут код одновременно.
409too_earlyОтмена пока недоступна, повторите через retry_after секунд.
409code_already_receivedКод по заказу уже пришёл — отменить нельзя.
409wrong_stateДействие недоступно в текущем статусе заказа.
429rate_limitedСлишком много запросов. Подождите retry_after секунд.
500internal_errorВнутренняя ошибка — повторите запрос.
502provider_errorНе удалось купить номер (проблема на стороне поставщика). Деньги не списаны.
502cancel_failedНе получилось отменить прямо сейчас — повторите позже.
503api_disabledAPI временно отключён.
503maintenanceВ магазине идут технические работы.

Лимиты

600 / минзапросов на один токен. При превышении — 429 rate_limited и заголовок Retry-After.
до 30 номеровза один запрос покупки (quantity).
≈ 30 активныхзаказов, ждущих код, на аккаунт (для части сервисов меньше).
20 минутожидание кода с момента покупки (у части сервисов 15), затем заказ отменяется с возвратом денег.
5 токеновможно создать на один аккаунт.
3–5 секундминимальный разумный интервал опроса заказа. Лучше — вебхуки.

Готовые примеры

Полный сценарий: купить номер → дождаться кода → закрыть заказ.

import time
import requests

BASE = "https://volksms.space"
H = {"Authorization": "Bearer YOUR_TOKEN"}


def call(method, path, **kw):
    r = requests.request(method, BASE + path, headers=H, timeout=30, **kw).json()
    if not r["ok"]:
        raise RuntimeError(f"{r['error']['code']}: {r['error']['message']}")
    return r["data"]


# 1. Покупаем номер
order = call("POST", "/v1/orders", json={"service": "tg"})["orders"][0]
print("Номер:", order["phone"])

# 2. Ждём код (или используйте вебхуки вместо опроса)
while True:
    o = call("GET", f"/v1/orders/{order['id']}")
    if o["status"] == "code_received":
        print("Код:", o["code"])
        call("POST", f"/v1/orders/{o['id']}/finish")   # 3. закрываем заказ
        break
    if o["status"] in ("cancelled", "expired"):
        print("Кода не будет, деньги возвращены")
        break
    time.sleep(4)
const BASE = "https://volksms.space";
const H = { Authorization: "Bearer YOUR_TOKEN", "Content-Type": "application/json" };

async function call(method, path, body) {
  const r = await (await fetch(BASE + path, { method, headers: H, body: body && JSON.stringify(body) })).json();
  if (!r.ok) throw new Error(`${r.error.code}: ${r.error.message}`);
  return r.data;
}

// 1. Покупаем номер
const order = (await call("POST", "/v1/orders", { service: "tg" })).orders[0];
console.log("Номер:", order.phone);

// 2. Ждём код (или используйте вебхуки вместо опроса)
while (true) {
  const o = await call("GET", `/v1/orders/${order.id}`);
  if (o.status === "code_received") {
    console.log("Код:", o.code);
    await call("POST", `/v1/orders/${o.id}/finish`);   // 3. закрываем заказ
    break;
  }
  if (o.status === "cancelled" || o.status === "expired") break;
  await new Promise(r => setTimeout(r, 4000));
}
BASE="https://volksms.space"
TOKEN="YOUR_TOKEN"

# баланс
curl -s "$BASE/v1/balance" -H "Authorization: Bearer $TOKEN"

# купить номер
curl -s -X POST "$BASE/v1/orders" -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" -d '{"service":"tg"}'

# статус и код
curl -s "$BASE/v1/orders/ORDER_ID" -H "Authorization: Bearer $TOKEN"
Служебные адреса без токена
АдресЧто отдаёт
/healthСостояние сервиса и версию API.
/docsЭта страница.
/openapi.jsonСпецификация OpenAPI 3 — для Postman, Insomnia и генераторов клиентов.