WhatsApp Cloud API Webhook Verification Fails in n8n (hub.challenge not returning)

<!-Hi everyone,
I am trying to connect WhatsApp Cloud API webhook to n8n, but Meta webhook verification keeps failing.
Error shown in Meta:
“The callback URL or verify token couldn’t be validated.”
My setup:
Webhook Node:

  • HTTP Method: GET
  • Path: whatsapp
  • Production URL: https://YOURDOMAIN/webhook/whatsapp
  • Respond: Using “Respond to Webhook” node
    Respond to Webhook Node:
  • Respond With: JSON
  • Response Body:
    {{$json.query[“hub.challenge”]}}
    Response Code: 200
    Verify Token in Meta: n8n123
    Issue:
    Meta verification fails, which means the hub.challenge handshake is not being returned correctly.
    Questions:
  1. Is my response expression correct?
  2. Does the Webhook node need “Respond Immediately” instead?
  3. Do I need to remove the Respond to Webhook node?
    Screenshots attached of:
  • Webhook node settings
  • Respond to Webhook node
  • Meta webhook error
    Thanks!
  • Hey! The fastest way to find solutions is by using the :magnifying_glass_tilted_right: search function at the upper right.
    If your question hasn’t been asked before, please follow the template below. Skip the questions that are not relevant to you. →

Describe the problem/error/question

What is the error message (if any)?

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

hi @alok_mishra1
for meta webhook verification, the webhook needs to return the raw hub.challenge as plain text, not JSON

Hi @alok_mishra1

Your verification is failing because of how Meta expects the response and how n8n’s webhook handling works.

From the official n8n WhatsApp bot guide, here’s the working pattern:

Webhook node:

  • HTTP Method: GET
  • Respond: Using 'Respond to Webhook' node
  • Use the production URL in Meta (and make sure the workflow is saved and active before you click Verify)

Respond to Webhook node:

  • Respond With: Text (not JSON)
  • Response Body: {{ $json.query['hub.challenge'] }}

This is exactly what the n8n guide uses and is known to work with Meta’s verification.

To answer your specific questions:

Is my response expression correct? The expression itself is correct, but you should use Respond With: Text, not JSON, to match the documented working setup.

Does the Webhook node need “Respond Immediately” instead? No. It must be set to Using 'Respond to Webhook' node, as in the guide.

Do I need to remove the Respond to Webhook node? No. The Respond to Webhook node is required to send back the hub.challenge value.

Also double-check:

You’re using the production webhook URL from the Webhook node. The workflow is active when you click Verify in Meta. Hitting the webhook URL in a browser while the workflow is active at least returns something (if it times out or is unreachable, Meta will also fail verification).

If after switching to Respond With: Text and confirming the production URL + active workflow it still fails, there might be connectivity/SSL/proxy issues worth looking into.

Hope that gets you unstuck!