Prerequisites
WORKSPACE_IDSALESFORGE_API_KEY- A publicly reachable URL that answers
2xxto receive deliveries
How it works
Each webhook gets its own secret, generated once and returned only in the create response. Every delivery is signed with HMAC-SHA256 over the event ID, the send timestamp, and the raw request body.1
Create a signed webhook
POST /workspaces/{workspaceID}/integrations/webhookstype is the event that triggers this webhook. Omit sequenceIds to receive the event from every sequence, or set it to scope the webhook to specific sequences.The response includes signingSecret:2
Read what arrives with each delivery
Example delivery used throughout this guide:
3
Verify the signature
- Split the signature header on
,, then each part on its first=, to readtandv1. - Reject the delivery if
tis more than 300 seconds from your current time. - Rebuild the signed content by joining the event ID, the
tvalue exactly as received, and the raw request body with literal.characters:event_id + "." + t + "." + raw_body. - Compute HMAC-SHA256 of that content using the full secret — including the
whsec_prefix — as the key, and compare the result tov1with a constant-time comparison.
4
Test your implementation
Run this known-good vector through your verifier before pointing it at live traffic:With the timestamp check disabled (the vector is old), it must return
true. Flip one byte of the secret, event ID, or body, and it must return false. If a mutation still passes, your verifier is reading something other than what it signs.