Webhooks and local development
When you or a user of your application performs certain actions, a webhook can be triggered. You can see the full list of webhook events for a list of the actions that could result in a Webhook. Depending on the events subscribed to in the Webhooks page in the Clerk Dashboard, a webhook event will be triggered and sent to the specified endpoint in your application. When you are developing on your localhost, your application is not internet facing and can’t receive the webhook request. You will need to use a tool that creates a tunnel from the internet to your localhost. These tools will provide temporary or permanent URLs depending on the tool and the plan you subscribe to. Popular tools includengrok, localtunnel, and Cloudflare Tunnel.
Debugging webhook-related issues can be tricky, so the following sections address common issues and how to resolve them.
Check your Middleware configuration
Incoming webhook events will never be signed in — they are coming from a source outside of your application. Since they will be in a signed out state, the route should be public. The following example shows the recommended Middleware configuration for your webhook routes.Test the Route Handler or API Route
If you are having trouble with your webhook, you can create a basic Route Handler to test it locally.- Create a test route by adding the following file and code to your application:
- Run your application.
- Send a request to the test route using the following command:
{"message":"The route is working"}, then the basic Route Handler is working and ready to build on.
[!IMPORTANT] Your webhook needs to return a success code like200or201when it has been successfully handled. This will mark the webhook as successful in the Dashboard and prevent retries.
Check your configuration in the Clerk Dashboard
Whether you are developing locally or deploying to production, the webhook URL provided in your webhook endpoint must be exact and correct. The URL breaks down into three parts:- the protocol (
httpvshttps) - Whether in development using a tunnel or in production, the URL will almost always usehttpsso ensure that the protocol is correct. - the domain (
domain.com) - The domain needs to be exact. A common error in production is not including thewww.. Unlike entering a domain in your browser, a webhook will not be redirected fromdomain.comtowww.domain.com. If your application lives onwww.domain.comthen the webhook URL must use that. - the path (
/api/webhooks/user) - The path must match the path in your application.
Debug your tunnel and webhook delivery
If your webhook is still getting errors after testing its route locally and verifying the endpoint’s configuration in the Clerk Dashboard, you can further investigate the specific errors returned by the webhook. Depending on the type of error, your approach to fixing the webhook will vary.- In the Clerk Dashboard, navigate to the Webhooks page.
- Select the endpoint for which you want to test.
- In the Message attempts table, you will likely see that one or more of those attempts have failed. Select the failed attempt to expand it.
- In the details for the attempt, there will be a
HTTP RESPONSE CODE. The code will likely be either a500or a4xxerror, which will indicate there is some misconfiguration.
Common HTTP response codes
The following table has some of the common response codes you might see and what they indicate. This is not an exhaustive list and you may need to research the code or error you are receiving. See HTTP response status codes from MDN for reference.| Code | Information |
|---|---|
400 | Usually indicates the verification failed, but could be caused by other issues. |
401 | The request was not authorized. If your test in the Test the Route Handler or API Route section worked, you should not see this error. If you are seeing it, then you will need to configure your Middleware to accept the request. |
404 | The URL for the webhook was not found. Check that your application is running and that the endpoint is correct in the Clerk Dashboard. |
405 | Your route is not accepting a POST request. All webhooks are POST requests and the route must accept them. Unless you are using the route for something else, you can restrict the route to POST requests only. |
500 | The request made it to your application, but there is a code-related issue. This is likely a webhook verification issue or something in the webhook logic. See the following sections. |
Debug webhook verification
To verify the webhook, see the guide on webhooks for a detailed code example. You can also visit the Svix guide on verifying payloads. Diagnosing a problem in this part of the webhook can be challenging. Your best bet would be the liberal use ofconsole.log. You could log out the following to check if the values are correct:
- the signing secret
- the headers
- the
bodybefore verifying - the result of the
.verify()attempt
null or errors where they should be returning values.
Check your logic
Once you have verified the webhook, you will now be writing your own code to handle the values from the webhook. This could range from saving data to a database, or integrating with another system, to updating users or sending emails or SMS. If the webhook is verified and you’re seeing a500 status code or your webhook is not behaving as expected, remember that you can use console.log to help diagnose what the problem is. Console logs and errors will be displayed on your command line, allowing you to see what’s happening and address the bugs.