DocumentationVerify HMAC signature

Verify HMAC signature

Validate X-MailingCore-Signature on your server.

Each outbound webhook includes a signature so you can confirm the payload came from MailingCore and was not altered.

Header format

X-MailingCore-Signature: t=1719763200,v1=5f7b3c...
  • t — Unix timestamp of the delivery
  • v1 — HMAC-SHA256 in hexadecimal

Verification algorithm

const crypto = require('crypto')

function verifyWebhook(rawBody, signatureHeader, secret) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((p) => p.split('='))
  )
  const timestamp = parts.t
  const receivedSig = parts.v1

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')

  return crypto.timingSafeEqual(
    Buffer.from(receivedSig, 'hex'),
    Buffer.from(expected, 'hex')
  )
}

Best practices

  1. Read the raw body without parsing JSON before verifying
  2. Reject very old timestamps (replay) — recommended tolerance ±5 min
  3. Use timingSafeEqual to compare signatures
  4. Respond 200 quickly and process in your own queue

Example payload

The JSON body includes type (event name), data (email or contact details), and tenant metadata. Exact structure depends on the event; see the OpenAPI reference at /docs-json for the current schema.