Skip to content

Verifying signed webhooks

Headers, signature scheme and a verification example for outgoing webhooks.

Updated

Headers

X-UptimeGuard-Event (incident_opened, incident_resolved, tls_expiring, test), X-UptimeGuard-Delivery (unique id for deduplication), X-UptimeGuard-Timestamp (Unix seconds) and X-UptimeGuard-Signature (v1=<hex>).

Signature

HMAC-SHA256 with your channel's signing secret over the string "<timestamp>.<raw body>". Reject requests older than five minutes and compare signatures in constant time.

Node.js example

import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(rawBody, headers, secret) {
  const ts = headers["x-uptimeguard-timestamp"];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = "v1=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
  const given = headers["x-uptimeguard-signature"] ?? "";
  return expected.length === given.length && timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}

Destinations

Webhook URLs must be public https endpoints; they pass the same destination policy as monitors.