Why verify
Your webhook endpoint is a public URL, so anyone could POST to it. Every
StockInsights delivery is signed with a secret only you and StockInsights know.
Verifying the signature on each request proves it genuinely came from
StockInsights and that the body was not altered in transit.
Verify the signature before you trust or act on any webhook payload.
Each delivery includes these headers:
How the signature works
The X-StockInsights-Signature header has two comma-separated fields:
t — the UNIX timestamp (seconds) when the signature was generated.
v1 — a hex-encoded HMAC-SHA256 of the string {t}.{raw_body}, keyed by
your signing secret.
The signed string is the timestamp, a literal ., then the exact raw request
body. To verify, recompute the HMAC and compare it to v1 in constant time.
Your signing secret is hex-encoded. Decode it to raw bytes before using it
as the HMAC key. Compute the HMAC over the raw request body exactly as
received — do not parse and re-serialize the JSON first, or the bytes (and the
signature) will differ.
Verify a signature
Using it in a handler
Timestamp tolerance and replay
The timestamp in t lets you reject old requests. StockInsights signs with the
current time, and the examples above reject anything more than 300 seconds
(5 minutes) from your server’s clock. This limits how long a captured request
could be replayed against your endpoint.
Keep your server clock in sync (NTP) so legitimate requests are not rejected for
clock drift. If your endpoint sits behind a proxy that buffers requests, make
sure the tolerance comfortably exceeds any added delay.
Rotating the secret
Rotating the signing secret (from Account Settings → Webhooks) issues a new
secret and invalidates the previous one immediately. There is no overlap
window in which both secrets verify, so plan the swap:
- Rotate in the dashboard and copy the new secret.
- Deploy it to your endpoint promptly.
Between those two steps, deliveries are signed with the new secret while your
endpoint still holds the old one, so they will fail verification.
What happens to those deliveries depends entirely on the status code your
handler returns. A 5xx (as in the examples above) is
retried, so the events land once
the new secret is deployed. A 4xx is treated as a permanent failure and
those events are dropped. If your handler returns 400 or 401 on an
invalid signature, change it to a 5xx before you rotate.
Rotation is only needed if the secret may have been exposed. You do not need to
rotate to recover a secret you did not save — it can be revealed again at any
time from the destination card in the dashboard.