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 asuser.created,user.updated, oruser.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.createdanduser.updated. - Workspace provisioning — Initialize default projects, billing accounts, or API keys when
organization.createdfires. - Access revocation — Tear down active sessions and revoke refresh tokens immediately on
user.deletedorsession.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:
- Extract
svix-id,svix-timestamp, andsvix-signaturefrom incoming request headers. - Read the raw, unparsed request body string (do not use parsed JSON).
- Compute the HMAC SHA-256 of
"${svixId}.${svixTimestamp}.${rawBody}"using the base64-decoded secret. - Compare against the signatures listed in
svix-signatureusing constant-time comparison. - 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 everyuser.createdevent. - 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.