Skip to documentation
Beacon Docs
TypeScript SDK

Verify webhook signatures

Verify the exact Beacon webhook body before processing a lifecycle event.

Open Markdown

Use the raw request body and the one-time signing secret from Beacon.

import {
  verifyBeaconWebhookSignature,
  type BeaconWebhookEvent,
} from "@beacon/sdk";

export async function POST(request: Request) {
  const rawBody = await request.text();
  const valid = await verifyBeaconWebhookSignature({
    rawBody,
    secret: process.env.BEACON_WEBHOOK_SECRET!,
    signatureHeader: request.headers.get("x-beacon-signature"),
  });

  if (!valid) return new Response("Invalid signature", { status: 401 });

  const event = JSON.parse(rawBody) as BeaconWebhookEvent;
  await saveEventOnce(event.id, event);
  return new Response(null, { status: 204 });
}

Do not parse and reserialize the body before verification. The default timestamp tolerance is five minutes.

Use a unique database constraint on event.id. Beacon keeps the event ID stable when it retries a delivery.

Read Publication webhooks for event names, retry rules, and ordering behavior.