SeleID

Webhooks

Webhooks

Webhooks · SeleQueue · SeleMail · Email Routing · Push · Bot protection · API and keys

Register an HTTPS endpoint and choose the events you want. We POST each event as JSON, signed with your endpoint secret. The secret is shown once when you create the endpoint; rotate it any time.

Create an endpoint

POST /v1/webhooks/endpoints
{ "url": "https://example.com/hooks/seleid", "events": ["user.created"] }
-> { "id": "we_1", "secret": "whsec_..." }

Verify the signature

Each request carries SeleID-Signature: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 of <t>.<raw body> with your secret. Compare in constant time and reject timestamps older than 5 minutes.

Node

import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(secret, rawBody, header, nowSec = Date.now() / 1000) {
  const p = Object.fromEntries(header.split(',').map((x) => x.split('=')));
  if (Math.abs(nowSec - Number(p.t)) > 300) return false;
  const want = createHmac('sha256', secret).update(p.t + '.' + rawBody).digest('hex');
  return want.length === p.v1.length && timingSafeEqual(Buffer.from(want), Buffer.from(p.v1));
}

Retries, log and replay

Any non-2xx answer, timeout (10 seconds) or network error is retried with exponential backoff (30 s, 1 min, 2 min, 4 min, 8 min), six attempts in all; after that the delivery is marked failed and kept in the dead-letter list. Every attempt is recorded in the delivery log. Replay re-sends the same event body as a new delivery. Respond quickly with 2xx and process in the background; the same event may arrive more than once, so de-duplicate on SeleID-Event-Id.

Endpoint URLs must be HTTPS on a public hostname (no IP addresses, localhost or internal names).

Last updated 2026-11-12Suggest an editReport a problem with this page