Choosing the right webhook fields, and no more

Meta sends nothing until three things are true: the field is switched on, the Page is connected to your app, and the verification handshake completed. Miss any one and the symptom is identical - an endpoint that is never called.

The handshake

When you save a callback URL, Meta makes one GET with three query parameters. Echo the challenge only when the token matches:

@app.get("/hooks/meta")
def verify(request: Request):
    args = request.query_params
    if args.get("hub.mode") == "subscribe" and \
       args.get("hub.verify_token") == VERIFY_TOKEN:
        return PlainTextResponse(args.get("hub.challenge"))
    raise HTTPException(403)

Return the challenge as plain text, not JSON. A quoted string is not the challenge and the callback silently fails to save.

Fields worth switching on

Meta webhook fields
FieldCarriesSwitch on?
messagesInbound messages and their statusYes, always
messaging_postbacksButton taps and menu selectionsIf you use buttons
message_reactionsReactions on your messagesRarely useful
feedComments and posts on the PageIf you answer comments
messaging_seenRead receipts from the customerNoisy; only if you use it

Switch on what you handle and nothing else. Every extra field is traffic your endpoint has to acknowledge, and an endpoint that 500s on an event type it did not expect gets its deliveries retried and then throttled - which takes the fields you do want down with it.

The Page connection people forget

Subscribing the app to a field is not the same as subscribing the Page to the app. Both are required. The second is a separate call per Page, and it is the step that gets missed when a second Page is added six months later - at which point one Page works and one does not, which is at least a more informative symptom.

Handling what arrives

Everything in webhooks done properly applies: verify the signature on raw bytes, assume duplicates, do not trust arrival order, acknowledge before working. Meta batches events, so one POST can carry several - iterate the entries rather than reading the first.

Questions people actually ask

Why is my Meta webhook not receiving anything?

Three usual causes: the field is not switched on, the Page is not connected to the app, or the verification handshake never completed. All three look identical - silence.

What is the hub.challenge request?

A one-off GET Meta makes when you save a webhook URL. Your endpoint must echo hub.challenge back when hub.verify_token matches yours, or the callback is never registered.

Njiwa

One inbox for WhatsApp, Facebook and Instagram, and an API that sends over either WhatsApp rail. 7 days free, no card.

Start a trial See pricing