Skip to main content

Verify Webhook Signatures

Every webhook delivery must be authenticated before you trust or process the payload.

Verification Inputs

To verify a webhook, use:
  • the raw request body exactly as received
  • the signature header sent by Zentra
  • the webhook secret returned when the endpoint was created
Do not JSON-parse and then re-serialize the payload before verification. Use the raw body bytes.
  1. Read the raw request body
  2. Extract the Zentra signature header
  3. Compute the expected signature with your stored webhook secret
  4. Compare signatures in constant time
  5. Reject invalid payloads with 401 or 400
  6. Only then parse and process the event

Example

import crypto from "crypto";

function verifyZentraWebhook(rawBody, signatureHeader, webhookSecret) {
  const expected = crypto
    .createHmac("sha256", webhookSecret)
    .update(rawBody)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

Reliability Requirements

  • Make processing idempotent because deliveries may be retried
  • Store delivery or event identifiers before applying business effects
  • Return 2xx only after the event is durably accepted by your system
  • Keep delivery handling fast; move heavy work to async jobs

Configure Webhooks

Create endpoints and store webhook secrets

Handling Webhooks

Full implementation guide with retry-safe patterns