Verifying webhooks with the Svix libraries (Recommended)

Each webhook call includes three headers with additional information used for verification:

  • svix-id: The unique message identifier for the webhook message. This identifier is unique across all messages but will remain the same when the same webhook is being resent (e.g., due to a previous failure).

  • svix-timestamp: The timestamp in seconds since the epoch.

  • svix-signature: The Base64-encoded list of signatures, space-delimited.


First install the libraries if you haven't already:

npm install svix
// Or
yarn add svix

Then verify webhooks using the code below. The payload is the raw (string) body of the request, and the headers are the headers passed in the request.

Framework specific examples

Here are examples of how to adjust the above examples to your framework of choice.

Python (Django)

from django.http import HttpResponse

from svix.webhooks import Webhook, WebhookVerificationError

secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"

@csrf_exempt
def webhook_handler(request):
    headers = request.headers
    payload = request.body

    try:
        wh = Webhook(secret)
        msg = wh.verify(payload, headers)
    except WebhookVerificationError as e:
        return HttpResponse(status=400)

    # Do something with the message...

    return HttpResponse(status=204)

Python (Flask)

Python (FastAPI)

Node.js (Next.js)

The svix-example repo contains an example of how to verify and use webhooks in a Next.js application.

Node.js (Next.js 13 App Router)

Node.js (Netlify Functions)

Node.js (Express)

Note: When integrating this example into a larger codebase, you will have to make sure not to apply the express.json() middleware to the webhook route, because the payload has to be passed to wh.verify without any prior parsing.

Node.js (NestJS)

Initialize the application with the rawBody flag set to true. See the NestJS docs for details.

Node.js (Nuxt)

Go (Standard lib)

Go (Gin)

Rust (axum)

Add the webhook_in route below to an axum router.

Ruby (Ruby on Rails)

Once you've set up your project add a route to your config/routes.rb file at the top of the Rails.application.routes.draw block:

The route above declares that POST /webhook requests are mapped to the index action of WebhookController.

To create WebhookController and its index action, we'll run the controller generator (with the --skip-routes option because we already have an appropriate route):

Rails will create several files for you:

Now we can add our verification logic to the newly created app/controllers/webhook_controller.rb file:

PHP (Laravel)

In your routes/api.php file add the following after the last use directive:

Last updated