dokumentacja · dla deweloperów
Webhooki
Powiadomienia push o tym, co interesuje Twoje systemy: zakończony skan, nowy tracker, opublikowana wersja, ukończony eksport dowodów. Podpisane, powtarzane i możliwe do podejrzenia.
Endpointy
Twórz endpointy w Ustawienia workspace’u → Deweloperzy → Webhooki lub przez API. Akceptowane są tylko adresy https na publicznych hostach; adresy prywatne i wewnętrzne są odrzucane przy rejestracji. Sekret podpisu (whsec_…) jest pokazywany raz przy tworzeniu i można go rotować w każdej chwili; po rotacji weryfikuj względem obu sekretów, dopóki Twój deploy nie nadrobi.
Zdarzenia
Dwanaście typów zdarzeń, subskrybowanych pojedynczo lub przez *:
scan.completed · scan.failed · tracker.new · issue.opened · issue.resolved · alert.raised · config.published · version.promoted · export.completed · declaration.updated · install.broken · plan.changed
Weryfikacja dostarczenia
Dostarczenia są zgodne z konwencją Standard Webhooks. Z każdym POST przychodzą trzy nagłówki:
webhook-id: <delivery id>
webhook-timestamp: <unix seconds>
webhook-signature: v1,<base64(hmac_sha256(key, id.timestamp.body))>
Klucz HMAC to część base64 Twojego sekretu whsec_, zdekodowana do surowych bajtów. Przelicz podpis nad id + "." + timestamp + "." + body, porównaj w stałym czasie i odrzuć wszystko starsze niż pięć minut:
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(secret, headers, rawBody) {
const key = Buffer.from(secret.slice('whsec_'.length), 'base64');
const msg = headers['webhook-id'] + '.' + headers['webhook-timestamp'] + '.' + rawBody;
const want = createHmac('sha256', key).update(msg).digest();
const got = Buffer.from(headers['webhook-signature'].split(',')[1], 'base64');
const fresh = Math.abs(Date.now() / 1000 - Number(headers['webhook-timestamp'])) < 300;
return fresh && want.length === got.length && timingSafeEqual(want, got);
}
Ponowne próby i ponowne dostarczanie
Nieudane dostarczenie jest powtarzane z backoffem: 1 minuta, potem 5 minut, 30 minut, 2 godziny, 6 godzin; potem jest oznaczane jako martwe. Każda próba, kod odpowiedzi i następna próba są widoczne w dzienniku dostarczeń endpointu, a każde dostarczenie można wysłać ponownie ręcznie; ponowne dostarczenie odwołuje się do oryginału. Historia dostarczeń jest przechowywana 90 dni.
Odpowiadanie
Odpowiadaj szybko dowolnym 2xx i wykonuj właściwą pracę asynchronicznie; wszystko inne liczy się jako błąd i planuje ponowną próbę. Dostarczenia mogą przychodzić w złej kolejności i, rzadko, więcej niż raz; użyj webhook-id dla idempotencji.