Skip to main content
Every webhook Sly sends is HMAC-signed. You MUST verify the signature before trusting the payload — otherwise an attacker could POST forged events to your endpoint.

The header

Sly includes two headers on every delivery:
  • t — Unix timestamp of signing
  • v1 — HMAC-SHA256 signature of {timestamp}.{raw_body} using your webhook secret

Verification algorithm

Node.js (with SDK)

verifyWebhook throws on any failure (stale, malformed, or bad signature).

Node.js (manual, no SDK)

Use the raw body. If your framework parses JSON before handing it to you, re-serialization will change whitespace and break the signature. Register the webhook route with a raw-body parser or read from the stream directly.

Python

Go

Ruby

Where to find your secret

From the dashboard: Settings → Webhooks → [endpoint] → Secret. Or from the API:

Rotating secrets

Create a new secret before rotating:
Overlap mode accepts both old and new secrets for overlap_seconds. Deploy the new secret during the overlap, verify, then let the old one expire.

Common pitfalls

  • Parsing the body before verifying. Most frameworks do this by default. Opt out for the webhook route.
  • Timing-unsafe comparison. Always use crypto.timingSafeEqual / hmac.compare_digest / fixed_length_secure_compare.
  • Clock drift. If your server clock is more than 5 minutes off, every webhook will fail verification. Use NTP.
  • Stripping headers at the proxy. Check your reverse proxy or WAF isn’t removing X-Sly-* headers.