Skip to content

Webhooks — what gets emitted and why

Webhooks are how your systems hear about things happening in your IntelliAuth tenant in near real-time. A user signs up; your CRM gets a row. An admin disables a user; your downstream services receive a "kick this user out" event. A password is reset; your audit pipeline lights up.

The pattern is push-based and one-way: IntelliAuth POSTs a JSON payload to a URL you control. Your receiver verifies the signature, processes the event, and returns a 2xx. If your receiver is down or slow, IntelliAuth retries on a backoff schedule and eventually parks the event in a dead-letter queue.

Every webhook delivery sends a JSON body like:

{
"event_id": "evt_01HZX...",
"event_type": "user.signed_up",
"occurred_at": "2026-05-17T08:00:00.000Z",
"tenant": { "id": "tnt_01HZ...", "slug": "banking-cymmetri" },
"actor": { "kind": "user", "id": "usr_01HZX...", "email": "anita@cymmetri.com" },
"data": {
"user": {
"id": "usr_01HZX...",
"email": "anita@cymmetri.com",
"name": "Anita Singh",
"created_at": "2026-05-17T08:00:00.000Z"
}
},
"delivery": { "attempt": 1, "subscription_id": "whsub_01HZX..." }
}

The five top-level fields (event_id, event_type, occurred_at, tenant, data) are universal. actor and delivery are usually present.

Plus a handful of headers:

HeaderPurpose
X-IntelliAuth-SignatureHMAC-SHA256 over the body, hex-encoded
X-IntelliAuth-Event-IdMirrors event_id — use for dedup
X-IntelliAuth-Event-TypeMirrors event_type — useful for routing without parsing the body
X-IntelliAuth-Delivery-Attempt1, 2, 3, … for retries
X-IntelliAuth-TimestampUnix seconds when the delivery was sent — protects against replay

A summary; the event reference is the catalogue.

  • Auth eventsuser.signed_in, user.signed_out, user.sign_in_failed, user.mfa_required, user.mfa_succeeded, user.mfa_failed.
  • User lifecycleuser.signed_up, user.updated, user.disabled, user.enabled, user.deleted, user.email_verified.
  • MFAmfa.factor_added, mfa.factor_removed, mfa.backup_codes_regenerated.
  • Application adminapplication.created, application.updated, application.secret_rotated, application.disabled, application.deleted.
  • Federationfederation.connection_added, federation.sso_completed, federation.sso_failed.
  • Security / risksecurity.brute_force_detected, security.token_reuse_detected, security.breach_incident_opened.
  • At-least-once. Your receiver may see the same event twice (typically when your receiver returned a slow 2xx and IntelliAuth's connection timed out). Dedupe by event_id.
  • Best-effort ordering. Events related to the same entity are usually delivered in order, but the platform does not guarantee strict global ordering across all events.
  • Retries. Non-2xx response or no response within 10 seconds triggers retry. The first attempt fires immediately; retries follow at 1m, 5m, 30m, 2h, and 12h. After the fifth retry fails (six attempts total), the event goes to the dead-letter queue.
  • TTL. Events sit in delivery for up to 24 hours from occurred_at before being marked permanently failed.

Polling for "new things since timestamp X" works at low traffic and breaks at scale. Webhooks scale the other way — your receiver only spins up when something actually happens. The platform's job is "tell you when"; your job is "do something fast when you hear".

Two common designs:

  • Receiver is your own server — a small endpoint that authenticates the signature, enqueues onto an internal queue, returns 200. The heavy work happens off the request path.
  • Receiver is a serverless function — Lambda, Cloud Run, Vercel — that processes the event inline. Easier to set up; pay-per-event cost; cold-start latency means you should monitor delivery times.
  • For the user is currently signing in and your code needs to react, that's a custom authentication pipeline Action — configured by your tenant admin in the IntelliAuth admin console. Pipeline Actions run synchronously inside the sign-in; webhooks fire after.
  • For historical access ("what events happened last week?"), that's the audit API, not webhooks. Webhooks are a stream from "now"; audit is the persistent log.
  • For bidirectional or RPC-shaped, that's a normal API call. Webhooks are one-way notifications.