Sync Clerk data to your app with webhooks
You will learn the following:
- Set up ngrok
- Set up a webhook endpoint
- Create the webhook
- Get type inference for your webhook events
- Test the webhook
- Configure your production instance
Before you start
The recommended way to sync Clerk data to your app is through webhooks.
In this guide, you'll set up a webhook in your Next.js app to listen for the user.created
event, create an endpoint in the Clerk Dashboard, build a handler, and test it locally using ngrok and the Clerk Dashboard.
Clerk offers many events, but three key events include:
user.created
: Triggers when a new user registers in the app or is created via the Clerk Dashboard or Backend API. Listening to this event allows the initial insertion of user information in your database.user.updated
: Triggers when user information is updated via Clerk components, the Clerk Dashboard, or Backend API. Listening to this event keeps data synced between Clerk and your external database. It is recommended to only sync what you need to simplify this process.user.deleted
: Triggers when a user deletes their account, or their account is removed via the Clerk Dashboard or Backend API. Listening to this event allows you to delete the user from your database or add adeleted: true
flag.
These steps apply to any Clerk event. To make the setup process easier, it's recommended to keep two browser tabs open: one for your Clerk Webhooks page and one for your ngrok dashboard.
Set up ngrok
To test a webhook locally, you need to expose your local server to the internet. This guide uses ngrok which creates a forwarding URL that sends the webhook payload to your local server.
- Navigate to the ngrok website to create an account.
- Follow steps 1 and 2 in ngrok's install guide.
- In the ngrok dashboard, select Domains from the sidebar.
- Select Create Domain. After the page refreshes, the Start a Tunnel panel will open.
- In the Start a Tunnel panel, select the command generated by ngrok. This command provides a free, non-ephemeral domain and starts a tunnel with that domain. The command should resemble
ngrok http --url=fawn-two-nominally.ngrok-free.app 80
. - Paste the command in your terminal and change the port number to match your server's port. For this guide, replace
80
with3000
, then run the command in your terminal. It will generate a Forwarding URL. It should resemblehttps://fawn-two-nominally.ngrok-free.app
. - Save your Forwarding URL somewhere secure. Close the panel.
Set up a webhook endpoint
- In the Clerk Dashboard, navigate to the Webhooks page.
- Select Add Endpoint.
- In the Endpoint URL field, paste the ngrok Forwarding URL you saved earlier, followed by
/api/webhooks
. This is the endpoint that Svix uses to send the webhook payload. The full URL should resemblehttps://fawn-two-nominally.ngrok-free.app/api/webhooks
. - In the Subscribe to events section, scroll down and select
user.created
. - Select Create. You'll be redirected to your endpoint's settings page. Keep this page open.
Add your Signing Secret to .env.local
To verify the webhook payload, you'll need your endpoint's Signing Secret. Since you don't want this secret exposed in your codebase, store it as an environment variable in your .env.local
file during local development.
- On the endpoint's settings page, copy the Signing Secret.
- In your project's root directory, open or create an
.env.local
file, which should already include your Clerk API keys. Assign your Signing Secret toSIGNING_SECRET
. The file should resemble:
Set the webhook route as public in your Middleware
Incoming webhook events don't contain auth information. They come from an external source and aren't signed in or out, so the route must be public to allow access. If you're using clerkMiddleware()
, ensure that the /api/webhooks(.*)
route is set as public. For information on configuring routes, see the clerkMiddleware()
guide.
Install svix
Clerk uses svix
to deliver webhooks, so you'll use it to verify the webhook signature. Run the following command in your terminal to install the package:
Create the endpoint
Set up a Route Handler that uses svix
to verify the incoming Clerk webhook and process the payload.
For this guide, the payload will be logged to the console. In a real app, you'd use the payload to trigger an action. For example, if listening for the user.created
event, you might perform a database create
or upsert
to add the user's details to the user's table.
If the route handler returns a 4xx or 5xx code, or no code at all, the webhook event will be retried. If the route handler returns a 2xx code, the event will be marked as successful, and retries will stop.
Narrow to a webhook event for type inference
WebhookEvent
encompasses all possible webhook types. Narrow down the event type for accurate typing for specific events.
In the following example, the if
statement narrows the type to user.created
, enabling type-safe access to evt.data with autocompletion.
To handle types manually, import the following package from your backend SDK (e.g., @clerk/nextjs/server
):
DeletedObjectJSON
EmailJSON
OrganizationInvitationJSON
OrganizationJSON
OrganizationMembershipJSON
SessionJSON
SMSMessageJSON
UserJSON
Test the webhook
- Start your Next.js server.
- In your endpoint's settings page in the Clerk Dashboard, select the Testing tab.
- In the Select event dropdown, select
user.created
. - Select Send Example.
- In the Message Attempts section, confirm that the event is labeled with
Succeeded
.
Handling failed messages
- In the Message Attempts section, select the event labeled with
Failed
. - Scroll down to the Webhook Attempts section.
- Toggle the arrow next to the Status column.
- Review the error. Solutions vary by error type. For more information, refer to the Debug your webhooks guide.
Trigger the webhook
To trigger the user.created
event, you can do either one of the following:
- Edit your user in the Clerk Dashboard.
- Select the
<UserProfile />
component in your app to edit your profile.
You should be able to see the webhook's payload logged to your terminal. You can also check the Clerk Dashboard to see the webhook attempt, the same way you did when testing the webhook.
Configure your production instance
- When you're ready to deploy your app to production, follow the guide on deploying your Clerk app to production.
- Create your production webhook by following the steps in the previous Set up a webhook endpoint section. In the Endpoint URL field, instead of pasting the ngrok URL, paste your production app URL.
- After you've set up your webhook endpoint, you'll be redirected to your endpoint's settings page. Copy the Signing Secret.
- On your hosting platform, update your environment variables on your hosting platform by adding Signing Secret with the key of
SIGNING_SECRET
. - Redeploy your app.
Feedback
Last updated on