Skip to content

Verify signatures

Anyone can send a POST to your webhook URL. Every request from Vaartix is signed with your endpoint’s secret, so check the signature first and reject anything that doesn’t match.

Vaartix follows the open Standard Webhooks specification, so you can also use any Standard Webhooks library.

import express from 'express';
import { verifyWebhook, WebhookVerificationError } from 'vaartix';
const app = express();
app.post('/webhooks/vaartix', express.raw({ type: 'application/json' }), (req, res) => {
let event;
try {
event = verifyWebhook({
payload: req.body, // a Buffer, thanks to express.raw()
headers: req.headers,
secret: process.env.VAARTIX_WEBHOOK_SECRET!,
});
} catch (err) {
if (err instanceof WebhookVerificationError) return res.status(400).send('Invalid signature');
throw err;
}
res.sendStatus(200);
// Handle the event after responding, e.g. queue it.
if (event.type === 'email.bounced') markAddressBad(event.data.recipient);
});
  1. Take the webhook-id and webhook-timestamp headers and the raw body.
  2. Join them with dots: {webhook-id}.{webhook-timestamp}.{body}.
  3. Compute HMAC-SHA256 of that string. The key is your secret without the whsec_ prefix, base64-decoded.
  4. Base64-encode the result and compare it, in constant time, with each v1, entry in the webhook-signature header (entries are separated by spaces).
  5. Reject requests whose timestamp is more than 5 minutes from your clock, so an intercepted request can’t be replayed later.