> ## Documentation Index
> Fetch the complete documentation index at: https://developers.1-funnel.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify webhook signatures

> DEC-WH-S01 HMAC-SHA256 verification for outbound deliveries.

<Warning>
  **Developer Preview**

  This documentation describes the upcoming 1Funnel External Integration API.

  The documented API endpoints and authentication services are not yet available
  for public integration.

  You can explore the API specifications, request and response schemas, webhook
  events, and integration guides.

  Sandbox and production availability will be announced separately.
</Warning>

Headers on every delivery:

* `1Funnel-Webhook-Id`
* `1Funnel-Webhook-Timestamp` (Unix epoch seconds)
* `1Funnel-Webhook-Signature` (`v1=<lowercase_hex>`)

Signed bytes: `timestamp + "." + raw_request_body`.

Replay tolerance: ±5 minutes. Compare digests in constant time. Preserve the
raw body — do not re-serialize JSON before verification.

```javascript theme={null}
import crypto from "node:crypto";

function verify({ rawBody, timestamp, signatureHeader, secret }) {
  if (!signatureHeader.startsWith("v1=")) return false;
  const provided = signatureHeader.slice(3);
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`, "utf8")
    .digest("hex");
  const a = Buffer.from(provided, "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

Each retry uses a fresh timestamp and signature; the event id stays stable.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.