RelySMS
API · протокол handler_api.php

Номери для прийому SMS — із вашого софту

Якщо ваш софт уже працює з сервісом активацій через handler_api.php, він запрацює з RelySMS: змініть адресу сервера й ключ. Ті самі дії, ті самі відповіді, наші ціни й повернення.

https://relysms.pro/stubs/handler_api.php

Швидкий старт

  1. Увійдіть у кабінет і відкрийте «Баланс» → «API» → «Створити ключ». Ключ показується один раз — збережіть його.
  2. Поповніть баланс до $20 або більше: покупки через API проходять лише за такого балансу. Тримати ключ можна й із нульовим балансом.
  3. Вкажіть у софті адресу сервера https://relysms.pro/stubs/handler_api.php і ваш ключ замість ключа попереднього сервісу.
  4. Купіть номер (getNumber), опитуйте статус раз на 5–10 секунд (getStatus), доки не прийде STATUS_OK із кодом.
  5. Завершіть замовлення (setStatus=6). Якщо код не прийшов — скасуйте через 2 хвилини (setStatus=8) або просто дочекайтеся кінця вікна: гроші повернуться самі.

Правила й ліміти

  • Покупки через API — лише за балансу від $20. Нижче порогу getNumber відповідає NO_BALANCE; решта методів працює.
  • Номер ваш 20 хвилин. Код не прийшов — замовлення закривається саме, гроші повертаються на баланс.
  • Скасувати можна через 2 хвилини після покупки, якщо коду ще немає. Гроші повертаються одразу.
  • Після першого коду замовлення оплачене й не повертається. Поки вікно відкрите, на номер можуть прийти й наступні коди.
  • До 20 запитів і до 5 покупок на секунду на ключ; до 50 відкритих замовлень одночасно.
  • Ціна фіксується в момент покупки. maxPrice захищає від покупки дорожче за ваш ліміт.
  • Діють умови сервісу: спам, шахрайство й масові реєстрації з цією метою заборонені.

Методи

Усі запити — GET або POST на одну адресу, параметри в рядку запиту чи в тілі форми. Ключ передається в параметрі api_key, дія — в action.

getBalance

Баланс акаунта в доларах.

Лише api_key і action.

GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getBalance

Відповідь

ACCESS_BALANCE:25.00

getNumber

Купити номер для сервісу в країні. Гроші списуються одразу; якщо код не прийде — повернуться. Відповідь: ACCESS_NUMBER:номер_замовлення:телефон.

ПараметрОбов’язковийОпис
serviceтакКод сервісу (getServicesList), наприклад tg.
countryтакКод країни (getCountries).
maxPriceніМаксимальна ціна в доларах. Дорожче — WRONG_MAX_PRICE з поточною ціною, нічого не списано.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getNumber&service=tg&country=187&maxPrice=0.80

Відповідь

ACCESS_NUMBER:1042:15550001111

Можливі помилки: BAD_SERVICE, BAD_COUNTRY, NO_NUMBERS, NO_BALANCE, WRONG_MAX_PRICE:0.59, LIMIT_ACTIVATIONS, RATE_LIMIT, BANNED

getNumberV2

Те саме, що getNumber, але відповідь у JSON із ціною й часом вікна.

ПараметрОбов’язковийОпис
serviceтакКод сервісу.
countryтакКод країни.
maxPriceніМаксимальна ціна в доларах.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getNumberV2&service=tg&country=187&maxPrice=0.80

Відповідь

{
  "activationId": 1042,
  "phoneNumber": "15550001111",
  "activationCost": 0.59,
  "countryCode": "187",
  "canGetAnotherSms": true,
  "activationTime": "2026-10-27T10:00:00.000Z",
  "activationEndTime": "2026-10-27T10:20:00.000Z"
}

Можливі помилки: BAD_SERVICE, BAD_COUNTRY, NO_NUMBERS, NO_BALANCE, WRONG_MAX_PRICE:0.59, LIMIT_ACTIVATIONS, RATE_LIMIT

getStatus

Статус замовлення: чекаємо код, код прийшов (із кодом) або скасовано.

ПараметрОбов’язковийОпис
idтакНомер замовлення з getNumber.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getStatus&id=1042

Відповідь

STATUS_OK:48213

Можливі помилки: NO_ACTIVATION

setStatus

Дія із замовленням: готовий, ще код, завершити, скасувати (див. «Статуси»).

ПараметрОбов’язковийОпис
idтакНомер замовлення.
statusтак1, 3, 6 або 8.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=setStatus&id=1042&status=6

Відповідь

ACCESS_ACTIVATION

Можливі помилки: NO_ACTIVATION, BAD_STATUS, EARLY_CANCEL_DENIED, ERROR_SQL

getActiveActivations

Усі відкриті замовлення ключа: номер, статус, отримані коди й тексти.

Лише api_key і action.

GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getActiveActivations

Відповідь

{
  "status": "success",
  "activeActivations": [
    {
      "activationId": 1042,
      "serviceCode": "tg",
      "phoneNumber": "15550001111",
      "activationCost": 0.59,
      "activationStatus": "2",
      "smsCode": ["48213"],
      "smsText": ["Telegram code: 48213"],
      "activationTime": "2026-10-27T10:00:00.000Z",
      "countryCode": "187"
    }
  ]
}

getPrices

Наші ціни в доларах і приблизна кількість номерів. Без параметрів — усе, що продається.

ПараметрОбов’язковийОпис
serviceніЛише цей сервіс.
countryніЛише ця країна.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getPrices&service=tg&country=187

Відповідь

{ "187": { "tg": { "cost": 0.59, "count": 1000 } } }

Можливі помилки: BAD_SERVICE, BAD_COUNTRY

getCountries

Список країн із кодами протоколу й назвами російською та англійською.

Лише api_key і action.

GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getCountries

Відповідь

{ "187": { "id": 187, "rus": "США", "eng": "United States", "visible": 1 } }

getServicesList

Список сервісів із кодами протоколу.

Лише api_key і action.

GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getServicesList

Відповідь

{ "status": "success", "services": [{ "code": "tg", "name": "Telegram" }] }

Статуси

Значення status у setStatus:

  • status=1 → ACCESS_READY — Номер введено в сервіс, чекаємо код. Нічого не змінює, залишено для сумісності.
  • status=3 → ACCESS_RETRY_GET — Попросити ще один код на той самий номер — після першого коду, поки замовлення відкрите. Безкоштовно. До нового коду getStatus відповідає STATUS_WAIT_RETRY.
  • status=6 → ACCESS_ACTIVATION — Завершити замовлення після коду. Нові SMS на номер більше не прийдуть.
  • status=8 → ACCESS_CANCEL — Скасувати замовлення без коду (не раніше ніж через 2 хвилини). Гроші повертаються на баланс.

Відповіді getStatus:

  • STATUS_WAIT_CODE — Коду ще немає — запитайте знову за 5–10 секунд.
  • STATUS_OK:48213 — Код прийшов; після двокрапки — сам код (або текст SMS, якщо коду в ньому немає).
  • STATUS_WAIT_RETRY:48213 — Запитано ще один код, він поки не прийшов; після двокрапки — попередній код.
  • STATUS_CANCEL — Скасовано або закрито без коду; гроші вже на балансі.

Помилки

Помилки приходять рядком, як заведено в цьому протоколі. Усе, крім RATE_LIMIT, відповідає зі статусом 200.

NO_KEYНе передано api_key.
BAD_KEYКлюч неправильний, вимкнений або акаунт заблоковано.
BAD_ACTIONНевідома дія.
BAD_SERVICEНемає такого коду сервісу.
BAD_COUNTRYНемає такого коду країни.
NO_NUMBERSНомерів для цієї пари зараз немає; гроші не списано.
NO_BALANCEНа балансі менше $20 (поріг API) або менше ціни номера.
WRONG_MAX_PRICEЦіна вища за maxPrice; після двокрапки — поточна ціна.
LIMIT_ACTIVATIONSЗабагато відкритих замовлень — завершіть або скасуйте частину.
RATE_LIMITЗанадто часто; HTTP 429. Повторіть за секунду.
BANNEDАкаунт заблоковано — напишіть у підтримку.
NO_ACTIVATIONНемає замовлення з таким номером у цього ключа.
BAD_STATUSЦя дія зараз недоступна для замовлення (наприклад, завершити без коду).
EARLY_CANCEL_DENIEDСкасувати можна лише через 2 хвилини після покупки.
ERROR_SQLТимчасова помилка на нашому боці — повторіть запит за хвилину.

Коди сервісів і країн

Коди — стандартні для протоколу: tg — Telegram, wa — WhatsApp і так далі; країна 187 — США. Повні списки віддають getServicesList і getCountries — беріть коди звідти, а не зі старих таблиць: набір сервісів і країн змінюється разом із наявністю.

REST API v1

Ті самі номери й ті самі правила, що в handler_api.php, але в JSON: сервіси за назвою (telegram), країни за ISO-кодом (US), HTTP-статуси й коди помилок, за якими програмі зручно розгалужуватися. Для нового коду — сюди; софт, що вже говорить handler_api.php, залиште як є.

https://relysms.pro/api/v1

Ключ

Ключ передається в заголовку: Authorization: Bearer <ключ> (або X-Api-Key: <ключ>). Не в адресі — адреси потрапляють у логи. Ліміти, поріг $20 і каталог ті самі, що в handler_api.php.

Повтори без подвійних покупок

До POST /orders і /orders/batch додавайте заголовок Idempotency-Key зі своїм значенням (UUID, до 255 символів). Якщо зв'язок обірвався і ви повторили запит з тим самим ключем, прийде перша відповідь (із заголовком Idempotent-Replayed: true), і нічого не купиться двічі. Той самий ключ з іншим тілом запиту відхиляється; повтор, що прийшов, поки перший ще виконується, отримає idempotency_in_progress. Успішні відповіді зберігаються 24 години; невдала покупка нічого не списала, її можна повторити з тим самим ключем.

Кілька номерів одразу

POST /orders/batch купує до 20 номерів одного сервісу й країни за один запит — так можна купувати швидше ніж 5 за секунду. Покупки йдуть по черзі; перша невдала зупиняє пачку, у відповіді буде те, що купилося, а причина — в stoppedBy. Якщо не купилося нічого, відповіддю буде сама помилка.

Сторінки

GET /orders віддає спочатку нові. Якщо next не null, передайте його в before — отримаєте наступну сторінку.

Вебхуки

Замість опитування GET /orders/{id} задайте HTTPS-адресу через PUT /webhook — ми надішлемо на неї POST, коли із замовленням, купленим через API, щось станеться. У тілі — замовлення таким, яким воно було в момент надсилання. Відповідайте будь-яким 2xx протягом 10 секунд; в одного замовлення може бути кілька подій, а одна подія після повтору може прийти двічі — орієнтуйтеся на id доставки.

  • order.code_received — Прийшов код (кожен новий код — знову ця подія).
  • order.finished — Замовлення завершено — вами або після закінчення часу після коду.
  • order.cancelled — Скасовано без коду; гроші повернулися на баланс.
  • order.expired — Час вийшов без коду; гроші повернулися на баланс.
  • ping — Перевірка з POST /webhook/test; order — null.
POST /relysms-hook HTTP/1.1
Content-Type: application/json
X-RelySMS-Event: order.code_received
X-RelySMS-Delivery: cm…
X-RelySMS-Signature: t=1793095272,v1=5f2b…

{
  "id": "cm…",
  "event": "order.code_received",
  "createdAt": "2026-10-27T10:01:12.000Z",
  "order": { "id": 1042, "status": "received", "codes": [{ "code": "48213", … }], … }
}

У кожному запиті є заголовок X-RelySMS-Signature: t=<unix-час>,v1=<підпис>. Підпис — HMAC-SHA256 рядка «t.тіло» (тіло як є, байт у байт) із секретом вебхука, у hex. Перевірте його і що t не старше 5 хвилин, перш ніж довіряти тілу.

Python

import hashlib, hmac, time

def verify(secret: str, body: bytes, header: str, tolerance=300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t, sig = parts.get("t", ""), parts.get("v1", "")
    if not t.isdigit() or abs(time.time() - int(t)) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

Node.js

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(secret, rawBody, header, tolerance = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
  const t = Number(parts.t);
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > tolerance) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return expected.length === parts.v1?.length && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Якщо ваш сервер не відповів 2xx, ми повторимо через 10 секунд, 1 хвилину, 5 хвилин, 30 хвилин, 2 години й 6 годин — усього 7 спроб, потім здаємося. GET /webhook/deliveries показує, що пішло і що не дійшло.

Методи

GET /balance

Баланс у доларах і чи вистачає його для покупок через API.

curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/balance

Відповідь

{ "balance": 25, "currency": "USD", "canBuy": true, "apiMinimum": 20 }

GET /services

Усі сервіси в продажу: наш id, назва й код handler_api.php.

ПараметрОбов’язковийОпис
lang queryніМова назв: en (типово), ru, uk, zh, es, pt, id, vi, tr, ar, fr.
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/services?lang=en"

Відповідь

{ "services": [{ "id": "telegram", "name": "Telegram", "protocolCode": "tg" }] }

GET /countries

Усі країни в продажу: ISO-код, назва й код handler_api.php.

ПараметрОбов’язковийОпис
lang queryніМова назв: en (типово), ru, uk, zh, es, pt, id, vi, tr, ar, fr.
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/countries?lang=en"

Відповідь

{ "countries": [{ "id": "US", "name": "United States", "protocolCode": 187 }] }

GET /prices

Наші ціни в доларах і приблизна кількість номерів. Без параметрів — усе, що продається.

ПараметрОбов’язковийОпис
service queryніId сервісу з /services, наприклад telegram.
country queryніISO-код країни з /countries, наприклад US.
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/prices?service=telegram"

Відповідь

{ "prices": [{ "service": "telegram", "country": "US", "price": 0.59, "stock": 1000 }] }

Можливі помилки: unknown_service, unknown_country

POST /orders

Купити номер. Гроші списуються одразу й повертаються, якщо код не прийде.

ПараметрОбов’язковийОпис
service bodyтакId сервісу з /services, наприклад telegram.
country bodyтакISO-код країни з /countries, наприклад US.
maxPrice bodyніМаксимальна ціна в доларах, число. Дорожче — price_above_max з поточною ціною, нічого не списано.
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1f0e2a-run-1" \
  -d '{"service":"telegram","country":"US","maxPrice":0.8}' \
  https://relysms.pro/api/v1/orders

Відповідь

{
  "order": {
    "id": 1042,
    "service": "telegram",
    "country": "US",
    "phone": "15550001111",
    "price": 0.59,
    "status": "waiting",
    "refunded": false,
    "codes": [],
    "awaitingAnotherCode": false,
    "createdAt": "2026-10-27T10:00:00.000Z",
    "expiresAt": "2026-10-27T10:20:00.000Z",
    "cancelableAt": "2026-10-27T10:02:00.000Z"
  }
}

Можливі помилки: bad_request, unknown_service, unknown_country, no_numbers, insufficient_balance, below_api_minimum, price_above_max, too_many_open_orders, buying_too_fast, idempotency_key_reused, idempotency_in_progress

POST /orders/batch

Купити до 20 номерів одного сервісу й країни за один запит.

ПараметрОбов’язковийОпис
service bodyтакId сервісу з /services, наприклад telegram.
country bodyтакISO-код країни з /countries, наприклад US.
quantity bodyтакСкільки номерів, від 1 до 20.
maxPrice bodyніМаксимальна ціна в доларах, число. Дорожче — price_above_max з поточною ціною, нічого не списано.
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1f0e2a-batch-1" \
  -d '{"service":"telegram","country":"US","quantity":5}' \
  https://relysms.pro/api/v1/orders/batch

Відповідь

{
  "orders": [{ "id": 1043, "phone": "15550001112", … }, { "id": 1044, … }],
  "requested": 5,
  "placed": 2,
  "stoppedBy": { "code": "no_numbers", "message": "…" }
}

Можливі помилки: bad_request, unknown_service, unknown_country, no_numbers, insufficient_balance, below_api_minimum, price_above_max, too_many_open_orders, buying_too_fast, idempotency_key_reused, idempotency_in_progress

GET /orders

Ваші замовлення, спочатку нові: типово відкриті, або всі.

ПараметрОбов’язковийОпис
status queryніopen (типово) — чекають коду або з кодом; all — усі замовлення.
limit queryніЗамовлень на сторінці, від 1 до 100 (типово 50).
before queryніЗначення next з попередньої сторінки.
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/orders?status=all&limit=50"

Відповідь

{ "orders": [{ "id": 1042, … }], "next": "1001" }

Можливі помилки: bad_request

GET /orders/{id}

Одне замовлення з кодами. Поки статус waiting — опитуйте раз на 5–10 секунд.

ПараметрОбов’язковийОпис
id pathтакId замовлення з відповіді на покупку.
curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042

Відповідь

{
  "order": {
    "id": 1042,
    "status": "received",
    "codes": [{ "code": "48213", "text": "Telegram code: 48213", "receivedAt": "2026-10-27T10:01:12.000Z" }],
    …
  }
}

Можливі помилки: not_found

POST /orders/{id}/finish

Завершити замовлення з кодом. Нові SMS на номер не прийдуть. Повтор нешкідливий.

ПараметрОбов’язковийОпис
id pathтакId замовлення з відповіді на покупку.
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/finish

Відповідь

{ "order": { "id": 1042, "status": "finished", … } }

Можливі помилки: not_found, invalid_state

POST /orders/{id}/another-code

Ще один код на той самий номер — після першого коду, поки замовлення відкрите. Безкоштовно. До нового коду в замовленні awaitingAnotherCode = true.

ПараметрОбов’язковийОпис
id pathтакId замовлення з відповіді на покупку.
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/another-code

Відповідь

{ "order": { "id": 1042, "status": "received", "awaitingAnotherCode": true, … } }

Можливі помилки: not_found, invalid_state, try_later

POST /orders/{id}/cancel

Скасувати замовлення без коду — через 2 хвилини після покупки. Гроші повертаються одразу.

ПараметрОбов’язковийОпис
id pathтакId замовлення з відповіді на покупку.
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/cancel

Відповідь

{ "order": { "id": 1042, "status": "cancelled", "refunded": true, … } }

Можливі помилки: not_found, invalid_state, too_early_to_cancel

GET /webhook

Адреса вебхука й секрет підпису, або null.

curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook

Відповідь

{ "webhook": { "url": "https://example.com/relysms-hook", "secret": "whsec_…", "createdAt": "2026-10-27T10:00:00.000Z" } }

PUT /webhook

Задати чи змінити адресу. Секрет створюється один раз і зберігається; rotateSecret випускає новий.

ПараметрОбов’язковийОпис
url bodyтакHTTPS-адреса вашого сервера. Приватні й локальні адреси не приймаються.
rotateSecret bodyніtrue — випустити новий секрет підпису.
curl -X PUT -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/relysms-hook"}' \
  https://relysms.pro/api/v1/webhook

Відповідь

{ "webhook": { "url": "https://example.com/relysms-hook", "secret": "whsec_…", "createdAt": "2026-10-27T10:00:00.000Z" } }

Можливі помилки: bad_request, invalid_webhook_url

DELETE /webhook

Видалити вебхук. Ще не надіслані події відкидаються.

curl -X DELETE -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook

Відповідь

{ "webhook": null }

POST /webhook/test

Надіслати подію ping — перевірити адресу й підпис.

curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook/test

Відповідь

{ "delivery": { "id": "cm…" } }

Можливі помилки: not_found

GET /webhook/deliveries

Останні 20 доставок: подія, статус, спроби, остання відповідь вашого сервера.

curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook/deliveries

Відповідь

{
  "deliveries": [{
    "id": "cm…", "event": "order.code_received", "orderId": 1042,
    "status": "pending", "attempts": 2, "lastHttpStatus": 502, "lastError": "HTTP 502",
    "createdAt": "2026-10-27T10:01:12.000Z", "deliveredAt": null, "nextAttemptAt": "2026-10-27T10:02:22.000Z"
  }]
}

Статуси замовлення

Поле status замовлення:

  • waiting — Номер ваш, коду ще немає.
  • received — Код прийшов, він у codes. Поки замовлення відкрите, можуть прийти ще коди.
  • finished — Ви завершили замовлення (або після коду закінчився час).
  • cancelled — Скасоване без коду; refunded — true, гроші на балансі.
  • expired — Час вийшов без коду; гроші повернулися на баланс.

Помилки

Помилка — це HTTP-статус і JSON з полем code, за яким зручно розгалужуватися, і message для людей. Деякі мають додаткові поля (price, cancelableAt, apiMinimum).

{ "error": { "code": "price_above_max", "message": "The price is above maxPrice.", "price": 0.59 } }
missing_key401Немає ключа в Authorization чи X-Api-Key.
invalid_key401Ключ неправильний, замінений новим, або акаунт заблоковано.
bad_request400Помилка в тілі чи параметрі; у message сказано, де.
unknown_service400Немає сервісу з таким id.
unknown_country400Немає країни з таким кодом.
idempotency_key_invalid400Idempotency-Key порожній або довший за 255 символів.
invalid_webhook_url400Адреса вебхука не HTTPS, не адреса взагалі або веде на приватний чи локальний сервер.
insufficient_balance402На балансі менше за ціну номера.
below_api_minimum402На балансі менше $20 — API купує лише від $20.
account_blocked403Акаунт заблоковано — напишіть у підтримку.
not_found404Немає замовлення з таким id у цього ключа.
no_numbers409Номерів для цієї пари зараз немає; нічого не списано.
price_above_max409Ціна вища за maxPrice; поточна — в полі price.
too_many_open_orders409Забагато відкритих замовлень — завершіть або скасуйте частину.
invalid_state409У цьому статусі так не можна (наприклад, завершити без коду).
too_early_to_cancel409Скасувати можна з моменту cancelableAt — через 2 хвилини після покупки.
idempotency_in_progress409Запит з цим Idempotency-Key ще виконується; повторіть трохи згодом.
idempotency_key_reused422Цей Idempotency-Key уже використано для іншого запиту.
rate_limited429Понад 20 запитів за секунду; коли повторити — в Retry-After.
buying_too_fast429Понад 5 покупок за секунду; використовуйте /orders/batch.
try_later503Тимчасово не вдалося — повторіть за хвилину.

Приклади REST

Купити номер, дочекатися коду, завершити замовлення.

Python

import time, uuid, requests

BASE = "https://relysms.pro/api/v1"
S = requests.Session()
S.headers["Authorization"] = "Bearer rs_your_key"

r = S.post(f"{BASE}/orders",
           json={"service": "telegram", "country": "US", "maxPrice": 0.8},
           headers={"Idempotency-Key": str(uuid.uuid4())}, timeout=30)
if r.status_code != 201:
    raise SystemExit(r.json()["error"])   # no_numbers, below_api_minimum, …
order = r.json()["order"]
print("number:", order["phone"])

while order["status"] == "waiting":       # up to 20 minutes
    time.sleep(10)
    order = S.get(f"{BASE}/orders/{order['id']}", timeout=30).json()["order"]

if order["status"] == "received":
    print("code:", order["codes"][-1]["code"])
    S.post(f"{BASE}/orders/{order['id']}/finish", timeout=30)
# "expired" or "cancelled": the money is back on the balance

Node.js

const BASE = "https://relysms.pro/api/v1";
const headers = { Authorization: "Bearer rs_your_key", "Content-Type": "application/json" };

const res = await fetch(`${BASE}/orders`, {
  method: "POST",
  headers: { ...headers, "Idempotency-Key": crypto.randomUUID() },
  body: JSON.stringify({ service: "telegram", country: "US", maxPrice: 0.8 }),
});
if (res.status !== 201) throw new Error((await res.json()).error.code);
let { order } = await res.json();
console.log("number:", order.phone);

while (order.status === "waiting") {
  await new Promise((r) => setTimeout(r, 10_000));
  ({ order } = await (await fetch(`${BASE}/orders/${order.id}`, { headers })).json());
}
if (order.status === "received") {
  console.log("code:", order.codes.at(-1).code);
  await fetch(`${BASE}/orders/${order.id}/finish`, { method: "POST", headers });
}

Приклади

Повний цикл: купити номер, дочекатися коду, завершити замовлення.

curl

KEY=rs_your_key
BASE=https://relysms.pro/stubs/handler_api.php

curl "$BASE?api_key=$KEY&action=getBalance"
curl "$BASE?api_key=$KEY&action=getNumber&service=tg&country=187&maxPrice=0.80"
# → ACCESS_NUMBER:1042:15550001111
curl "$BASE?api_key=$KEY&action=getStatus&id=1042"
# → STATUS_WAIT_CODE … then STATUS_OK:48213
curl "$BASE?api_key=$KEY&action=setStatus&id=1042&status=6"

Python

import time, requests

BASE = "https://relysms.pro/stubs/handler_api.php"
KEY = "rs_your_key"

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

answer = call("getNumber", service="tg", country="187", maxPrice="0.80")
if not answer.startswith("ACCESS_NUMBER"):
    raise SystemExit(answer)          # NO_NUMBERS, NO_BALANCE, …
_, order_id, phone = answer.split(":")
print("number:", phone)

for _ in range(120):                  # up to 20 minutes, every 10 s
    status = call("getStatus", id=order_id)
    if status.startswith("STATUS_OK:"):
        print("code:", status.split(":", 1)[1])
        call("setStatus", id=order_id, status=6)
        break
    if status == "STATUS_CANCEL":
        break                         # refunded automatically
    time.sleep(10)

Node.js

const BASE = "https://relysms.pro/stubs/handler_api.php";
const KEY = "rs_your_key";

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

const answer = await call("getNumber", { service: "tg", country: "187", maxPrice: "0.80" });
if (!answer.startsWith("ACCESS_NUMBER")) throw new Error(answer);
const [, id, phone] = answer.split(":");
console.log("number:", phone);

for (let i = 0; i < 120; i++) {
  const status = await call("getStatus", { id });
  if (status.startsWith("STATUS_OK:")) {
    console.log("code:", status.slice("STATUS_OK:".length));
    await call("setStatus", { id, status: "6" });
    break;
  }
  if (status === "STATUS_CANCEL") break; // refunded automatically
  await new Promise((r) => setTimeout(r, 10_000));
}

Питання

Мій софт працював з іншим сервісом активацій. Що змінити?

Адресу сервера — на https://relysms.pro/stubs/handler_api.php, ключ — на ключ із кабінету. Коди сервісів і країн ті самі.

Чому NO_BALANCE, якщо гроші на балансі є?

Покупки через API працюють за балансу від $20. У кабінеті й Mini App такого порогу немає.

Що з грошима, якщо код не прийшов?

Повернуться на баланс самі, коли вікно закриється, або одразу — при скасуванні через 2 хвилини.

Можна отримати другий код на той самий номер?

Так, поки вікно відкрите: setStatus=3 і знову getStatus.

Є тестовий режим?

Ні: усі покупки справжні. Почніть із дешевої пари й перевірте потік на одному номері.

Ключ витік. Що робити?

Кабінет → «Баланс» → «API» → «Випустити новий». Старий перестає працювати одразу.

Для ШІ-асистентів

Повна документація одним текстом для ChatGPT, Claude та інших моделей — у /uk/developers.md, коротка карта — у /llms.txt. Дайте моделі посилання й попросіть підключити RelySMS до вашого коду.

Прочитай https://relysms.pro/uk/developers.md і підключи RelySMS до мого скрипта.

developers.md · llms.txt