Skip to content
Integration

Consuming Clerk Webhooks: Verification, Retries, and Error Recovery

How to receive and verify Clerk webhooks using Svix headers (svix-id, svix-timestamp, svix-signature), handle user lifecycle events, manage retries, and recover missed syncs.

Published 3 min read
On this page

Clerk uses webhooks powered by Svix to notify your application whenever authentication or user state changes: a user signs up, updates their primary email, creates an organization, or signs into a new session. Because these events frequently drive user provisioning, database records, and permission caches in your backend, missing a webhook leaves your database out of sync with Clerk.

This guide walks through consuming Clerk webhooks reliably: signature verification with Svix headers, fast acknowledgement, idempotency, and recovering from failures.

What Clerk webhooks are

Clerk emits HTTP POST requests containing JSON payloads when user lifecycle events occur. Each delivery includes:

  • data: The updated resource (e.g. User, Session, OrganizationMembership).
  • type: The event name, such as user.created, user.updated, or user.deleted.
  • object: Always "event".

Crucial Svix Headers

Clerk relies on standard Svix headers for payload verification:

  • svix-id: Unique identifier for the webhook message.
  • svix-timestamp: Unix timestamp when the webhook was generated.
  • svix-signature: Composed of version identifiers and HMAC SHA-256 signatures (v1,signature_base64).

Common use cases

  • User synchronization — Create or update local user profile records in Postgres/MySQL on user.created and user.updated.
  • Workspace provisioning — Initialize default projects, billing accounts, or API keys when organization.created fires.
  • Access revocation — Tear down active sessions and revoke refresh tokens immediately on user.deleted or session.revoked.
  • Analytics & onboarding — Trigger welcome email workflows and telemetry when a first session is created.

Verifying Clerk webhook signatures

To prevent tampering and replay attacks, verify the Svix headers against the signing secret provided in your Clerk Dashboard (Configure → Webhooks → Signing Secret, prefixed with whsec_).

Verification steps:

  1. Extract svix-id, svix-timestamp, and svix-signature from incoming request headers.
  2. Read the raw, unparsed request body string (do not use parsed JSON).
  3. Compute the HMAC SHA-256 of "${svixId}.${svixTimestamp}.${rawBody}" using the base64-decoded secret.
  4. Compare against the signatures listed in svix-signature using constant-time comparison.
  5. Reject timestamps older than 5 minutes (300 seconds) to prevent replay attacks.

Common failure modes and debugging

1. Signature verification mismatch

Usually caused by:

  • Using a parsed JSON body instead of the exact UTF-8 raw byte stream.
  • Not decoding the whsec_ prefix if verifying manually.
  • Server clock drift exceeding the 5-minute tolerance window.

2. Slow endpoint timeouts

Clerk expects your endpoint to return a 2xx response within a few seconds. If your handler connects to slow downstream databases or queues synchronously, Clerk will mark the attempt failed and schedule exponential backoff retries.

3. Duplicate event processing

Network hiccups can cause the same svix-id to be delivered more than once. Store processed svix-id values with an expiration TTL or use database upserts on Clerk’s data.id.

Debugging Clerk webhooks with HookWatch

Placing HookWatch in front of your Clerk webhook destination gives you instant visibility:

  • Capture the full svix-* headers and payload for every user.created event.
  • Inspect the exact HTTP status and error body your application returned.
  • Replay failed user-sync deliveries with one click once your database migration is applied.
Get started

See what happened to every webhook.

HookWatch keeps the request, the response, and every attempt for each delivery — so the debugging, retry, and replay steps in this article are a matter of reading, not reconstructing.