whsec_. It is shown once when you create the endpoint; find or roll it later under Webhooks → your endpoint → Signing secret.
How it works

Relay signs the timestamp and the raw body with the endpoint's secret. Your server checks the timestamp, recomputes the signature and compares.
- Split the header on
,and readtandv1. - Reject the request if
tis more than 5 minutes from your server’s clock. This stops someone resending a request they captured. - Compute HMAC-SHA256 of
{t}.{raw body}with your signing secret, as lowercase hex. - Compare it with
v1in constant time. Answer400if they differ.
Use the raw body
Sign and compare the bytes exactly as they arrived. If your framework parses JSON first, the re-serialized body can differ by a space or a key order and the signature won’t match. In Express, useexpress.raw({ type: "application/json" }) on the webhook route.
Example
relay.webhooks.verify.
Rolling the secret
When you roll a secret, Relay signs with both the old and the new one for 24 hours and sends twov1 values in the header. Accept the request if either matches, and deploy the new secret within the day.