Kaiten
Webhooks

Verifying Signatures

Secure your webhook endpoints with Svix signature verification.

Verifying Signatures

Every webhook delivery from Kaiten includes a signature that you should verify to ensure the payload hasn't been tampered with.

Headers

Each delivery includes these headers:

HeaderDescription
svix-idUnique message identifier
svix-timestampUnix timestamp of the delivery attempt
svix-signatureHMAC-SHA256 signature

Verification

The easiest way to verify signatures is with the Svix SDK:

Node.js:

import { Webhook } from 'svix';

const wh = new Webhook(process.env.WEBHOOK_SECRET);

app.post('/webhook', (req, res) => {
  try {
    const payload = wh.verify(req.body, req.headers);
    // Process verified payload
    res.status(200).send('OK');
  } catch (err) {
    res.status(400).send('Invalid signature');
  }
});

Python:

from svix.webhooks import Webhook

wh = Webhook(os.environ["WEBHOOK_SECRET"])

@app.post("/webhook")
async def handle_webhook(request):
    payload = wh.verify(await request.body(), request.headers)
    # Process verified payload
    return {"status": "ok"}

Go:

import svix "github.com/svix/svix-webhooks/go"

wh, _ := svix.NewWebhook(os.Getenv("WEBHOOK_SECRET"))

func handleWebhook(w http.ResponseWriter, r *http.Request) {
    payload, err := wh.Verify(body, r.Header)
    if err != nil {
        http.Error(w, "Invalid signature", 400)
        return
    }
    // Process verified payload
}

Getting Your Webhook Secret

The signing secret is provided when you create a webhook endpoint. You can also retrieve it from the Svix dashboard (if self-hosting Svix) or from the Kaiten API.

On this page