Skip to main content
Verify every webhook before parsing it into trusted application data. Signal signs the timestamp and exact raw request body with the endpoint secret.

Headers

The signed bytes are:

Node.js example

This function expects the raw body string before JSON parsing:

Verification sequence

1

Read the raw body

Disable automatic body consumption for this route or preserve the raw bytes alongside the parsed value.
2

Read both headers

Reject the request if either header is missing or malformed. HTTP header names are case-insensitive.
3

Check timestamp freshness

Parse epoch seconds and reject requests outside your chosen tolerance. Account for small clock skew and keep server time synchronized.
4

Calculate HMAC

Join timestamp, a dot, and the exact raw body. Use HMAC-SHA256 with the endpoint secret.
5

Compare in constant time

Compare equal-length byte sequences with a timing-safe function.
6

Parse and enqueue

Only after verification, parse JSON and durably accept the event.
Serializing parsed JSON again changes whitespace, key ordering, or escaping and breaks verification. Always sign the body exactly as received.

Secret handling

Store one secret per endpoint in a secret manager. Do not log it or include it in exception output. Endpoint list and get responses do not return it after creation.