Documentation

Webhooks

AdminUpdated Sep 11, 2026

Webhooks

A webhook lets Atlas push an event to your backend the moment it happens — a user is created, a session is revoked, an organization membership changes — so you can react without polling.

Atlas delivering an event to your endpoint

Register an endpoint

  1. Open Integrations → Webhooks for the instance (or use the Backend API).

  2. Add an endpoint URL on your backend and choose the events it should receive (a specific list, or * for all).

  3. Atlas creates the endpoint and reveals its signing secret exactly once — copy it now; it's never shown again. If you lose it, rotate to mint a new one (deliveries signed with the old secret start failing immediately).

The event catalog

Atlas emits events across the object lifecycle, including:

  • Users: user.created, user.updated, user.deleted, user.banned, user.unbanned

  • Sessions: session.created, session.revoked, session.ended, session.pending, session.removed

  • Messages: email.created, sms.created

  • Organizations: organization.created/updated/deleted, organizationMembership.created/updated/deleted, organizationInvitation.created/accepted/revoked, organizationDomain.created/updated/deleted

  • Authorization: role.created/updated/deleted, permission.created/updated/deleted

  • Enterprise & billing: ssoConnection.*, scimToken.created/revoked, subscription.created/updated/deleted, waitlistEntry.*

The payload

Every delivery is a JSON body carrying the full resource object, not a diff — so a consumer that processes events out of order can still reconstruct state from the latest one it sees:

{
  "id": "evt_2a…",
  "type": "user.created",
  "timestamp": 1757600000000,
  "instance_id": "inst_…",
  "data": { "id": "user_…", "email_addresses": [ … ], … }
}

Verify the signature

Always verify before trusting a delivery. Atlas signs each one with HMAC-SHA256 and sends three headers:

  • atlas-id — the event id

  • atlas-timestamp — the send time (ms)

  • atlas-signaturev1,<base64 mac>

The signed material is id.timestamp.body — the timestamp is inside the signature, not just a header, so a captured body can't be replayed under a fresh timestamp. To verify:

  1. Recompute HMAC_SHA256(secret, "<id>.<timestamp>.<rawBody>"), base64-encode it, and compare (constant-time) to the value after v1,.

  2. Reject any request whose timestamp is more than 5 minutes from now, in either direction — that's the replay window.

  3. Use the raw request body exactly as received; re-serializing JSON changes the bytes and breaks the signature.

Deliveries, retries and testing

  • Every attempt is recorded as a delivery you can inspect (status, response) in the dashboard.

  • You can redeliver a past event, and send a synthetic webhook.test event to one endpoint to confirm your handler works (it records a real delivery but is never fanned out to your other endpoints).

  • The worker performs delivery and retries out of band, so a slow endpoint doesn't slow down sign-in.

Next

Shape tokens for downstream services → JWT templates & custom claims.

Was this page helpful?