Перейти к содержанию
Версия контракта: 0.3.3 — спека

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

От нуля до доставленного сообщения — пять минут и один curl.

1. Ключ

Тестовый ключ выдаёт оператор хаба. Он выглядит так:

nbh_test_01k4m2p7q9wz_8f3a1c5e7b9d2f4a6c8e0b1d3f5a7c9e

Значение показывается один раз: в базе лежит только его хеш. Потеряли — выпускается новый, старый отзывается.

2. Отправка

curl -sS -X POST https://api.sms.termdev.ru/v1/messages \
  -H "Authorization: Bearer nbh_test_01k4m2p7q9wz_8f3a1c5e7b9d2f4a6c8e0b1d3f5a7c9e" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+79000000001",
    "class": "otp",
    "template": "otp-login",
    "variables": {"code": "482913"}
  }'

Ответ — 202 и объект сообщения:

{
  "object": "message",
  "id": "msg_01K4M2P7Q9WZ8F3A1C5E7B9D2F",
  "status": "accepted",
  "final": false,
  "to": "+7900***0001",
  "class": "otp",
  "created_at": "2026-09-10T04:12:33.481Z"
}

202 — это не доставка. Хаб принял сообщение и отвечает за него дальше; доставка придёт отдельно.

Три вещи в запросе обязательны и стоят объяснения:

  • template — отправка идёт по шаблону, свободного текста нет. Шаблон заводится заранее и проходит модерацию у оператора;
  • class — класс трафика: otp для одноразовых кодов, service для сервисных сообщений. От него зависят сроки жизни, лимиты и то, действует ли отписка;
  • Idempotency-Key — UUID на попытку отправки. Обрыв связи посреди запроса иначе означает выбор между вторым сообщением живому человеку и кодом, который он не получил. См. Идемпотентность.

3. Что дальше с сообщением

curl -sS https://api.sms.termdev.ru/v1/messages/msg_01K4M2P7Q9WZ8F3A1C5E7B9D2F \
  -H "Authorization: Bearer $HUB_KEY"

Через пару секунд status станет delivered, а final — true. Полная модель статусов и что делать с каждым — Статусы и их проверка.

Опрашивать статус в цикле не нужно: подпишитесь на вебхуки, и события приедут сами. Опрос — способ догнать пропущенное, а не основной путь.

4. Проверить, что у вас за ключ

curl -sS https://api.sms.termdev.ru/v1/account -H "Authorization: Bearer $HUB_KEY"

Ручка отвечает режимом (live или test), действующими лимитами и, в боевом режиме, пределом расхода. Числа в ней — правда для вашего аккаунта; в руководстве стоят умолчания.

PHP

$response = $client->post('https://api.sms.termdev.ru/v1/messages', [
    'headers' => [
        'Authorization'   => 'Bearer ' . config('smshub.key'),
        'Idempotency-Key' => (string) Str::uuid(),
    ],
    'json' => [
        'to'        => '+79000000001',
        'class'     => 'otp',
        'template'  => 'otp-login',
        'variables' => ['code' => $code],
    ],
]);

$message = json_decode((string) $response->getBody(), true);
// $message['id'] — сохраните его: по нему приедут вебхуки

client_ref в запросе — ваш собственный идентификатор записи. Он не обязателен для одиночной отправки, но с ним повтор запроса не создаст второго сообщения, даже если ключ идемпотентности потерялся.

Куда дальше

  • Песочница — магические номера: доставка, недоставка, молчащий оператор, анти-флуд;
  • Вебхуки — как получать события и проверять подпись;
  • Ошибки — что означает отказ и что повторять;
  • Ограничения MVP — чего хаб пока не умеет.