Without verification, any server that discovers your webhook URL could send fake events. Inbox signs every webhook delivery with your signing secret so you can confirm it’s authentic before processing.
This format prevents replay attacks — the timestamp is part of the signed payload, so an attacker can’t reuse a captured signature with a different body or at a different time.
import express from "express";const app = express();// Important: use raw body for signature verificationapp.use("/webhooks/inbox", express.raw({ type: "application/json" }));app.post("/webhooks/inbox", (req, res) => { const signature = req.headers["x-inbox-signature"] as string; const rawBody = req.body.toString(); if (!signature) { return res.status(401).json({ error: "Missing signature" }); } const result = verifyWebhookSignature( rawBody, signature, process.env.INBOX_WEBHOOK_SECRET!, ); if (!result.valid) { return res.status(401).json({ error: result.reason }); } const event = JSON.parse(rawBody); // Process the verified event console.log("Verified event:", event.type, event.id); res.sendStatus(200);});app.listen(3000);
Make sure you verify against the raw request body string, not a
re-serialized version. Parsing the JSON and re-serializing it may change
whitespace or key ordering, which will produce a different signature.