Webhook Security
Signature Algorithm
Stendly signs every webhook using HMAC-SHA256:
payload = timestamp + raw_body
signature = HMAC-SHA256(webhook_secret, payload)
header = "t=" + timestamp + ",v1=" + signature
Verification Process
- Extract the
X-Stendly-Signatureheader - Parse timestamp and signature from the header
- Recompute HMAC-SHA256 using your webhook secret
- Compare computed signature with the header using constant-time comparison
- Verify timestamp is within 5 minutes (prevents replay attacks)
SDK Verification
All SDKs handle this automatically:
event = client.webhooks.construct_event(
payload=request.get_data(),
signature_header=request.headers["X-Stendly-Signature"],
webhook_secret=WEBHOOK_SECRET
)
Best Practices
- Always verify signatures - never skip verification
- Use raw body - verify against the raw request body, not parsed JSON
- HTTPS only - never use webhooks over HTTP
- Rotate secrets - change webhook secret periodically
- Idempotent handlers - handle duplicate webhook deliveries safely