What is HMAC webhook verification?
HMAC webhook verification proves a webhook is genuine by signing each payload with a shared secret using a hash-based message authentication code, so the receiver can confirm both who sent it and that the payload was not altered in transit.
import crypto from 'node:crypto'
// X-Netexem-Signature: t=1748700343,v1=9f86d0818...
function verify(rawBody, header, secret) {
const [t, v1] = header.split(',').map((p) => p.split('=')[1])
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex')
// Constant-time compare to avoid timing attacks:
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(v1),
)
}Recompute the signature, compare in constant time, then trust.
Every webhook is signed, so you can trust it.
Every VanceTel webhook — inbound messages, delivery receipts and call events — is HMAC-SHA256 signed. Recompute the signature from the raw body and your signing secret, compare it in constant time, and only then act on the event. Your endpoint never trusts an unverified request.
HMAC verification in practice.
A customer replies to a text, and VanceTel POSTs a message.received event to your endpoint with a signature header. Your handler recomputes the HMAC-SHA256 over the raw body using your signing secret. The values match, so the reply is genuine and threads into your app. A forged request would fail the check and be dropped.
Keep reading.
HMAC webhook questions.
Want to see signed webhooks verified end to end? Book a walkthrough.
Why verify a webhook with HMAC?
A webhook endpoint is a public URL, so anyone could POST to it. An HMAC signature is computed from the payload and a secret only you and the sender know. If the signature on an incoming request recomputes to the same value, you know it came from the real sender and was not modified — otherwise you reject it.
How does VanceTel sign webhooks?
Every VanceTel webhook — inbound messages, delivery receipts and call events — carries an HMAC-SHA256 signature in a header. You recompute the signature from the raw body and your signing secret, compare it in constant time, and only then trust the event.
What happens if the signature does not match?
Treat the request as untrusted and reject it without acting on the payload. A mismatch means the request was not sent by VanceTel with your secret, or the body was altered in transit — either way it should never reach your business logic.