Skip to content
Język: Polski

API dla programistów

Webhooki: zdarzenia, payload i podpis

Zaktualizowano 1 listopada 2026 6 min czytania

Skonfiguruj webhooki w panelu, odbieraj dostarczenia i weryfikuj podpis HMAC – z przykładami dla curl, Node.js i PHP.

Webhook wysyła żądanie HTTP do Twojego serwera, gdy tylko coś się wydarzy w Twoim workspace – na przykład gdy strona zostanie opublikowana. Dzięki temu nie musisz ciągle sprawdzać, czy coś się zmieniło. Każde dostarczenie jest podpisane, aby Twój serwer mógł odróżnić prawdziwe wiadomości od podrobionych.

Wymagania

  • Rola właściciela lub admina w workspace – pozycja menu „Webhooki” pojawia się tylko dla tych ról
  • Od planu Creator Pro; w Creator Free widać komunikat „Webhooki są dostępne od planu Creator Pro.”
  • Do 5 webhooków w Creator Pro, 25 w Creator Agency, 100 w Enterprise (można dostosować)
  • Serwer dostępny pod publicznym adresem https

Webhookami zarządzasz tylko w panelu. Nie można ich tworzyć ani zmieniać za pomocą kluczy API.

Tworzenie webhooka

Strona „Webhooki” bez webhooków z przyciskiem „+ Nowy webhook”
Strona „Webhooki” w workspace
  1. Otwórz „Webhooki” w nawigacji
  2. Kliknij „+ Nowy webhook”
  3. Wpisz docelowy URL i wybierz zdarzenia
  4. Opcjonalnie: wpisz opis i wybierz status
  5. Kliknij „Utwórz webhook”
  6. W kroku „Gotowe” skopiuj sekret podpisu („Sekret podpisu – widoczny tylko teraz”) i zapisz go na swoim serwerze – jest pokazywany tylko w tym momencie
  7. Przetestuj webhook przyciskiem „Test”. Wynik zostaje na karcie do następnego testu: „Dostarczono” albo „Nie dostarczono” z kodem HTTP (lub „brak odpowiedzi”), czasem trwania i początkiem odpowiedzi
„Docelowy URL (https://…)”
Do 2048 znaków. Tylko https, bez danych logowania w URL, bez adresów localhost i bez nazw wewnętrznych, takich jak .local, .internal czy .lan. Nazwa musi wskazywać na publiczne adresy IP; LinkHarbor sprawdza to ponownie przed każdym dostarczeniem.
„Zdarzenia”
Co najmniej jedno zdarzenie. Każda grupa ma opcje „Zaznacz wszystko” i „Odznacz wszystko”.
„Opis”
Opcjonalny, do 255 znaków – na przykład do czego służy webhook.
„Status”
„Aktywny” lub „Wyłączony”. Wyłączone webhooki nie otrzymują dostarczeń.

Zdarzenia

ZdarzenieW paneluKiedyZawartość data
page.publishedStrona opublikowanaStrona została opublikowana – w panelu, przez API lub przez asystenta AIpage_id, version, checksum, published_by_user_id (null dla kluczy API i asystentów AI)
form.submittedFormularz wysłanyOdwiedzający wysłał formularz na jednej z Twoich stronform_id, form_name, submission_id, page_id, block_id, submitted_at, values (klucz pola → wartość), consent (klucz zgody → true/false)
domain.verifiedDomena zweryfikowanaWłasna domena została pomyślnie zweryfikowanadomain_id, hostname, verification_method, status
domain.disabledDomena wyłączonaWłasna domena została wyłączona w panelu (nie przy przejściu na niższy plan)domain_id, hostname, status
webhook.test– (przycisk „Test”)Klikasz „Test”message (informacja w języku konta osoby, która uruchamia test; nie porównuj z nią w kodzie)

form.submitted zawiera wartości dokładnie tak, jak wysłał je odwiedzający, ale nigdy jego adresu IP ani przeglądarki. Dostarczenie odbywa się w tle: odwiedzający na nie nie czeka, a nieudane dostarczenie nie blokuje zgłoszenia.

Budowa dostarczenia

LinkHarbor wysyła każde dostarczenie jako POST z treścią JSON i tymi nagłówkami:

NagłówekZawartość
Content-Typeapplication/json
X-LinkHarbor-EventNazwa zdarzenia, na przykład page.published
X-LinkHarbor-Delivery-IdUnikalne ID tego dostarczenia (UUID), identyczne z id w treści
X-LinkHarbor-TimestampCzas wysłania w sekundach Unix
X-LinkHarbor-Signaturesha256=, a po nim podpis HMAC-SHA256 w hex
X-LinkHarbor-Signature-Versionv1
Przykładowy payload dla page.published
{
  "id": "3f1c2a9e-8d4b-4a51-9f0e-6b7c1d2e3f40",
  "event": "page.published",
  "created_at": "2026-11-01T09:30:12+00:00",
  "data": {
    "page_id": 42,
    "version": 8,
    "checksum": "9b1e5c…",
    "published_by_user_id": 7
  }
}

Ponowne dostarczenia dostają nowe id oraz pola redelivery_of (ID powtarzanego dostarczenia) i delivery_root (ID pierwszego dostarczenia w tym łańcuchu).

Weryfikacja podpisu

Każdy webhook ma własny sekret podpisu (32 znaki hex). Widzisz go dokładnie raz: w ostatnim kroku tworzenia webhooka i zaraz po „Sekret ↺”. Od razu skopiuj go na swój serwer – LinkHarbor nie pokaże go później ponownie. LinkHarbor oblicza z jego pomocą podpis w ten sposób:

  1. Budowanie wiadomości: znacznik czasu, kropka, ID dostarczenia, kropka, surowa treść – czyli timestamp.delivery_id.body
  2. Obliczenie HMAC-SHA256 tej wiadomości z sekretem podpisu jako kluczem
  3. Wysłanie wyniku jako ciągu hex z prefiksem sha256=

Twój serwer powinien sprawdzać podpis porównaniem w stałym czasie, odrzucać dostarczenia ze znacznikiem czasu starszym niż 300 sekund i przechowywać ID dostarczeń co najmniej przez ten czas, aby rozpoznawać powtórzenia. Ważne: podpisywana jest surowa treść, dokładnie taka, jaka przychodzi – a nie JSON zakodowany przez Ciebie ponownie.

Node.js (Express): odbieranie i weryfikacja webhooka
import crypto from 'node:crypto';
import express from 'express';

const app = express();
const SECRET = process.env.LH_WEBHOOK_SECRET;
const seen = new Set(); // w produkcji: baza danych lub Redis z wygasaniem

app.post('/webhooks/linkharbor', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-LinkHarbor-Timestamp') || '';
  const id = req.get('X-LinkHarbor-Delivery-Id') || '';
  const sig = req.get('X-LinkHarbor-Signature') || '';

  if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
    return res.status(400).send('timestamp');
  }

  const expected = 'sha256=' + crypto
    .createHmac('sha256', SECRET)
    .update(ts + '.' + id + '.')
    .update(req.body) // surowa treść jako Buffer
    .digest('hex');

  const a = Buffer.from(expected);
  const b = Buffer.from(sig);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return res.status(401).send('signature');
  }

  const event = JSON.parse(req.body.toString('utf8'));
  const key = event.delivery_root || event.id; // rozpoznawanie ponownych dostarczeń z tego samego łańcucha
  if (!seen.has(key)) {
    seen.add(key);
    // tutaj przetwarzanie, najlepiej asynchronicznie w kolejce
  }
  res.sendStatus(200);
});

app.listen(3000);
PHP: odbieranie i weryfikacja webhooka
<?php
$secret = getenv('LH_WEBHOOK_SECRET');
$body   = file_get_contents('php://input');
$ts     = $_SERVER['HTTP_X_LINKHARBOR_TIMESTAMP'] ?? '';
$id     = $_SERVER['HTTP_X_LINKHARBOR_DELIVERY_ID'] ?? '';
$sig    = $_SERVER['HTTP_X_LINKHARBOR_SIGNATURE'] ?? '';

if (!ctype_digit($ts) || abs(time() - (int)$ts) > 300) {
    http_response_code(400);
    exit('timestamp');
}

$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $id . '.' . $body, $secret);
if (!hash_equals($expected, $sig)) {
    http_response_code(401);
    exit('signature');
}

$event = json_decode($body, true);
// Rozpoznaj zduplikowane dostarczenia po $event['delivery_root'] ?? $event['id'],
// a potem przetwórz.
http_response_code(200);

Testowanie endpointu przez curl

Ten skrypt wysyła poprawnie podpisane dostarczenie testowe do Twojego serwera – przydatne, zanim utworzysz webhook w LinkHarbor:

Symulacja podpisanego dostarczenia testowego
SECRET="your-signing-secret"
URL="https://example.com/webhooks/linkharbor"
TS=$(date +%s)
ID=$(uuidgen | tr 'A-Z' 'a-z')
BODY='{"id":"'"$ID"'","event":"webhook.test","created_at":"2026-11-01T09:30:12+00:00","data":{"message":"To jest zdarzenie testowe dla tego webhooka."}}'
SIG="sha256=$(printf '%s' "$TS.$ID.$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')"

curl -X POST "$URL" \
  -H "Content-Type: application/json" \
  -H "X-LinkHarbor-Event: webhook.test" \
  -H "X-LinkHarbor-Delivery-Id: $ID" \
  -H "X-LinkHarbor-Timestamp: $TS" \
  -H "X-LinkHarbor-Signature: $SIG" \
  -H "X-LinkHarbor-Signature-Version: v1" \
  -d "$BODY"

Odpowiedź, limit czasu i ponowne dostarczenie

  • Każda odpowiedź ze statusem 2xx liczy się jako sukces; przekierowania (3xx) nie są wykonywane
  • Twój serwer ma 10 sekund na odpowiedź i najwyżej 5 sekund na nawiązanie połączenia
  • Wszystkie webhooki dla jednego zdarzenia mają łącznie 25 sekund; te, na które do tego czasu nie przyszła kolej, są oznaczane jako nieudane i można je dostarczyć ponownie
  • LinkHarbor nie ponawia nieudanych dostarczeń automatycznie
  • Nieudane dostarczenia możesz wysłać ponownie ręcznie, ale nie takie, które w międzyczasie się powiodło. Ponowne dostarczenie ma nowe id i nowe created_at
  • Na jedno zdarzenie dozwolone są najwyżej 3 próby, wliczając pierwsze dostarczenie; potem trafia ono do zakładki „Dead letters” i nie można go już wysłać ponownie

Dostarczenia w panelu

„Dostarczenia” otwiera dziennik webhooka. Ma on trzy zakładki:

„Wszystkie dostarczenia”
Wszystkie dostarczenia z filtrami zdarzenia, statusu („Sukces (2xx)”, „Błąd klienta (4xx)”, „Błąd serwera (5xx)”, „Nieudane”) i „Limit”. „↺ Ponów” dostarcza nieudane dostarczenie ponownie, o ile nie ma późniejszego udanego. Kliknięcie wiersza pokazuje żądanie, odpowiedź, treść i surowy JSON.
„Powtórki”
Łańcuchy ponownych dostarczeń z wynikiem „Naprawione” lub „Nadal nie działa” i liczbą prób.
„Dead letters”
Dostarczenia, w których nie powiodły się wszystkie dozwolone próby – pierwsze dostarczenie i ponowne razem. Zakładka służy tylko do podglądu: tych dostarczeń nie można już wysłać ponownie. Sprawdź swój endpoint; potem nowe zdarzenia są dostarczane normalnie. Jeśli potrzebujesz tych danych, pobierz je przez API.

Jeśli ponowne dostarczenie się nie uda, panel podaje powód:

„Nie dostarczono ponownie: to zdarzenie nie powiodło się już … razy, kolejne próby nie są możliwe. Znajdziesz je w zakładce «Dead letters».”
Wykorzystano wszystkie 3 próby.
„Nie dostarczono ponownie: to zdarzenie zostało w międzyczasie dostarczone.”
Późniejsze dostarczenie w tym samym łańcuchu już się powiodło.

Weryfikacja w panelu

W sekcji „Weryfikacja” znajdziesz dwie pomoce:

„Zestaw weryfikacyjny”
„Załaduj zestaw” pokazuje algorytm, nazwy nagłówków, format podpisywanej wiadomości i zalecaną tolerancję 300 sekund. Sam sekret nie jest w nim zawarty.
„Zweryfikuj podpis”
Wpisz ID dostarczenia, znacznik czasu, podpis i surową treść żądania otrzymanego dostarczenia. LinkHarbor odpowie wtedy „Podpis prawidłowy” lub „Podpis nieprawidłowy”. Znacznik czasu i podpis skopiuj z nagłówków X-LinkHarbor-Timestamp i X-LinkHarbor-Signature. Sprawdzenie działa tylko dla dostarczeń z ostatnich 5 minut; dla starszych zgłasza „Podpis nieprawidłowy”, nawet jeśli podpis jest poprawny.

Zmiana sekretu, wyłączanie, usuwanie

  • „Sekret ↺” generuje nowy sekret podpisu i pokazuje go raz; stary od razu przestaje działać, a Twój serwer musi używać nowego
  • W „Edytuj” ustaw status „Wyłączony”, aby wstrzymać dostarczenia
  • Ikona kosza usuwa webhook; dopóki nie zamkniesz komunikatu, możesz to cofnąć przyciskiem „Cofnij”

Gdy przechodzisz na mniejszy plan, webhooki ponad nowy limit zostają wyłączone, a w Creator Free wszystkie. Pozostają jednak zachowane; po zmianie planu na wyższy LinkHarbor automatycznie włącza wyłączone webhooki do limitu nowego planu – także te, które wyłączono ręcznie.

Nic nie znaleziono?

Napisz, czego potrzebujesz, a nasz zespół pomocy technicznej pomoże Ci osobiście.

Skontaktuj się z pomocą