Skip to main content
When you set a secret on a webhook subscription, Struct signs every delivery with an HMAC so you can confirm the request is genuine and the body was not tampered with in transit.
Always verify signatures in production. Your endpoint is a public URL — without verification, anyone who discovers it can POST forged events to it.

The signature header

Each delivery includes:
  • Algorithm: HMAC-SHA256.
  • Key: the secret you set when creating (or rotating) the webhook.
  • Message: the raw request body bytes, exactly as received — do not re-serialize the JSON before computing the HMAC.
  • Encoding: lowercase hex, prefixed with sha256=.
There is no timestamp component, so you verify the body alone.

How to verify

Compute the HMAC-SHA256 of the raw body with your secret, prefix it with sha256=, and compare it to the header using a constant-time comparison.
Frameworks that auto-parse JSON often discard the raw body. Make sure you hash the bytes as received — re-serializing the parsed object can reorder keys or change whitespace and break the signature.

Other delivery headers

Every delivery also carries these headers (handy for logging and routing):

Rotating your secret

If a secret may have leaked, rotate it. New deliveries are signed with the new secret immediately:
Last modified on June 3, 2026