Skip to content
work/whatsapp-doctor

whatsapp-doctor

LIVE

Find out why your WhatsApp webhook returns 200 and delivers nothing.

A zero-dependency CLI that diagnoses a WhatsApp Cloud API setup and reports the two failures you cannot see from a browser.

Visit whatsapp-doctorDesign, build, tests, docs.
7
Checks
0
Dependencies
33
Tests
MIT
License
The problem

Why it exists.

I lost days to a webhook that answered verification, returned 200 to everything I sent it, and delivered nothing. Meta had no errors to show, because from their side there were none. Two causes, and neither is visible from a browser: an apex domain redirecting to www, which kills every POST at the 307 because webhook senders do not follow redirects, and a CDN quietly refusing the same request from a datacenter that it happily accepts from a laptop. Nothing existed that would check for either.

whatsapp-doctor is an open-source command line tool that checks a WhatsApp Cloud API integration end to end and tells you what is actually wrong. It inspects the token's real scopes and expiry, the phone number's platform type and verification, Meta's own send-readiness verdict, whether any app is subscribed to the WhatsApp Business Account, and template state. Then it probes the callback URL the way Meta calls it, with redirects deliberately left unfollowed, because that is the only way to see what a webhook sender sees. Every failure prints the fix rather than the symptom, and it never sends a message, so running it costs nothing.

Architecture

How the pieces fit.

The whole system, end to end. Trace any node to see its role and connections.

architecture --interactive
Client
Edge / API
Data
External
Jobs

Hover or focus any node to trace its role and connections.

What's inside

Every surface, shipped.

01

Sees what Meta sees

The callback is probed with redirects unfollowed, so an apex-to-www hop shows up as the silent killer it is, rather than looking healthy because your browser follows it for you.

02

Names bot protection

A rejection carrying CDN headers is reported as edge filtering, judged on IP reputation rather than anything in the request, with where to confirm it in that CDN's own logs.

03

Finds the silent webhook

Setting a callback URL subscribes nothing. If no app is subscribed to the WhatsApp Business Account, no event is ever delivered and nothing reports a problem. That check alone explains most dead webhooks.

04

Refuses to cry wolf

An unsigned probe getting a 401 usually means the handler verifies signatures correctly, so that is reported as unresolved rather than broken. Punishing the apps that get security right would make the tool useless.

Hard decisions

The calls that mattered.

01

Probe the origin, not the User-Agent

problem · The obvious way to detect edge filtering is to send two requests with different User-Agents and compare. It is also wrong.

call · Real bot protection judges the caller by IP reputation and TLS fingerprint, so changing the User-Agent from one machine proves nothing. The diagnosis keys off CDN response headers, and the User-Agent comparison is only reported when it demonstrably changes the answer.

02

A host is not a filter

problem · Running it against a real production endpoint accused a perfectly healthy webhook of blocking Meta, because the hosting platform stamps its own header on every response.

call · Only things that genuinely sit in front of an app and can refuse a request before your code runs count as evidence. Testing against something real caught a false positive that testing against fixtures never would have.

03

Never send a message

problem · The most direct way to test a messaging integration is to send a message, which costs money and can reach a real customer.

call · It only reads configuration and probes your own callback, so it is safe to run against production at any time. The one thing it cannot answer, whether a specific customer's 24-hour window is open, is stated as a limit instead of guessed at.

Stack
Node.js (fetch, no deps)WhatsApp Cloud APIMeta Graph APInode:assertnpx-runnable CLI
Outcome

A small, sharp tool that answers a question thousands of developers hit and nothing else checks for. Zero dependencies, MIT, runnable with npx, and its whole test suite runs offline against a fake Graph API with no credentials.

Next case study

Sellnudge

open
Available now

Want one of these for your product?