Вебхуки
Получайте события активаций на свой сервер в реальном времени, проверяйте заголовок SmsGrab-Signature и разберитесь с повторами, тестовыми доставками и автоматическим отключением.
На этой странице
Вебхуки отправляют события на ваш сервер в момент, когда они происходят, поэтому опрашивать API не нужно. Вебхук принадлежит одному API-ключу. Он получает события номеров, купленных этим ключом, а также оповещения о низком балансе аккаунта.
События
| Событие | Когда |
|---|---|
activation.created |
Куплен номер |
activation.code_received |
Каждое новое SMS, со всеми сообщениями на данный момент |
activation.completed |
Завершён вами или по истечении времени после кода |
activation.cancelled |
Отменён до кода, деньги возвращены |
activation.expired |
Код не пришёл вовремя, деньги возвращены |
activation.refunded |
Любой возврат списания |
balance.low |
Баланс опустился ниже заданного вами порога |
webhook.test |
Тестовая доставка, запущенная вами |
Создание вебхука
В Аккаунт > Разработчикам откройте ключ и добавьте вебхук с URL, нужными событиями и необязательным описанием. У каждого ключа может быть до 3 вебхуков.
URL должен:
- начинаться с
https://; - использовать имя хоста, а не IP-адрес;
- вести на публичный адрес. Частные сети, localhost и похожие диапазоны отклоняются.
Вы получите секрет для подписи, начинающийся с whsec_. Как и API-ключ, он показывается только один раз. Позже его можно сменить, и это тоже потребует пароль.
Как выглядит доставка
POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: SmsGrab-Webhooks/1.0
SmsGrab-Event: activation.code_received
SmsGrab-Delivery: 9f7d6c1e-2b44-4c1a-8f0e-6a3d2c1b0e9f
SmsGrab-Signature: t=1790503200,v1=3b9a0c…
{ "id": "evt_4e1f…", "type": "activation.code_received", "created_at": "2026-09-27T10:06:12.004Z",
"api_version": "2026-09-27", "data": { "activation": { "id": "5c1d0c2e-…", "status": "CODE_RECEIVED" } } }
Проверка подписи
SmsGrab-Signature содержит метку времени t и v1 — HMAC-SHA256 от t, точки и необработанного тела запроса с вашим секретом в качестве ключа. Отклоняйте доставки, у которых метка времени расходится с вашими часами больше чем на 300 секунд, и сравнивайте подписи за постоянное время.
[$t, $v1] = (function (string $h): array {
parse_str(str_replace(',', '&', $h), $p);
return [(int) ($p['t'] ?? 0), (string) ($p['v1'] ?? '')];
})($_SERVER['HTTP_SMSGRAB_SIGNATURE'] ?? '');
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', $t.'.'.$body, getenv('SMSGRAB_WEBHOOK_SECRET'));
$ok = abs(time() - $t) <= 300 && hash_equals($expected, $v1);
import hmac, hashlib, time
def verify(header: str, body: bytes, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
return abs(time.time() - t) <= 300 and hmac.compare_digest(expected, parts.get("v1", ""))
import crypto from 'node:crypto';
export function verify(header, rawBody, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t ?? 0);
const expected = crypto.createHmac('sha256', secret).update(`${t}.`).update(rawBody).digest('hex');
const given = Buffer.from(parts.v1 ?? '', 'utf8');
return Math.abs(Date.now() / 1000 - t) <= 300 && given.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(expected, 'utf8'), given);
}
Всегда проверяйте необработанное тело ровно в том виде, в каком вы его получили, до разбора JSON.
Отвечайте быстро
Ответьте любым статусом 2xx в течение 10 секунд, а долгую обработку выполняйте потом, например в очереди. Перенаправления не выполняются.
Повторы
Неудачная доставка повторяется через 1 минуту, 5 минут, 15 минут, 1 час, 3 часа, 6 часов, 12 часов и 24 часа. Повтор содержит тот же id события, поэтому запоминайте обработанные идентификаторы и пропускайте дубликаты. События одной активации приходят по порядку.
Автоматическое отключение
- Ответ
410 Goneсразу отключает вебхук. - После 50 неудачных попыток подряд на протяжении не менее 24 часов вебхук отключается, и вы получаете уведомление. Исправьте эндпоинт, а затем снова включите вебхук.
- Отзыв ключа отключает его вебхуки.
Тест и повторная доставка
Отправьте событие webhook.test со страницы вебхука, чтобы сразу увидеть код статуса, время ответа и возможную ошибку. Список доставок хранит каждую доставку 30 дней, и любую из них можно отправить повторно.
Эта статья была полезной?
Спасибо! Рады, что помогло.