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.
The signature header
Each delivery includes:- Algorithm: HMAC-SHA256.
- Key: the
secretyou 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=.
How to verify
Compute the HMAC-SHA256 of the raw body with your secret, prefix it withsha256=, 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):| Header | Description |
|---|---|
X-Webhook-ID | UUID of the webhook subscription that produced the delivery. |
X-Delivery-ID | UUID of this specific delivery. Matches the id field in the body — use it to deduplicate. |
X-Event-Type | The event name, e.g. trader_whale_trade. |
X-Attempt | Delivery attempt number, starting at 1. Struct retries failed deliveries — see the attempt field. |
X-Webhook-Signature | The HMAC signature described above (only present when a secret is set). |