Verify the signature
X-Webhook-Signature is a lowercase hexadecimal HMAC-SHA256 of the exact JSON request body, using your webhook signing secret. It has no sha256= prefix.
Capture the raw bytes before JSON parsing. Re-serializing JSON changes whitespace or field order and can invalidate the signature.
Node.js verification helper
Buffer, the header value and a secret from your secure environment. Reject missing or invalid signatures. Do not log the secret or private event data.
Queued delivery retries
Normal queued deliveries have a 15-second request timeout and up to five attempts. Failed attempts become eligible for retry after 2, 4, 8 and 16 minutes respectively. Processing timing depends on the worker schedule; these are eligibility delays, not a delivery-time guarantee. After the fifth failed attempt, a queued delivery is markedpermanently_failed.
The legacy direct-trigger path retries inline with shorter backoff and records failed attempts separately. Do not build a receiver that depends on one exact retry timetable. Use the delivery log as the source of truth for an individual attempt.
Duplicates, replay and ordering
Retries can repeat a payload, and ordering is not guaranteed. Keep your business action idempotent and store a fingerprint of accepted events where practical. The envelope does not promise a globally unique event ID. The signature authenticates the body, but it does not itself prevent replay. Acknowledge duplicates without repeating their side effects. Do not reject every old timestamp automatically: legitimate queued retries can arrive later than the original event.Test deliveries
Test requests can includeX-Webhook-Test: true. Treat tests separately from live workflows, but still validate their signatures. Test payloads do not guarantee every real event’s full data shape.