Salt la conținut
Documentație · Webhookuri

Webhookuri

Usher le poate spune serverelor dvs. ce se întâmplă într-un mediu, chiar în momentul în care se întâmplă: cineva se înscrie, se conectează, își schimbă datele sau pleacă. Fiecare eveniment este un POST semnat către o adresă aleasă de dvs., retrimis dacă serverul nu răspunde.

Adăugați un endpoint

În Usher Console, deschideți mediul, apoi Webhookuri → Endpoint nou. Indicați o adresă https:// a dvs. și alegeți evenimentele despre care trebuie să afle. Console afișează o singură dată secretul de semnare al endpointului (whsec_…): păstrați-l împreună cu celelalte secrete ale serverului.

EvenimentCând
user.createdCineva și-a creat un cont
user.updatedUn cont s-a modificat: adresa de e-mail, numele, verificarea sau interdicția (inclusiv o interdicție din directorul organizației dvs., prin SCIM)
user.deletedUn cont a fost șters
session.createdCineva s-a conectat
session.endedO sesiune s-a încheiat: deconectare, revocare sau expirare anticipată

Trimiteți un test trimite un eveniment webhook.test doar către acel endpoint, indiferent de evenimentele la care este abonat.

Ce sosește

Cerere
POST /usher/webhooks HTTP/1.1
content-type: application/json
user-agent: Usher-Webhooks/1
webhook-id: msg_2fk7x…
webhook-timestamp: 1793643116
webhook-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=
Corp
{
  "type": "user.created",
  "timestamp": "2026-11-02T18:11:56.412Z",
  "data": {
    "user": {
      "id": "Qz3m…",
      "email": "lena@acme.com",
      "emailVerified": false,
      "name": "Lena Live",
      "image": null,
      "banned": false,
      "createdAt": "2026-11-02T18:11:56.380Z",
      "updatedAt": "2026-11-02T18:11:56.380Z"
    }
  }
}

Evenimentele descriu persoane și sesiuni, niciodată secrete: fără tokenuri, fără hashuri de parole, fără roluri și fără motivul pentru care cineva a primit interdicție.

Verificați fiecare livrare

Usher semnează după specificația Standard Webhooks, așa că oricare dintre bibliotecile ei verifică semnătura pentru dvs. Refuzați tot ce nu trece verificarea. Bibliotecile refuză și un timestamp mai vechi sau mai nou de cinci minute, ca o livrare veche să nu poată fi reluată.

app/usher/webhooks/route.ts
// a route that receives Usher's webhooks (Node, the standardwebhooks package)
import { Webhook } from 'standardwebhooks'

const wh = new Webhook(process.env.USHER_WEBHOOK_SECRET!) // whsec_…, from Usher Console

export async function POST(request: Request) {
  const body = await request.text() // the raw body: the signature covers it byte for byte
  let event: { type: string; timestamp: string; data: Record<string, unknown> }
  try {
    event = wh.verify(body, Object.fromEntries(request.headers)) as typeof event
  } catch {
    return new Response('bad signature', { status: 400 })
  }
  // webhook-id is the same on every attempt: skip one you have handled already
  if (await alreadyHandled(request.headers.get('webhook-id')!)) return new Response(null, { status: 204 })
  await queue(event) // answer quickly; do the work afterwards
  return new Response(null, { status: 204 })
}
  • Răspundeți în 15 secunde cu orice cod 2xx. Orice altceva, inclusiv o redirecționare, se consideră eșec.
  • Așteptați-vă la repetări. Un mesaj își păstrează webhook-id la fiecare încercare; ignorați-l pe cel deja tratat.
  • Nu vă bazați pe ordine. Reîncercările pot sosi după evenimente mai noi.

Când serverul nu răspunde

Usher încearcă din nou după 5 secunde, 5 minute, 30 de minute, 2 ore, 5 ore, 10 ore și încă 10 ore (în total, cam o zi și jumătate), apoi renunță. Jurnalul de livrări din Console arată încercările fiecărui mesaj și ultimul răspuns al serverului, iar Trimiteți din nou reia o livrare de la început.

Un secret nou

Secret nou din Console generează încă un secret și îl afișează o singură dată. În următoarele 24 de ore, fiecare livrare poartă două semnături, câte una pentru fiecare secret, ca să puteți implementa secretul nou fără să pierdeți nimic. După aceea semnează doar cel nou.

De unde vin livrările

Webhookurile ies din Usher prin proxy-ul de ieșire, care nu se conectează la adrese private sau interne. Un endpoint trebuie să fie o adresă https:// pe un nume public: nu o adresă IP, nu un nume privat și nu o adresă de pe domeniile Usher.