WhatsApp Cloud API webhook verification not reaching my Worker

Hey all! I’m trying to set up a WhatsApp Cloud API webhook with a Cloudflare Worker, but Meta’s verification request never seems to hit my Worker. What I did: In Meta Developer Dashboard → WhatsApp → Configuration, I set: Callback URL: https://jolly-darkness-c35f.andrastothbalint.workers.dev/ Verify Token: abc My Worker code is just a minimal verifier (hard-coded token for now). I deployed the Worker and confirmed it’s live. What I saw: When I click Verify and Save in Meta, I get the error: “The callback URL or verify token couldn’t be validated.” In Cloudflare → Workers → Logs → Live, no requests appear when Meta tries to verify. If I use webhook.site as the callback URL instead, I do see Meta send a proper GET with hub.mode=subscribe, hub.verify_token=abc, and hub.challenge=.... So Meta is definitely sending the request, but Cloudflare Worker doesn’t show anything. Also noticed this error in the Cloudflare dashboard occasionally: API Request Failed: GET /api/v4/accounts/.../workers/domains/records (502) Question: Has anyone here successfully verified a WhatsApp Cloud API webhook on a Cloudflare Worker? Could Cloudflare be blocking Facebook’s verification requests (Bot Fight Mode, WAF, IPv6 issues)? Any known workarounds or settings I should tweak? Thanks a ton!!!
1 Reply
AndrasTothBalint
AndrasTothBalintOP3mo ago
Here's my code: export default { async fetch(request) { const url = new URL(request.url); // Webhook verification (GET) if (request.method === 'GET') { const mode = url.searchParams.get('hub.mode'); const token = url.searchParams.get('hub.verify_token'); const challenge = url.searchParams.get('hub.challenge'); if (mode === 'subscribe' && token === 'abc') { return new Response(challenge, { status: 200 }); } else { return new Response('Forbidden', { status: 403 }); } } // Incoming events (POST) if (request.method === 'POST') { const body = await request.json(); console.log("📩 Incoming webhook:", JSON.stringify(body)); return new Response('ok', { status: 200 }); } return new Response('ok', { status: 200 }); } }

Did you find this page helpful?