Converc|Docs

Webhooks

Signature Verification

Verify webhook signatures to ensure authenticity.

Signature header

Each webhook includes an X-IC-Signature header:

TEXT
t=timestamp,v1=signature

Compute an HMAC SHA-256 of:

TEXT
timestamp + "." + raw_body

Then compare the result to v1.

Use the raw request body (not JSON-parsed) to avoid signature mismatch.

We also send:

  • X-IC-Event (event type)
  • X-IC-Id (event id)

Example verification (Node)

TYPESCRIPT
"color:#c792ea">import crypto "color:#c792ea">from "color:#c3e88d">'node:crypto'

"color:#c792ea">const signature = req.headers["color:#c3e88d">'x-ic-signature']
"color:#c792ea">const timestamp = signature?.match(/t=(\d+)/)?.[1]
"color:#c792ea">const provided = signature?.match(/v1=([a-f0-9]+)/)?.[1]

"color:#c792ea">const payload = `${timestamp}.${rawBody}`
"color:#c792ea">const expected = crypto
  .createHmac("color:#c3e88d">'sha256', secret)
  .update(payload)
  .digest("color:#c3e88d">'hex')

"color:#c792ea">const valid =
  provided &&
  crypto.timingSafeEqual(
    Buffer."color:#c792ea">from(provided),
    Buffer."color:#c792ea">from(expected)
  )

Optionally reject signatures older than a few minutes to reduce replay risk.

Having issues? hello@converc.com.