Skip to content
Back to blog
Engineering

Verify Authevo webhooks with the HMAC signature

By The Authevo Team5 min read

Webhooks let Authevo push events to your server — a delivery status update for a code, or a low-balance warning before sends pause. But your webhook URL is a public endpoint anyone could POST to, so before you act on an event you should confirm it actually came from Authevo. Every webhook we send is signed for exactly that.

The signature header

Each request carries X-Authevo-Signature: sha256=<hex>, where the hex is an HMAC-SHA256 of the exact raw request body, keyed by your webhook secret. That secret is shown once when you register and can be rotated from your dashboard at any time.

Verify it in a few lines

On your endpoint, read the raw request body (the exact bytes, before any JSON re-parsing), compute the same HMAC with your secret, and compare it to the header in constant time. In Node.js, that’s const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex"); — then crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header)). If they don’t match, reject the request with a 401.

A few rules of thumb

  • Always compare in constant time (timingSafeEqual), never with === — it avoids leaking the signature through timing.
  • Hash the raw body bytes, not a re-serialized object — re-stringifying JSON can reorder keys and break the match.
  • Rotate the secret from your dashboard if it’s ever exposed; verification uses the new secret right away.

Once a request checks out, branch on the event — an otp.status_update tells you a code’s delivery state, and an account.low_balance is your cue to top up before sends pause. Ignore anything that fails the signature check.