What a signed webhook is, and why your integration must verify it

Without verification, anyone who knows the URL can send you fake events.

A webhook is the platform sending your server an HTTP request whenever an event happens. The signature is what proves the request really came from it. Without verifying the signature your endpoint is open to anyone: they can send “payment received” and your server will believe it.

Verify against the raw bytes

The signature is computed over the request body exactly as it was sent. If any middleware parses the JSON and re-serialises it, the result will not match — and the usual response to that, unfortunately, is somebody switching verification off. You have to capture the raw bytes before anything touches them.

Acknowledge first, process second

Return 200 as soon as you have (a) verified the signature and (b) durably written the raw payload somewhere. The real work happens afterwards, from a queue. Platforms retry on any non-200 and drop the notification after a retry window, so a handler that is slow because a downstream service is slow turns a temporary outage into permanent message loss. A single notification can also carry up to 1,000 updates, which cannot be processed inside a response deadline.

And here Meta's own pages disagree

How long does the platform keep retrying before it drops a notification? Meta's Graph API webhooks page says 36 hours; its Cloud API page says up to 7 days. **Both are Meta's, and they disagree.** We are not going to pick one and write it down as fact. The right design is not to depend on the number at all: write the payload early, make handling order-independent, and be idempotent — then the number does not matter.

Duplicates are expected, not exceptional

  • Assume every event can arrive more than once, and that order is not guaranteed.
  • Derive the idempotency key from the platform's own identifier — never from a hash of the payload, because the payload for the same event can differ between the original and the retry.
  • That key belongs in a column with a unique constraint, not in an in-memory cache.
  • A timeout is indistinguishable from a failure to the sender — so slow processing is itself what creates the duplicates.

The question to ask anyone building an integration for you: “do you verify the signature against the raw bytes?” If the answer is “the what?”, that is the answer.

Sources

Every figure and rule on this page has its source here, with the date it was read. What is not here is not on the page.

  • The webhook rules: ordering, signature, idempotency — with the recorded conflict between Meta's two pages.claude/skills/platform/webhook-reliability.md (2026-09-15)

Tell us what you need

Write us a couple of lines about the project and we will reply within 24 hours on working days. In a hurry? Call us, or send a WhatsApp message.

Request a quote