Webhooki: subskrybuj zdarzenia linków i workspace

Wysyłaj podpisane żądania HTTP POST z Elido do swojego serwera, gdy zmieniają się linki, domeny, członkowie lub workspace. Nagłówki, ładunki, ponowne próby dostarczenia, log dostarczania i rotacja sekretu.

8 min czytaniaZaktualizowano 2026-09-22

Co skonfigurujesz

  • Endpoint odbierający zdarzenia Elido, takie jak link.created, link.updated, link.deleted, member.invited i domain.verified.
  • Weryfikację HMAC-SHA256 nagłówka X-Elido-Signature, dzięki której Twój serwer może potwierdzić, że każde dostarczenie pochodzi z Elido.
  • Trzy próby dostarczenia każdego zdarzenia, log dostarczania z ręcznym przyciskiem **Retry** oraz rotację sekretu z 7-dniowym okresem nakładania się kluczy.

Webhooki przesyłają zdarzenia z Elido do Twojego serwera w chwili ich wystąpienia, więc nie musisz odpytywać API. Typowe zastosowania to synchronizowanie metadanych linków z CRM, aktualizowanie wewnętrznego indeksu linków albo uruchamianie zadania po opublikowaniu linku.

Webhooki obejmują zmiany linków, domen, członków i workspace. Nie zawierają pojedynczych kliknięć. Aby uzyskać dane o kliknięciach, użyj eksportu kliknięć albo integracji zdarzeń, takiej jak Mixpanel. Zdarzenia webhook dla pojedynczych kliknięć są planowane.

Dodaj endpoint webhooka

  1. Przejdź do Dashboard → Webhooks.
  2. Wpisz URL, na który mamy wysyłać żądania POST, oraz opcjonalny opis.
  3. Wybierz typ endpointu: Events (wybierasz typy zdarzeń) albo SIEM (firehose) (każde zdarzenie w workspace).
  4. W przypadku endpointu Events zaznacz wybrane typy zdarzeń. Zdarzenia link.* są domyślnie zaznaczone.
  5. Kliknij Add endpoint. Sekret podpisywania pojawi się raz, bezpośrednio pod formularzem. Skopiuj go teraz: Elido nie pokaże go ponownie.

URL musi być adresem HTTPS. Zwykłe http:// jest odrzucane podczas zapisywania endpointu, z wyjątkiem localhost i 127.0.0.1, które pozostają dozwolone na potrzeby lokalnego programowania.

Endpoint możesz wstrzymywać i wznawiać z poziomu listy. Wstrzymany endpoint nie otrzymuje nowych dostarczeń, a wszystko, co nadal znajduje się dla niego w kolejce, czeka, aż go wznowisz.

Kto może zarządzać webhookami

Każdy członek workspace może wyświetlać endpointy i log dostarczania. Tworzenie, edytowanie, wstrzymywanie, usuwanie, rotowanie sekretu i ponawianie dostarczenia wymagają uprawnienia workspace.edit, które mają wbudowane role Admin i Owner. Klucz API może wywoływać te same endpointy webhooków API, jeśli jego rola ma to uprawnienie.

Typy endpointów

  • Events (event): otrzymuje tylko zasubskrybowane typy zdarzeń. Podpisywany.
  • SIEM (siem): otrzymuje każde zdarzenie opublikowane w workspace, w tym audit.event dla każdego wpisu w logu audytu. Podpisywany. Przeznaczony do potoków logów i narzędzi bezpieczeństwa.
  • Discord, Telegram i Sentry: kanały czatu i alertów, które korzystają z tego samego systemu dostarczania, ale wysyłają własny format wiadomości dostawcy. Uwierzytelniają się przez URL dostawcy lub token, więc nie zawierają nagłówków podpisu. Zobacz strony Discord, Telegram i Sentry.

Wszystko poniżej o podpisach i sekretach dotyczy wyłącznie endpointów Events i SIEM.

Katalog zdarzeń

Nazwy mają format <resource>.<action>. Formularz w dashboardzie udostępnia najczęściej używane typy, ale przez API możesz zasubskrybować endpoint Events do dowolnego typu z tej listy, a endpoint SIEM otrzymuje wszystkie typy.

W selektorze dashboardu:

  • link.created: utworzono krótki link, w tym link utworzony zbiorczo.
  • link.updated: link został zmieniony (cel, tytuł, tagi, wygaśnięcie itd.), przywrócony, zmienił status albo jego status bezpieczeństwa został zmieniony przez moderację.
  • link.deleted: link został miękko usunięty.
  • workspace.updated: zmieniono ustawienia workspace.
  • workspace.created: publikowane po utworzeniu workspace. Ponieważ endpoint nie może istnieć w workspace przed jego utworzeniem, zwykle nie otrzymasz tego zdarzenia.
  • member.invited: ktoś dołączył do workspace przez bezpośrednie dodanie, zaakceptowanie zaproszenia albo provisioning SCIM.
  • member.removed: członek został usunięty ręcznie albo przez SCIM.
  • audit.event: jedno zdarzenie dla każdego wpisu w logu audytu.

Dostępne przez API lub endpoint SIEM:

  • link.expired: minął termin wygaśnięcia linku.
  • link.cap_reached: link osiągnął limit kliknięć. data zawiera cap i clicks.
  • link.broken: kontrola kondycji linku Elido wykryła, że cel nie działa. data zawiera status_code, error_message i first_seen_at.
  • link.encrypted_created i link.encryption_rotated: dotyczą zaszyfrowanych linków.
  • domain.verified: niestandardowa domena pomyślnie przeszła kontrolę DNS.
  • domain.ssl_failed: rekordów DNS niestandardowej domeny nadal nie znaleziono 24 godziny po jej dodaniu. Mimo nazwy dotyczy to weryfikacji DNS, a nie odnowienia certyfikatu.
  • member.role_changed: zmieniła się rola członka. data zawiera old_role, new_role i changed_by_user_id.
  • invitation.created i invitation.accepted.
  • Zdarzenia rozliczeniowe: subscription.* (na przykład subscription.activated, subscription.renewed, subscription.canceled) oraz usage.threshold_80, usage.threshold_100.

Planowane, obecnie niewysyłane: link.clicked.aggregated (liczba kliknięć na link w danym oknie), zdarzenia pojedynczych kliknięć, conversion.recorded, domain.tls_renewed, qr.generated oraz osobne zdarzenie abuse.flagged. Decyzja moderacyjna dotycząca linku obecnie przychodzi jako link.updated z nową wartością abuse_status.

Struktura ładunku

Każde podpisane dostarczenie jest żądaniem POST z Content-Type: application/json, User-Agent: Elido-Webhooks/1.0 i następującą kopertą:

{
  "type": "link.created",
  "workspace_id": 4123,
  "timestamp": "2026-09-22T09:42:11Z",
  "data": {
    "id": 891234,
    "workspace_id": 4123,
    "domain_id": 12,
    "slug": "spring-2026",
    "destination_url": "https://acme.com/spring-sale",
    "title": "Spring sale",
    "tags": ["email"],
    "status": "active",
    "expires_at": null,
    "created_by_user_id": 5821,
    "created_at": "2026-09-22T09:42:11Z"
  }
}
  • type to typ zdarzenia. Znajduje się także w nagłówku X-Webhook-Event.
  • timestamp to moment wystąpienia zdarzenia w UTC.
  • data zależy od zdarzenia. W przypadku zdarzeń link.* jest to pełny obiekt linku (powyższy przykład jest skrócony). Dla pozostałych zdarzeń jest to mały obiekt z identyfikatorami i polami wymienionymi w katalogu.
  • Sekrety nigdy nie opuszczają Elido: pola takie jak hash hasła linku albo token zaproszenia są usuwane z data przed dostarczeniem.

W treści nie ma jeszcze pola id zdarzenia; ID poszczególnych zdarzeń jest planowane. Aby zapewnić idempotencję, użyj nagłówka X-Webhook-Delivery, opisanego poniżej.

Nagłówki i podpisy

Każde dostarczenie do endpointu Events lub SIEM zawiera:

NagłówekWartość
X-Elido-Signaturev1=, a następnie szesnastkowy podpis HMAC-SHA256
X-Webhook-SignatureTa sama wartość co X-Elido-Signature, zachowana dla starszych integracji
X-Webhook-TimestampCzas uniksowy w sekundach, w którym podpisano to żądanie
X-Webhook-EventTyp zdarzenia, na przykład link.created
X-Webhook-DeliveryID dostarczenia. Pozostaje takie samo przy ponownych próbach tego dostarczenia
X-Elido-Signature-PreviousTylko podczas rotacji sekretu: ten sam podpis utworzony starym kluczem

Podpis jest obliczany tak:

v1=hex( HMAC-SHA256( secret, "{X-Webhook-Timestamp}.{raw request body}" ) )

Kluczem jest cały ciąg sekretu, razem z prefiksem whsec_, użyty bez zmian. Podpisuj otrzymane surowe bajty, a nie ponownie zserializowany obiekt JSON, i porównuj w czasie stałym. Krótki przykład w Node (Express):

import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.ELIDO_WEBHOOK_SECRET; // full whsec_... value

function same(a, b = "") {
  const x = Buffer.from(a);
  const y = Buffer.from(b);
  return x.length === y.length && timingSafeEqual(x, y);
}

const app = express();
app.post(
  "/webhooks/elido",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const ts = req.get("X-Webhook-Timestamp") ?? "";
    if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
      return res.status(400).send("stale timestamp");
    }
    const expected =
      "v1=" +
      createHmac("sha256", SECRET)
        .update(`${ts}.`)
        .update(req.body)
        .digest("hex");
    const ok = [
      req.get("X-Elido-Signature"),
      req.get("X-Elido-Signature-Previous"),
    ].some((sig) => same(expected, sig));
    if (!ok) return res.status(401).send("bad signature");

    const event = JSON.parse(req.body.toString("utf8"));
    // queue event for processing, then answer quickly
    res.sendStatus(200);
  },
);

Wersje w Pythonie i Go, wektor testowy oraz typowe błędy znajdziesz w przewodniku weryfikacji podpisów webhooków.

Rotacja sekretu podpisywania

Otwórz endpoint w Dashboard → Webhooks i kliknij Rotate secret. Nowy sekret whsec_ zostanie pokazany raz, a od tego momentu Elido będzie podpisywać nim dostarczenia.

Stary klucz pozostaje ważny przez 7-dniowy okres karencji. W tym czasie każde dostarczenie zawiera dwa podpisy: X-Elido-Signature z nowym kluczem oraz X-Elido-Signature-Previous ze starym, dzięki czemu odbiorca, który nie przełączył się jeszcze na nowy klucz, nadal może weryfikować podpis. Podczas wdrażania nowego sekretu akceptuj oba nagłówki.

Endpointy utworzone przed 22 września 2026 r. stanowią wyjątek: podczas ich pierwszej rotacji nie jest generowany X-Elido-Signature-Previous, więc pierwotny sekret przestaje działać od razu. Wdróż nowy sekret zaraz po tej pierwszej rotacji. Endpointy utworzone od tej daty są podpisywane oboma kluczami już od pierwszej rotacji. Od drugiej rotacji obowiązuje 7-dniowe nakładanie się kluczy.

Ponowne próby dostarczenia

Dostarczenie kończy się niepowodzeniem po odpowiedzi innej niż 2xx, błędzie sieci albo braku odpowiedzi w ciągu 10 sekund. Każde dostarczenie ma łącznie 3 próby:

  1. Pierwsza próba, kilka sekund po zdarzeniu.
  2. Ponowna próba około 5 minut po pierwszym niepowodzeniu.
  3. Ostatnia ponowna próba około 15 minut po drugim niepowodzeniu.

Jeśli trzecia próba się nie powiedzie, dostarczenie zostaje oznaczone jako failed i nie jest już automatycznie ponawiane. Endpoint pozostaje aktywny, a nowe zdarzenia są nadal dostarczane. Twój endpoint może zobaczyć to samo dostarczenie więcej niż raz (na przykład gdy przetworzył żądanie, ale odpowiedział po upływie 10-sekundowego limitu), więc usuwaj duplikaty na podstawie X-Webhook-Delivery.

Log dostarczania

Otwórz endpoint w Dashboard → Webhooks, aby zobaczyć 100 ostatnich dostarczeń. Dla każdego z nich zobaczysz typ zdarzenia, status (pending, delivered lub failed), status HTTP zwrócony przez serwer, czas odpowiedzi, liczbę wykorzystanych z 3 prób, czas utworzenia i zakończenia, termin następnej próby dla oczekujących dostarczeń, ostatni błąd oraz pełny wysłany ładunek.

Każde dostarczone lub nieudane dostarczenie ma przycisk Retry. Ponownie dodaje on to samo dostarczenie do kolejki (z tym samym ID X-Webhook-Delivery, ale ze świeżym podpisem) z nowym limitem 3 prób. Przez API GET /v1/workspaces/{workspace_id}/webhooks/{id}/deliveries stronicuje starsze dostarczenia za pomocą limit (do 100) i offset, a POST .../deliveries/{delivery_id}/retry robi to samo co przycisk. Jeśli nie możesz samodzielnie odtworzyć dostarczenia, support Elido może odtworzyć je za Ciebie.

Zapisywanie treści odpowiedzi Twojego serwera w logu jest planowane.

Testowanie lokalne

Planowane jest polecenie CLI przekazujące webhooki do localhost (npx @elido/cli webhooks forward). Do tego czasu udostępnij lokalny serwer przez tunel, taki jak ngrok lub Cloudflare Tunnel, dodaj HTTPS URL tunelu jako endpoint i usuń go po zakończeniu pracy.

Limity

  • 10 sekund na odpowiedź endpointu.
  • 3 próby dostarczenia każdego zdarzenia oraz ręczne ponowienia.
  • API logu dostarczania zwraca najwyżej 100 dostarczeń na stronę.

Rozwiązywanie problemów

Podpis nigdy się nie zgadza. Najczęstsze przyczyny: framework sparsował i ponownie zserializował JSON przed jego zahaszowaniem (hashuj surowe body), usunięto prefiks whsec_ z klucza albo podpisujesz za pomocą timestamp z treści zamiast nagłówka X-Webhook-Timestamp. Wpis o weryfikacji podpisów zawiera wektor testowy, z którym możesz porównać swój kod.

Podpis przestał się zgadzać po rotacji. Twój serwer nadal ma stary sekret. Wdróż nowy. W przypadku endpointu utworzonego przed 22 września 2026 r. podczas pierwszej rotacji nie ma X-Elido-Signature-Previous, na którym można by się oprzeć.

Niektóre zdarzenia przychodzą dwukrotnie. Elido ponowiło próbę, ponieważ endpoint odpowiedział błędem albo działał dłużej niż 10 sekund. Usuwaj duplikaty na podstawie X-Webhook-Delivery i odpowiadaj kodem 2xx przed wykonaniem powolnych operacji.

Typ zdarzenia nigdy nie przychodzi. Sprawdź, czy endpoint jest na niego zasubskrybowany i nie jest wstrzymany oraz czy typ znajduje się w powyższym katalogu. Typy oznaczone jako planowane nie są jeszcze wysyłane.

Czy to było pomocne?
Potrzebujesz więcej? Napisz do zespołu - odpowiedź w ciągu jednego dnia roboczego.Skontaktuj się z pomocą