Skip to main content
Every webhook delivery is signed with HMAC-SHA256. Verify the signature to confirm the payload came from AgentRef and wasn’t tampered with.
The Node.js and Python SDKs do not currently expose a webhook signature helper. Use the manual verification algorithm below, or wrap it in your own helper for your framework.

Signature Format

AgentRef sends three headers with each webhook delivery:

Verification Algorithm

1

Get the raw request body

Read the body as a raw string – do not parse JSON first. Parsing and re-serializing can change whitespace or key order, breaking the signature.
2

Read the headers

Extract svix-id, svix-timestamp, and svix-signature from the request headers.
3

Compute the expected signature

Build the signed content string: {svix-id}.{svix-timestamp}.{body}Compute HMAC-SHA256 of this string using your webhook signing secret (the part after whsec_, base64url-decoded).
4

Compare signatures

Base64-encode your HMAC result and compare it to the signature value (after the v1, prefix) using constant-time comparison.

Code Examples

Common Pitfalls

Don’t parse the body before verifying. If your framework automatically parses JSON, use a raw body parser for the webhook route. JSON.parse(JSON.stringify(body)) may reorder keys or change whitespace, producing a different signature.
  • Use express.raw() in Express (not express.json()) for the webhook route
  • In Next.js App Router, use await request.text() to get the raw body
  • Always use constant-time comparison (crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to prevent timing attacks
  • Validate the timestamp – reject events older than 5 minutes to prevent replay attacks