Developer docs

Verify webhooks

Every webhook is signed with your secret. Reject the request if the signature does not match.

Request

Headers

X-Ildstedet-Webhook-Signaturehex stringRequired
HMAC-SHA256 of the raw body, hex-encoded.
X-Ildstedet-Webhook-VersionstringRequired
Payload version. The same value is in the JSON field webhookVersion.

Check

  1. Read the raw body bytes. Do not parse JSON first and re-serialize it.
  2. Compute HMAC-SHA256 of those bytes with your signing secret.
  3. Compare the hex digest to the signature header with a timing-safe comparison.
  4. Parse and handle the JSON only after the comparison succeeds.

Example

Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'

export function verifyIldstedetWebhook(rawBody, signature, secret) {
  const digest = createHmac('sha256', secret).update(rawBody).digest('hex')
  const actual = Buffer.from(signature ?? '', 'utf8')
  const expected = Buffer.from(digest, 'utf8')
  if (actual.length !== expected.length) return false
  return timingSafeEqual(actual, expected)
}
The signature covers the entire raw body, including webhookVersion. Webhooks are sent to HTTPS endpoints only.