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:
| Header | Description |
|---|---|
svix-id | Unique message identifier |
svix-timestamp | Unix timestamp of the delivery attempt |
svix-signature | HMAC-SHA256 signature |
Verification
Using the Svix SDK (Recommended)
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.

