Быстрый старт¶
От нуля до доставленного сообщения — пять минут и один 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 — чего хаб пока не умеет.