Why Your WhatsApp Webhook Fails on Localhost (and How to Fix It)
Plugin Pros
You set up WhatsApp or Telegram on a local WordPress site, send a test message, and nothing happens. There’s no error and no log entry. The message never shows up.
That isn’t a bug in your code. Webhooks on localhost can’t work, by design. This guide explains why, then shows you how to test them with a free HTTPS tunnel.
Why webhooks on localhost fail silently
Webhooks are pushed to you
Messaging platforms don’t wait for your site to ask for new messages. When a customer writes to you, the platform’s servers send an HTTPS request to your webhook URL.
That covers the big three:
- WhatsApp Cloud API and Messenger (Meta): Meta sends a
POSTrequest with a JSON payload to your callback URL for every event. - Telegram Bot API: after you call
setWebhook, Telegram sends an HTTPSPOSTwith each update to your URL.
So the request starts on their servers, not on your computer.
Their servers can’t see your computer
localhost, 127.0.0.1, .test, and .local addresses only exist on your machine or your local network. To Meta’s or Telegram’s servers, https://mysite.test points nowhere.
That’s why it “fails silently”. The request never reaches your site, so WordPress has nothing to log, and nothing in your dashboard shows an error.
They also require valid HTTPS
Even a public URL has to meet some rules:
- Meta requires HTTPS with a valid TLS/SSL certificate. Self-signed certificates aren’t supported.
- Telegram requires an HTTPS URL. Webhooks only work on ports 443, 80, 88, or 8443. Self-signed certificates only work if you upload your public certificate when you call
setWebhook.
A local site with a self-signed certificate fails both checks.
Good news for live chat: Kinetix website Live Chat doesn’t need a public webhook. The visitor’s browser connects out to livechat.pluginpros.co, so Live Chat works on localhost as long as your site can reach that service. Only the messaging-app channels need the tunnel below.
The fix: give your local site a public HTTPS URL
A tunnel connects your local web server to a public HTTPS address. Requests to that address travel through the tunnel to your computer, so Meta and Telegram can finally reach your webhook.
Three popular options:
- ngrok: needs a free account. The free plan gives you one fixed dev domain (for example,
your-name.ngrok-free.app) with automatic HTTPS. - Cloudflare Quick Tunnels (
cloudflared): no account or domain needed. You get a randomtrycloudflare.comURL that changes every time you start the tunnel. - Expose: a PHP-friendly tunnel. The free plan uses a random tunnel name for each connection and limits how long each connection stays open.
These are for testing only. For a live store, use a real public host with a valid SSL certificate.
How to test webhooks on localhost with a tunnel
Step 1: Start your tunnel
Point the tunnel at the port your local WordPress site runs on. The examples use port 80. Change it if your setup uses a different port.
ngrok
ngrok config add-authtoken YOUR_TOKEN
ngrok http 80
Cloudflare Quick Tunnel
cloudflared tunnel --url http://localhost:80
Expose
expose token YOUR_TOKEN
expose share http://localhost
Each tool prints a public https:// URL. Copy it. Keep the terminal open, because the URL stops working when you close the tunnel.
Step 2: Point WordPress at the tunnel URL
Webhook URLs are built from your WordPress address, so WordPress has to know its new public address.
- In WordPress, go to Settings → General.
- Change WordPress Address (URL) and Site Address (URL) to your tunnel’s HTTPS address.
- Click Save Changes. You may need to log in again on the new address.
If these fields are locked, your wp-config.php sets WP_HOME and WP_SITEURL. Update them there instead.
Step 3: Flush permalinks
- Go to Settings → Permalinks.
- Make sure the structure is anything except Plain. Kinetix webhooks use the REST API path
/wp-json/kmbp/v1/webhooks/. - Click Save Changes. That refreshes the rewrite rules.
Step 4: Re-register the webhook
Your webhook URL now starts with the tunnel address. Every platform needs to know about it.
WhatsApp (and Messenger)
- In WordPress, open Kinetix Messaging → Settings and choose the channel.
- Copy the Webhook URL shown in the plugin. For WhatsApp, it looks like this:
https://YOUR-TUNNEL-URL/wp-json/kmbp/v1/webhooks/whatsapp - In the Meta App Dashboard, open your webhook settings and paste it as the Callback URL.
- Enter the same Verify Token you saved in the plugin, then click Verify and Save.
During verification, Meta sends a GET request with hub.mode, hub.verify_token, and hub.challenge. The plugin checks the token and sends back the challenge. A green “Verified” means Meta reached your site through the tunnel.
Telegram
- Open Kinetix Messaging → Settings → Telegram.
- Go to the Webhook tab and click Register Webhook.
- Confirm the status shows the webhook as active, then click Save.
The plugin calls Telegram’s setWebhook for you with the new URL.
Step 5: Send a test message
- Message your WhatsApp Business number, Facebook Page, or Telegram bot from your phone.
- Open Kinetix Messaging → Inbox. The conversation should appear within a few seconds.
- Reply from the inbox and check that it arrives on your phone.
If nothing arrives, Telegram can tell you why. Open this URL in your browser (with your bot token) and read last_error_message:
https://api.telegram.org/botYOUR_BOT_TOKEN/getWebhookInfo
Restarted the tunnel? Re-register the webhook
Cloudflare Quick Tunnels and Expose’s free plan give you a new URL each time they start. The old webhook URL then points nowhere, and messages go silent again.
Each time the URL changes:
- Update Settings → General to the new address.
- Save Settings → Permalinks again.
- Re-register the webhook in Meta and in Kinetix’s Telegram settings (Step 4).
ngrok’s free dev domain stays the same between restarts, which saves you most of this. You still need the tunnel running to receive anything.
Tip: Meta retries failed deliveries for up to 36 hours. Telegram keeps pending updates for up to 24 hours. If you reconnect quickly, a few delayed messages may still arrive.
Troubleshooting
Meta says the callback URL couldn’t be verified
- Cause: the tunnel isn’t running, or the verify tokens don’t match.
- Fix: check the tunnel terminal is open, then copy-paste the same Verify Token into both Meta and the plugin.
Webhook verifies, but no messages arrive
- Cause: webhook fields aren’t subscribed, or the tunnel URL changed.
- Fix: subscribe to
messagesin Meta. If the URL changed, re-register it (Step 4).
Telegram’s getWebhookInfo shows an error
- Cause: Telegram can’t reach the URL or gets an error response from it.
- Fix: read
last_error_message, make sure the tunnel is up, then click Register Webhook again.
The tunnel URL shows the wrong site or a server error
- Cause: your local server routes by hostname (for example
mysite.test). - Fix: point the tunnel at your local site’s URL instead of the bare port. Expose supports this directly with
expose share mysite.test.
Redirect loop after switching WordPress to the HTTPS tunnel URL
- Cause: the tunnel ends HTTPS and forwards plain HTTP, so WordPress doesn’t know the request was secure.
- Fix: add WordPress’s documented reverse-proxy check to
wp-config.php, above the “stop editing” line:if ( isset( $_SERVER[‘HTTP_X_FORWARDED_PROTO’] ) && strpos( $_SERVER[‘HTTP_X_FORWARDED_PROTO’], ‘https’ ) !== false ) { $_SERVER[‘HTTPS’] = ‘on’;}
Webhook requests are blocked (403)
- Cause: a security plugin, firewall, or CDN rule blocks unauthenticated
POSTrequests. - Fix: allow
/wp-json/kmbp/v1/webhooks/in that tool.
FAQ
Can I test WhatsApp webhooks on localhost without a tunnel?
No. Meta’s servers must reach your callback URL over public HTTPS with a valid certificate, and localhost isn’t reachable from the internet. Use a tunnel, or a public staging subdomain with a valid SSL certificate.
Do I need a tunnel for Kinetix website Live Chat?
No. Live Chat doesn’t use an inbound webhook. The visitor’s browser connects out to livechat.pluginpros.co, so it works on localhost as long as your site can reach that service.
Why did my webhook stop working the next day?
Your tunnel URL probably changed. Cloudflare Quick Tunnels and Expose’s free plan create a new address on each start. Update your WordPress address, then re-register the webhook with Meta or Telegram.
Can I use a staging subdomain instead?
Yes. It needs a valid (not self-signed) HTTPS certificate and port 443 open to the internet. It also has to be outside any VPN or firewall that blocks webhook POST requests.
One inbox once it’s working
Once your webhooks reach WordPress, Kinetix Messaging puts WhatsApp, Telegram, Messenger, and your other channels in one inbox. If you’re new to it, start with the Kinetix Messaging overview.
Ready to connect a real number? Follow the step-by-step guide: Connect WhatsApp to WordPress with Kinetix Messaging.