Provider reference / Meta

How Meta (Instagram, Facebook, Threads) delivers webhooks

Meta retries with decreasing frequency for 36 hours, then drops the event. The hub.challenge handshake, signature format, and a Node verifier.

Delivery behaviour

Read from the vendor's own documentation, last checked 2026-08-06. Where the vendor states no number, this table carries none.

Response budgetnot published by the vendor
RetryRetried with decreasing frequency over 36 hours. Unacknowledged notifications are dropped after that
Gives upnot published by the vendor
Sourcehttps://developers.facebook.com/docs/graph-api/webhooks/getting-started

Signature

Verified against a working verifier proven by a test suite, not read from documentation. Last verified 2026-08-20.

AlgorithmHMAC-SHA256
Signed payloadraw body
Encodinghex
Headerx-hub-signature-256 = sha256=hex
Tolerancenone enforced

Verify it

The raw request body, byte for byte, before any JSON parsing. Every scheme on this page breaks the moment a framework re-serializes the payload.

const crypto = require("node:crypto");

// Same scheme as GitHub: "sha256=" + hex HMAC of the raw body, keyed by the
// app secret.
const expected =
  "sha256=" +
  crypto.createHmac("sha256", appSecret).update(rawBody).digest("hex");
const valid = crypto.timingSafeEqual(
  Buffer.from(req.headers["x-hub-signature-256"]),
  Buffer.from(expected),
);

Before any of this runs, Meta must accept the callback URL: it sends a GET carrying hub.mode=subscribe and expects hub.challenge echoed back verbatim. No echo, no subscription.

What bites

Meta publishes the retry window (36 hours, decreasing frequency, then the notification is dropped) but not a per-request response budget or a disable threshold. Where the vendor states no number, this page carries none.

Read more

AnyHook sits in front of endpoints that receive from Meta: it answers inside the budget above, retries on its own schedule when your server is down, and keeps every event replayable. Change one URL, keep your code.

How it works →