Повтори та збої
Якщо приймач не відповів 2xx, доставка повторюється за фіксованим розкладом. Якщо він не відповідає майже добу — вебхук вимикається, а власнику надходить лист.
Розклад повторів
| Спроба | Коли |
|---|---|
| 1 | одразу після події |
| 2 | +5 секунд |
| 3 | +5 хвилин |
| 4 | +30 хвилин |
| 5 | +2 години |
| 6 | +5 годин |
| 7 | +10 годин |
| 8 | +10 годин |
Загалом 8 спроб за ~28 годин. До кожної паузи додається випадковий джитер ±10 %: без нього тисяча подій однієї транзакції била б у ваш сервер синхронно — саме тоді, коли йому й так важко.
Диспетчер прокидається раз на хвилину. Одиночна зміна доїжджає в межах хвилини, масова операція (застосування чернетки, видалення працівника назавжди) — пачкою, у межах ~15 хвилин: за один захід у чергу з одного ендпоінта береться не більше ніж 50 доставок, щоб один галасливий приймач не зайняв усю партію. Заходів у хвилинному тику декілька — партія за партією, доки вистачає бюджету тика (50 секунд).
Номер поточної спроби видно в заголовку Smengo-Delivery-Id — після двокрапки.
Класифікація відповіді
| Відповідь приймача | Що робимо |
|---|---|
2xx |
успіх, тіло відповіді ігнорується |
3xx |
збій redirect_not_allowed: редиректи не переходимо — адресу має обслуговувати кінцевий сервер |
410 Gone |
термінально: доставка позначається мертвою, ендпоінт одразу вимикається |
429, 5xx |
збій із повтором; враховується заголовок Retry-After |
інші 4xx |
збій із повтором |
| немає відповіді за 15 секунд | збій timeout із повтором |
| мережа, TLS, DNS | збій із повтором (network_…, dns_failed) |
| адреса резолвиться у приватну мережу | збій private_address — запит не надсилається взагалі |
Retry-After
Заголовок розуміється в обох формах RFC 9110 — секунди та HTTP-дата — і застосовується як max(розклад, Retry-After) з капом в 1 годину. Два наслідки:
- сервер може відкласти наступну спробу, але не може її прискорити:
Retry-After: 0не перетворює повтори на гарячий цикл; - далі години відкласти не можна — інакше вичерпання спроб розтяглося б на тижні.
Авто-вимкнення
Тригер — перша доставка, що вичерпала всі 8 спроб (або відповідь 410 Gone). Тоді:
- Ендпоінт переводиться у стан «вимкнений» — доставки припиняються.
- Усі накопичені доставки цього ендпоінта позначаються мертвими і не будуть надіслані після ввімкнення: інакше на полагоджений сервер обрушився б 28-годинний беклог.
- Власнику надходить лист (на платіжну адресу організації, інакше — на адресу творця ендпоінта).
- У картці вебхука з'являється банер із причиною — його видно й без листа.
Як повернути доставку: полагодьте приймач → «Надіслати тестову» → переконайтеся, що надійшов 2xx → увімкніть вебхук назад. Пропущене за час вимкнення дочитується через API v1 — ручного повтору доставок у v1 немає.
Пауза, а не вимкнення
Кнопка «Пауза» — не те саме, що авто-вимкнення:
- поки вебхук на паузі, нові події в чергу не потрапляють взагалі — після відновлення ви отримаєте лише те, що станеться далі;
- доставки, які вже стояли в черзі на момент паузи, поїдуть після відновлення;
- тестову подію можна надіслати й на паузі — це штатний спосіб перевірити полагодження.
Неактивна підписка
Якщо в організації скінчився тріал і підписка неактивна, push зупиняється разом із рештою платного функціоналу: доставка відкладається на годину й повторюється, спроба при цьому не витрачається, ендпоінт не вимикається. Після оплати доставки відновляться самі, у межах години. У журналі такі рядки позначені subscription_inactive.
Журнал доставок
- Зберігається 30 днів, разом із тілом події — рівно тим, що пішло на вашу адресу.
- Нижче карток, у блоці «Останні доставки», видно 25 останніх доставок за всіма вебхуками організації: час, тип події, код відповіді, кількість спроб, тіло та історію спроб. Ліміт спільний: якщо ендпоінтів три, це 25 рядків на всіх, а не по 25 на кожен.
- З відповіді зберігаються перші 512 байтів — цього достатньо, щоб побачити текст помилки вашого сервера.
Коди в колонці «помилка»
| Код | Значення |
|---|---|
http_<код> |
сервер відповів не-2xx (наприклад, http_500) |
redirect_not_allowed |
відповідь 3xx; редиректи не підтримуються |
gone |
відповідь 410; ендпоінт вимкнено |
timeout |
відповіді не було 15 секунд |
network_<код> |
мережева помилка Node (network_ECONNREFUSED, network_EPROTO, …) |
dns_failed |
ім'я хоста не розв'язалося за відведений час |
private_address |
адреса резолвиться у приватний або службовий діапазон |
not_https, port_not_allowed, userinfo_not_allowed, fragment_not_allowed, invalid_url, url_too_long, url_too_short |
адреса не пройшла перевірку форми перед надсиланням |
subscription_inactive |
підписка організації неактивна, доставку відкладено на годину |
endpoint_disabled |
доставку погашено під час авто-вимкнення ендпоінта |
lease_expired |
доставка зависла (збій інвокації) і була підібрана службовим процесом |
Як не потрапити на повтори
- Відповідайте
2xxдо важкої роботи: прийміть подію, перевірте підпис, покладіть у чергу, відповідайте200. - Не відповідайте
3xx: балансувальник, який редиректитьhttp→httpsабо/hook→/hook/, ламає доставку. Вказуйте кінцеву адресу. - Повертайте
410лише коли адреса мертва остаточно: цей код вимикає вебхук з першого разу. - За тимчасового перевантаження відповідайте
429або503ізRetry-After— так ви керуєте темпом, не втрачаючи подій.
Далі
- Огляд — формат доставки та вимоги до приймача.
- Перевірка підпису — готові приклади на Node і Python.