Webhook-uri: abonați-vă la evenimentele linkurilor și workspace-ului

Trimiteți POST-uri HTTP semnate de la Elido către serverul dumneavoastră când se modifică linkuri, domenii, membri și workspace-ul. Headere, payload, reîncercări, jurnalul livrărilor și rotirea secretului.

9 min de cititActualizat 2026-09-22

Ce veți configura

  • Un endpoint care primește evenimente Elido precum link.created, link.updated, link.deleted, member.invited și domain.verified.
  • Verificarea HMAC-SHA256 a headerului X-Elido-Signature, astfel încât serverul dumneavoastră să poată confirma că fiecare livrare provine de la Elido.
  • Trei încercări de livrare per eveniment, un jurnal al livrărilor cu un buton manual Retry și rotirea secretului cu o suprapunere de 7 zile.

Webhook-urile trimit evenimente de la Elido către serverul dumneavoastră pe măsură ce se produc, astfel încât nu trebuie să interogați periodic API-ul. Utilizări tipice: sincronizarea metadatelor linkurilor cu un CRM, menținerea la zi a unui index intern de linkuri sau pornirea unei sarcini când este publicat un link.

Webhook-urile acoperă modificările linkurilor, domeniilor, membrilor și workspace-ului. Nu transportă clicuri individuale. Pentru date despre clicuri, folosiți exportul clicurilor sau o integrare de evenimente precum Mixpanel. Evenimentele webhook pentru fiecare clic sunt planificate.

Adăugați un endpoint webhook

  1. Accesați Dashboard → Webhooks.
  2. Introduceți URL-ul către care trebuie să trimitem POST-ul și o descriere opțională.
  3. Alegeți tipul endpointului: Events (alegeți tipurile de evenimente) sau SIEM (firehose) (fiecare eveniment din workspace).
  4. Pentru un endpoint Events, bifați tipurile de evenimente dorite. Evenimentele link.* sunt bifate implicit.
  5. Faceți clic pe Add endpoint. Secretul de semnare apare o singură dată, chiar sub formular. Copiați-l acum: Elido nu îl va mai afișa.

URL-ul trebuie să fie HTTPS. URL-urile simple http:// sunt respinse la salvarea endpointului, cu excepția adreselor localhost și 127.0.0.1, care rămân permise pentru dezvoltarea locală.

Puteți pune pe pauză și relua un endpoint din listă. Un endpoint pus pe pauză nu mai primește livrări noi, iar elementele care încă sunt în coadă așteaptă până când îl reluați.

Cine poate gestiona webhook-urile

Orice persoană din workspace poate vedea endpointurile și jurnalul livrărilor. Crearea, editarea, punerea pe pauză, ștergerea, rotirea secretului și reîncercarea unei livrări necesită permisiunea workspace.edit, pe care o au rolurile integrate Admin și Owner. O cheie API poate apela aceleași endpointuri webhook ale API-ului dacă rolul său are această permisiune.

Tipuri de endpointuri

  • Events (event): primește doar tipurile de evenimente la care v-ați abonat. Semnat.
  • SIEM (siem): primește fiecare eveniment publicat pentru workspace, inclusiv audit.event pentru fiecare intrare din jurnalul de audit. Semnat. Destinat conductelor de jurnale și instrumentelor de securitate.
  • Discord, Telegram și Sentry: canale de chat și alertare care reutilizează același sistem de livrare, dar trimit propriul format de mesaje al furnizorului. Se autentifică prin URL-ul sau tokenul furnizorului, deci nu transportă headere de semnătură. Consultați Discord, Telegram și Sentry.

Tot ce urmează despre semnături și secrete se aplică numai endpointurilor Events și SIEM.

Catalogul evenimentelor

Numele urmează formatul <resource>.<action>. Formularul din dashboard oferă cele mai comune tipuri; prin API puteți abona un endpoint Events la orice tip din această listă, iar un endpoint SIEM le primește pe toate.

În selectorul din dashboard:

  • link.created: a fost creat un link scurt, inclusiv linkuri create în bloc.
  • link.updated: un link s-a modificat (destinație, titlu, etichete, expirare și așa mai departe), a fost restaurat, i s-a modificat starea sau starea de siguranță i-a fost modificată de moderare.
  • link.deleted: un link a fost șters logic.
  • workspace.updated: setările workspace-ului s-au modificat.
  • workspace.created: este publicat când este creat un workspace. Deoarece nu poate exista niciun endpoint într-un workspace înainte ca acesta să fie creat, în mod normal nu îl veți primi.
  • member.invited: cineva s-a alăturat workspace-ului prin adăugare directă, acceptarea unei invitații sau aprovizionare SCIM.
  • member.removed: un membru a fost eliminat manual sau prin SCIM.
  • audit.event: câte un eveniment pentru fiecare intrare din jurnalul de audit.

Disponibile prin API sau printr-un endpoint SIEM:

  • link.expired: un link a trecut de data de expirare.
  • link.cap_reached: un link a atins limita de clicuri. data include cap și clicks.
  • link.broken: verificarea stării linkului de către Elido a constatat că destinația nu funcționează. data include status_code, error_message și first_seen_at.
  • link.encrypted_created și link.encryption_rotated: pentru linkuri criptate.
  • domain.verified: un domeniu personalizat a trecut verificarea DNS.
  • domain.ssl_failed: înregistrările DNS ale unui domeniu personalizat nu au fost găsite nici după 24 de ore de la adăugare. În ciuda numelui, este vorba despre verificarea DNS, nu despre reînnoirea certificatului.
  • member.role_changed: rolul unui membru s-a modificat. data include old_role, new_role și changed_by_user_id.
  • invitation.created și invitation.accepted.
  • Evenimente de facturare: subscription.* (de exemplu subscription.activated, subscription.renewed, subscription.canceled) și usage.threshold_80, usage.threshold_100.

Planificate, nu sunt trimise în prezent: link.clicked.aggregated (numărul de clicuri per link și interval), evenimentele pentru fiecare clic, conversion.recorded, domain.tls_renewed, qr.generated și un eveniment separat abuse.flagged. O decizie de moderare pentru un link sosește în prezent ca link.updated, cu noul abuse_status.

Structura payloadului

Fiecare livrare semnată este un POST cu Content-Type: application/json, User-Agent: Elido-Webhooks/1.0 și acest înveliș:

{
  "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 este tipul evenimentului. Se află și în headerul X-Webhook-Event.
  • timestamp este momentul producerii evenimentului, în UTC.
  • data depinde de eveniment. Pentru evenimentele link.* este obiectul complet al linkului (exemplul de mai sus este prescurtat). Pentru celelalte evenimente este un obiect mic, cu ID-urile și câmpurile enumerate în catalog.
  • Secretele nu părăsesc Elido: câmpuri precum hashul parolei unui link sau un token de invitație sunt eliminate din data înainte de livrare.

În corp nu există încă un câmp id al evenimentului; un ID per eveniment este planificat. Pentru idempotență, folosiți headerul X-Webhook-Delivery, descris mai jos.

Headere și semnături

Fiecare livrare către un endpoint Events sau SIEM conține:

HeaderValoare
X-Elido-Signaturev1= urmat de semnătura HMAC-SHA256 în hexazecimal
X-Webhook-SignatureAceeași valoare ca X-Elido-Signature, păstrată pentru integrările mai vechi
X-Webhook-TimestampTimpul Unix în secunde la care a fost semnată această cerere
X-Webhook-EventTipul evenimentului, de exemplu link.created
X-Webhook-DeliveryID-ul livrării. Rămâne același la reîncercările aceleiași livrări
X-Elido-Signature-PreviousNumai în timpul unei rotiri a secretului: aceeași semnătură creată cu cheia veche

Semnătura se calculează astfel:

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

Cheia este întregul șir al secretului, inclusiv prefixul whsec_, folosit ca atare. Semnați octeții bruti primiți, nu un obiect JSON serializat din nou, și comparați în timp constant. Un exemplu scurt în 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);
  },
);

Pentru versiunile Python și Go, un vector de test și greșelile frecvente, consultați cum se verifică semnăturile webhook.

Rotiți secretul de semnare

Deschideți endpointul în Dashboard → Webhooks și faceți clic pe Rotate secret. Noul secret whsec_ este afișat o singură dată, iar Elido începe să semneze cu el din acel moment.

Cheia veche rămâne valabilă timp de 7 zile. În această perioadă, fiecare livrare conține două semnături: X-Elido-Signature cu cheia nouă și X-Elido-Signature-Previous cu cea veche, astfel încât un receptor care nu a făcut încă schimbarea să poată continua verificarea. Acceptați oricare dintre headere cât timp implementați noul secret.

Endpointurile create înainte de 22 septembrie 2026 sunt o excepție: la prima lor rotire nu produc X-Elido-Signature-Previous, așa că secretul inițial încetează să funcționeze imediat. Implementați noul secret imediat după acea primă rotire. Endpointurile create începând de atunci semnează cu ambele chei chiar de la prima rotire. Începând cu a doua rotire, se aplică suprapunerea de 7 zile.

Reîncercări

O livrare eșuează la orice răspuns care nu este 2xx, la o eroare de rețea sau dacă nu există răspuns în 10 secunde. Fiecare livrare primește în total 3 încercări:

  1. Prima încercare, la câteva secunde după eveniment.
  2. O reîncercare la aproximativ 5 minute după primul eșec.
  3. O ultimă reîncercare la aproximativ 15 minute după al doilea eșec.

Dacă a treia încercare eșuează, livrarea este marcată failed și nu mai este reîncercată automat. Endpointul rămâne activ, iar evenimentele noi continuă să fie livrate. Endpointul dumneavoastră poate vedea aceeași livrare de mai multe ori (de exemplu, când a procesat o cerere, dar a răspuns după expirarea celor 10 secunde), așa că eliminați duplicatele folosind X-Webhook-Delivery.

Jurnalul livrărilor

Deschideți un endpoint în Dashboard → Webhooks pentru a vedea cele mai recente 100 de livrări. Pentru fiecare primiți tipul evenimentului, starea (pending, delivered sau failed), starea HTTP returnată de serverul dumneavoastră, timpul de răspuns, încercările folosite din 3, momentul creării și al finalizării, următoarea oră de reîncercare pentru cele în așteptare, ultima eroare și payloadul complet trimis.

Orice livrare delivered sau failed are un buton Retry. Acesta pune din nou în coadă aceeași livrare (cu același ID X-Webhook-Delivery, semnată din nou) cu un buget nou de 3 încercări. Prin API, GET /v1/workspaces/{workspace_id}/webhooks/{id}/deliveries parcurge livrările mai vechi cu paginare folosind limit (până la 100) și offset, iar POST .../deliveries/{delivery_id}/retry face același lucru ca butonul. Dacă nu puteți reda singur o livrare, serviciul de asistență Elido o poate reda pentru dumneavoastră.

Înregistrarea în jurnal a corpului de răspuns al serverului dumneavoastră este planificată.

Testare locală

Este planificată o comandă CLI care transmite webhook-urile către localhost (npx @elido/cli webhooks forward). Până atunci, expuneți serverul local printr-un tunel precum ngrok sau Cloudflare Tunnel, adăugați URL-ul HTTPS al tunelului ca endpoint și eliminați-l când ați terminat.

Limite

  • 10 secunde pentru ca endpointul dumneavoastră să răspundă.
  • 3 încercări de livrare per eveniment, plus reîncercări manuale.
  • API-ul jurnalului livrărilor returnează cel mult 100 de livrări per pagină.

Depanare

Semnătura nu corespunde niciodată. Cauzele obișnuite sunt: frameworkul dumneavoastră a analizat și a serializat din nou JSON-ul înainte să îl calculați ca hash (calculați hashul corpului brut), ați eliminat prefixul whsec_ din cheie sau semnați folosind timestamp din corp în locul headerului X-Webhook-Timestamp. Articolul despre verificarea semnăturii conține un vector de test cu care vă puteți verifica codul.

Semnătura a încetat să corespundă după o rotire. Serverul dumneavoastră încă are secretul vechi. Implementați-l pe cel nou. Pentru un endpoint creat înainte de 22 septembrie 2026, la prima rotire nu există X-Elido-Signature-Previous pe care să vă bazați.

Unele evenimente sosesc de două ori. Elido a făcut o reîncercare deoarece endpointul dumneavoastră a răspuns cu o eroare sau a durat mai mult de 10 secunde. Eliminați duplicatele folosind X-Webhook-Delivery și răspundeți cu un 2xx înainte de a efectua operațiuni lente.

Un tip de eveniment nu sosește niciodată. Verificați dacă endpointul este abonat la el și nu este pus pe pauză și dacă tipul se află în catalogul de mai sus. Tipurile marcate ca planificate nu sunt încă trimise.

Ți-a fost de ajutor?
Ai nevoie de mai multe informații? Scrie echipei - răspundem în cel mult o zi lucrătoare.Contactează suportul