Skip to main content
LeadVector signs each delivery the way Standard Webhooks specifies, so its libraries verify it in one call. Each library checks the signature with your endpoint’s secret and refuses a delivery whose webhook-timestamp is more than five minutes off your clock, which stops a captured request from being sent again later. Verify the body exactly as it arrived: parse it only after the check. Re-serialized JSON can differ by a space and fail. Then store the event somewhere durable (a queue, a database table) before you answer 2xx, and answer an error if you can’t: a 2xx marks the delivery as succeeded, and LeadVector won’t send it again. The examples below do the work after answering, from what they stored.

With a library

By hand

Without a library, the check is:
  1. Take the secret after whsec_ and decode it from base64: that is the key.
  2. Build the signed content: {webhook-id}.{webhook-timestamp}.{body}, with the raw body.
  3. Compute HMAC-SHA256 of it with the key, and encode the result in base64.
  4. webhook-signature holds one or more signatures, space-separated, each v1, and a base64 value. The delivery is genuine if any of them equals yours. Compare in constant time.
  5. Refuse it if webhook-timestamp (Unix seconds) is more than five minutes from now.

When a rotation overlaps

While a rotated secret’s old one still signs (overlapHours), each delivery carries a signature from each, and one that either secret verifies is genuine. Switch your receiver to the new secret any time in that window; the libraries above accept a delivery if any of its signatures matches the secret you gave them.