Verify Webhooks Requests

Learn how to use the signing secret to verify your webhooks.

To ensure that webhook requests are authentic and coming from Reloop, verify the signature included in the request headers. This prevents unauthorized requests from reaching your application logic.

Headers

Every delivery includes:

HeaderDescription
Reloop-IdEvent id (whev_…), same as body id
Reloop-TimestampUnix timestamp (seconds) used in the signature
Reloop-Signaturet=<timestamp>,v1=<hex hmac>

Signature algorithm

  1. Read the raw request body bytes (do not re-serialize JSON).
  2. Read Reloop-Timestamp (or parse t= from Reloop-Signature).
  3. Compute HMAC-SHA256 over the string `${timestamp}.${rawBody}` using your endpoint secret (whsec_…).
  4. Compare the hex digest to the v1= value with a constant-time compare.
  5. Reject if the timestamp is older than ~5 minutes (replay protection).
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyReloopWebhook(input: {
  secret: string;
  rawBody: string;
  signatureHeader: string;
  toleranceSeconds?: number;
}): boolean {
  const parts = Object.fromEntries(
    input.signatureHeader.split(",").map((p) => {
      const [k, ...rest] = p.trim().split("=");
      return [k, rest.join("=")];
    }),
  );
  const timestamp = Number(parts.t);
  const v1 = parts.v1;
  if (!Number.isFinite(timestamp) || !v1) return false;

  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > (input.toleranceSeconds ?? 300)) return false;

  const expected = createHmac("sha256", input.secret)
    .update(`${timestamp}.${input.rawBody}`)
    .digest("hex");

  try {
    const a = Buffer.from(expected, "hex");
    const b = Buffer.from(v1, "hex");
    return a.length === b.length && timingSafeEqual(a, b);
  } catch {
    return false;
  }
}

Payload shape

{
  "id": "whev_01h…",
  "type": "email.delivered",
  "created_at": "2026-07-22T12:00:00.000Z",
  "data": {
    "email_id": "em_…",
    "from": "hello@example.com",
    "to": ["user@example.com"],
    "subject": "Welcome",
    "status": "delivered"
  }
}

Why verify webhooks?

Verification is critical because it allows you to:

  • Confirm the request was signed with your endpoint secret
  • Reject forged events from third parties
  • Detect and drop replayed requests outside the time window

Was this page helpful?

Edit this page