惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
Hacker News: Ask HN
Hacker News: Ask HN
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
月光博客
月光博客
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
The GitHub Blog
The GitHub Blog
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
F
Full Disclosure
U
Unit 42
Jina AI
Jina AI
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
腾讯CDC
T
Threatpost
H
Hacker News: Front Page
P
Palo Alto Networks Blog
博客园 - 聂微东
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
L
LINUX DO - 热门话题
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Spread Privacy
Spread Privacy

Clerk Blog

Going to production with Clerk Deploy Clerk Init: The fastest way to start a new project Introducing Clerk CLI Middleware-based route protection bypass Postmortem: Clerk System Outage (March 10, 2026) Clerk for the AI era Add API Key support to your SaaS in minutes Postmortem: Clerk System Outage (February 19, 2026) Using Clerk in a React Native app Postmortem: DNS Provider Outage (February 10, 2026) How do I implement passkeys in Next.js? Clerk ranked #4 fastest-growing software vendor on Ramp’s December 2025 list How do I handle JWT verification in Next.js? Committing to Agent Identity: Clerk raises $50m Series C from Menlo and Anthropic’s Anthology Fund What is the best way to handle authentication in Next.js App Router? Postmortem: Database Incident (September 14–18, 2025) How do I add authentication to a Next.js app? Introducing Free Trials in Clerk Billing Postmortem: August 28, 2025 - elevated API latency and errors Introducing Mosaic: Bring Your Brand to Every Authentication Flow Multi-tenant authentication: What you need to know (and how Clerk helps) What are the risks and challenges of multi-tenancy? Resilience in Practice: Regional Failover at Clerk Build a Cross-Platform B2B App with Clerk, Expo, and Supabase Highlights from the MiduDev/Clerk Hackathon Add multi-tenancy to an app built with Clerk, Lovable, and Supabase How to build an AI coding rules app with Clerk, Lovable, and Supabase How to Build Multi-Tenant Authentication with Clerk Choosing the right SaaS architecture: Multi-Tenant vs. Single-Tenant Postmortem: June 26, 2025 service outage How to Design a Multi-Tenant SaaS Architecture What is multi-tenancy and why it matters for B2B SaaS How OAuth Works Synchronize user data from Clerk to Supabase Add subscriptions to your SaaS with Clerk Billing Getting started with Clerk Billing Multi-tenant analytics with Tinybird and Clerk How Huntr Migrated 250K Users to Clerk: A Scalable Auth Solution for Startups How to take Clerk to Production How to take your Clerk application to production A practical guide to testing Clerk Next.js applications Implementing multi-tenancy into a Supabase app with Clerk How Clerk integrates with a Next.js application using Supabase How Clerk integrates with Supabase Build a blog with tRPC, Prisma, Next.js and Clerk How to enrich PostHog events with Clerk user data How to build a secure project management platform with Next.js, Clerk, and Neon Validate your SaaS idea while building an audience Postmortem: February 6, 2025 service outage Implement Role-Based Access Control in Next.js 15 Build a Next.js sign-up form with React Hook Form Build a Next.js login page template How to implement Google authentication in Next.js 15 What is middleware in Next.js? How to customize Next.js metadata How to set environment variables in Node.js Building a React Login Page Template How to implement per-user OAuth scopes with Clerk Using Clerk SSO to access Google Calendar and other service data Streamline enterprise customer onboarding with SAML and Clerk Clerk launches EASIE SSO and eliminates SSO fees How to secure Liveblocks Rooms with Clerk in Next.js Securing Node.js Express APIs with Clerk and React Combining the benefits of session tokens and JWTs Build a task manager with Next.js, Supabase, and Clerk Comparing Clerk Webhooks vs Backend API Automate Neon schema changes with Drizzle and GitHub Actions A guide to reading authenticated user data from Clerk Role based access control with Clerk Organizations Mitigating OAuth’s recently discovered Open Response Type vulnerability Per-user B2B monetization with Stripe and Clerk Organizations Build a team-based task manager with Next.js, Neon, and Clerk Building a Hybrid Sign-Up/Subscribe Form with Stripe Elements Welcoming Colin from Zod as our inaugural Open Source Fellow Build a modern authenticated chat application with Next.js, Ably, and Clerk Build a waitlist with Clerk user metadata How to use Clerk with PostHog Identify in Next.js How to secure API Gateway using JWT and Lambda Authorizers with Clerk What are passkeys and how do they work? Comparing Authentication in React.js vs. Next.js How to Add an Onboarding Flow for your Application with Clerk Create Your Own Custom User Menu with Radix - Part 2 Introducing Webhook Workflows with Inngest & Svix Clerk raises $30M Series B from CRV and Stripe Clerk in 2023: A Year in Review Build a Movie Emoji Quiz App with Remix, Fauna, and Clerk Ultimate Guide to Magic Link Authentication Create Your Own Custom User Menu with Radix Introducing has(), protect(), and <Protect> Updated Pricing: 10,000 MAUs Free, and a new “Pro Plan” Next.js Authentication with Clerk: Streamlined SSR Handling Clerk Webhooks: Data Sync with Convex Exploring Clerk Metadata with Stripe Webhooks The Ultimate Guide to Next.js Authentication Empower Your Support Team With User Impersonation A Complete Guide to Session Management in Next.js The Advanced Guide to Passwordless Authentication in Next.js How We Roll – Chapter 10: Roundup How We Roll – Chapter 9: Infrastructure Password-Based Authentication in Next.js
Clerk Webhooks: Getting Started
Dev Agrawal · 2023-09-30 · via Clerk Blog

In an age of software that is composed of decoupled services built by specialized (often outsourced) teams, webhooks play an important architectural role. Webhooks enable us to outsource important user interactions and services to external platforms that are specifically designed for those purposes, and still have our applications be able to respond to those interactions.

For example, Clerk is specifically designed to handle authentication and user management related interactions on behalf of your applications. Webhooks allow Clerk to notify your application of these interactions so that you can implement custom follow-up logic. These interactions include (but are not limited to) signing in, changing profile information, creating an organization, or getting invited to an organization. Clerk ensures that all these important interactions are handled securely and responsively, while giving you a way to implement follow-up logic.

In this blog post we will build a simple webhook integration in a Next.js project. We will also explore the use cases of webhooks with Clerk and discuss how to best handle webhooks for production-ready applications.

This post assumes basic familiarity with Next.js and Clerk.

Setting up Webhooks in Next.js

For this walkthrough we will start with a Next.js project that is already setup with Clerk. However, you can create a webhook subscription in any server-side web framework like Express or Fastify.

If you don’t already have a Next.js project setup with Clerk, you can start by cloning the Clerk Next.js App Router template.

This will create a minimal Next.js project fully setup with Clerk’s embedded components and a secured dashboard page.

Create a .env.local file in the root of the project and add your keys here from the Clerk dashboard.

.env.local

Let’s create an API route that will handle the Clerk webhook. This handler will live in app/api/clerk/route.ts and will have the URL of your-app.com/api/clerk.

Webhooks are POST requests by default, so let’s create a handler for receiving POST requests.

app/api/clerk/route.ts

The webhook event data is available as the request payload. Let’s parse it out and log it to the console.

app/api/clerk/route.ts

Clerk provides a WebhookEvent type for strong typescript inference. For now we will simply assert the webhook payload to be of this type.

Let’s also create a simple GET handler to test if we can access this URL.

app/api/clerk/route.ts

Add this endpoint as a public route to the Clerk middleware

middleware.ts

Start the development server.

Now we can navigate to this endpoint in the browser.

Endpoint GET response screenshot

That’s all we need to setup a simple webhook endpoint! Now we can provide Clerk with a URL to this endpoint, and we can start receiving events.

However, we are not ready to test this locally yet. While the application is accessible on localhost in our machine, it’s not accessible to anything outside our local network. Since webhook requests are originated from Clerk’s servers, the localhost URL will just point back to the Clerk server instead of our machine.

Local network firewall access diagram

While we could provide Clerk with the public IP address of our machine, any incoming requests to our local home/work networks will be blocked by firewalls.

Firewall blocking external access diagram

To work around this problem, we can use a tunneling service like localtunnel, which creates a secure tunnel to our local machine from the cloud.

Localtunnel architecture diagram

Let’s setup localtunnel in a new terminal window.

Once the installation is complete, we can create a tunnel to our local server.

You should see an output in your terminal like this.

Localtunnel terminal output screenshot

Localtunnel will generate a random URL on the loca.lt domain that will point to your locally running server on port 3000. We can navigate to this new URL in our browser.

Localtunnel has a security mechanism built in to prevent abuse from malicious actors and phishing links. It asks for the public IP address of your local machine to ensure that it’s really you trying to access your application. Follow the instructions on this page to get your public IP address, and submit it on this page.

Once that’s done, we can access our application on this URL. We should also be able to access our webhook endpoint.

If the application doesn’t show up, make sure both the nextjs server and localtunnel are running on separate terminal windows.

Now we are ready to plug our endpoint into Clerk’s dashboard. Go to the Webhooks page, and click Add Endpoint. Enter the localtunnel URL here. You can also add a description for this endpoint.

Add webhook endpoint in Clerk dashboard screenshot

Here you can select which specific events you want to receive at this endpoint. Let’s leave these unselected for now so that we can receive webhooks for all events. Hit Create.

Once the webhook endpoint is created, we can navigate to the Testing tab. Here we can trigger an example event manually to test our webhook endpoint. Select any event from the dropdown, and hit Send Example.

Send example webhook event screenshot

If your application is running locally and tunneling is set up correctly, you should see a message in your console with the example event.

Webhook payload logged in console screenshot

You will also see a log entry in the Testing tab that shows the status of the webhook.

Webhook delivery status log screenshot

Even though the webhook was correctly received and logged to the console, the dashboard marks the webhook delivery as failed. To ensure that the delivery is marked as succeeded, we need to return a success response from our endpoint.

app/api/clerk/route.ts

Let’s send another example event. This time it the webhook should be marked as succeeded.

Successful webhook delivery screenshot

Now we can test the webhook with real events. Navigate to your application and sign up with a new account. This should log two webhook events in the console - a user.created and a session.created event.

Congratulations, we now have a functioning webhook receiver in our application! We can now further explore what events are triggered by Clerk. For example,

  • Updating the user profile sends a user.updated event
  • Signing out of the application sends a session.ended event
  • Remotely signing out a different device will result in a session.revoked event
  • Creating a new organization will trigger an organization.created and an organizationMembership.created event

We can also see logs for real webhook events in the dashboard.

Clerk dashboard webhook logs screenshot

When you deploy this app to a cloud environment like Vercel, you will need to create a new endpoint in the Clerk dashboard that points to the deployed application instead of a localtunnel URL.

Note that localtunnel will generate a random URL everytime we start the tunnel, which means everytime we are testing with webhooks locally, we will need to create a new endpoint in the Clerk dashboard. To solve this, we can ask localtunnel to provision a specific URL by adding a --subdomain argument.

If the requested URL is available, it will be provisioned for us instead of a randomly generated URL. This will allow us to reuse the same endpoint in the Clerk dashboard everytime we are testing locally.

Webhook Use Cases

So now that we are receiving webhook events from Clerk, what can we do with it?

Data Synchronization

While Clerk’s own database acts as the primary source of truth for authentication and user management, you can create a copy of this data in your own database which gets updated asynchronously through webhooks. This allows you to query your own database for user data instead of relying on Clerk’s APIs, along with flexibility with the data model, complex queries, transactional guarantees, and real time behavior. This mechanism is called data synchronization.

Event Driven Systems

Some advanced use cases might rely on asynchronous workflows and background jobs, such as sending notifications to users or other external systems. These workflows can be triggered to execute when a webhook event is received, for example, sending new users an onboarding email to your application, or subscribing them to mailing lists for software updates and promotional campaigns. Such systems are called event driven systems.

Bring Your Own Email/SMS

Clerk allows you to bring your own Email and/or SMS servers for delivering auth-related messages which would usually be delivered by Clerk. Whenever an auth-related message is created, Clerk sends a webhook event with that message to your application. You can configure Clerk to not deliver these messages in the Clerk dashboard, and instead handle the delivery yourself by listening to the webhook events. (add links to HWR and docs)

We will walk through implementing some of these use-cases in future articles.

Webhook Best Practices

While setting up a simple webhook receiver for testing purposes is straightforward, operating a webhook-driven system in production requires some additional work. Clerk implements webhook deliveries through Svix, a service that specializes in handling webhook deliveries. Svix manages concerns like scalability, logging, retries, security, and delivery guarantees. However, we still need to ensure that our application is setup to receive and process webhooks correctly. Let’s explore some best practices for implementing webhook endpoints for production-ready applications.

Error Handling

Webhook deliveries are marked as successful or failed depending on the HTTP response returned by our webhook endpoint. A failed webhook delivery is retried with exponential backoff until it succeeds, ensuring that our application will never miss an event. The exponential backoff ensures that our application servers are not overloaded with retries and explode server resources.

Our webhook endpoints should be setup to return a successful response (20x) if everything went well. But in case of an error during the processing of a webhook, we can simply throw an error response (40x or 50x) and expect a retry, which often succeeds. We can also monitor the webhook status in the Clerk dashboard, which provides observability into failed webhook deliveries and help discover issues.

app/api/clerk/route.ts

Security

Since webhooks requests can originate on any remote server, webhook endpoints are vulnerable to attacks from malicious actors. Securing webhook endpoints is important to ensure malicious actors cannot make unwanted changes to your application.

Svix adds security measures to webhook requests by adding a secure hash in the request headers created using a secret key. We can use the svix library in our webhook endpoint to validate that the request was sent by a legitimate Svix server and not a malicious actor.

app/api/clerk/route.ts

We can get the webhook signing secret from the Clerk dashboard and store in a CLERK_WEBHOOK_SECRET environment variable.

Webhook signing secret screenshot

Now our webhook endpoint is fully secure and ready to be deployed to production servers.

Selective Events

In our walkthrough, we configured Clerk to trigger the webhook endpoint for all events. While this was useful for testing, we want to minimize the use of server resources by only processing events that we actually care about.

For production endpoints, we can apply event filters in the Clerk dashboard by selecting the events that we are processing in the application, and leaving everything else unselected.

Select webhook events screenshot

Summary

Webhooks play an important role in creating unified user experiences through integrations like data sync and event driven systems. In this article we setup a simple webhook endpoint, explored some use cases, and addressed concerns like security and error handling.

We will dive deep into specific use cases around data sync and event driven systems in future blog posts and walk through implementing them into our projects.

To learn more about webhooks, check out the ultimate webhooks guide, or to learn more about the webhook events exposed by Clerk, read the documentation.