Developers

Quickstart

Receive and verify your first webhook in a few minutes.

Create a receiver

Your endpoint must be a public HTTPS URL that accepts POST requests and answers with a 2xx status. Install Express:

npm i express

This receiver verifies the signature and acknowledges the event:

server.ts
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.ZAHER_WEBHOOK_SECRET!; // whsec_…
const app = express();

// Keep the raw body: the signature is computed over the exact bytes sent.
app.post(
  "/webhooks/zaher",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const body = req.body.toString("utf8");
    if (!isValid(body, req.header("X-Zaher-Signature"), req.header("X-Zaher-Timestamp"))) {
      return res.sendStatus(400);
    }

    const event = JSON.parse(body);
    console.log("Received", event.type, event.id);

    res.sendStatus(200); // acknowledge fast; do slow work afterwards
  }
);

function isValid(body: string, signatureHeader?: string, timestamp?: string) {
  if (!signatureHeader || !timestamp) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected = createHmac("sha256", SECRET)
    .update(`${timestamp}.${body}`)
    .digest();

  return signatureHeader.split(",").some((part) => {
    const [version, hex] = part.trim().split("=");
    const received = Buffer.from(hex ?? "", "hex");
    return (
      version === "v1" &&
      received.length === expected.length &&
      timingSafeEqual(received, expected)
    );
  });
}

app.listen(3000);

Testing locally

Expose your local server over HTTPS with a tunnel such as ngrok http 3000 or cloudflared tunnel, and use the tunnel URL as your endpoint.

Add the endpoint in Zaher

  1. In your dashboard, open Settings → Webhooks and click Add endpoint.
  2. Paste your HTTPS URL and pick the events to receive.
  3. Copy the signing secret shown after saving and set it as ZAHER_WEBHOOK_SECRET in your receiver. You can reveal it again later from the endpoint page.

Send a test event

On the endpoint page, choose an event under Send a test event and click Send test. Zaher sends sample data with "test": true through the real signing and delivery pipeline. The attempt appears in the Delivery log with your server's response.

Next steps

On this page