Debug Telegram bot webhooks

Your bot works with getUpdates polling, you switch to a webhook for production, and… nothing. No updates, no errors in your logs — because the failure is happening between Telegram and your server, where you can't see it. Here's how to make every step visible.

1. Point the webhook at a capture URL first

Before debugging your server, confirm what Telegram actually sends. Create a bin (button below, or curl https://hookden.pages.dev/new) and set it as your webhook:

$ curl "https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://hookden.pages.dev/h/YOUR_BIN"

Send your bot a message and watch the dashboard: the full Update JSON arrives — message, callback_query, my_chat_member, whatever your bot is subscribed to — with every header Telegram sends. Now you know exactly what your handler must parse, and you have real payloads to copy as curl / Python and replay against your handler locally.

This works because bins are HTTPS on port 443 with a valid certificate — which is precisely what Telegram requires (see the error table below).

2. Ask Telegram what's wrong: getWebhookInfo

$ curl "https://api.telegram.org/bot<TOKEN>/getWebhookInfo"

This is the single most useful debugging call. Look at:

3. The classic errors

4. Verify it's really Telegram: secret_token

Set a secret when registering the webhook:

$ curl "https://api.telegram.org/bot<TOKEN>/setWebhook?url=…&secret_token=my-secret-123"

Telegram then sends X-Telegram-Bot-Api-Secret-Token: my-secret-123 with every update. Point the webhook at a bin first and you can see the header arrive with your own eyes before writing the check into your handler — captured headers show it verbatim.

5. Develop on localhost — no tunnel needed

Telegram refuses plain-HTTP and localhost URLs, which is why most tutorials reach for ngrok. But Telegram bots don't reply through the webhook response — they call sendMessage etc. over the regular API — so all you need is the inbound updates, and those can be relayed:

$ curl -s https://hookden.pages.dev/cli -o hookden && chmod +x hookden
$ ./hookden relay YOUR_BIN http://localhost:8080/webhook

Set the webhook to your bin once; every update is re-delivered to your local bot byte-exact (the secret_token header included, so your verification code runs unchanged). Your laptop needs no public IP, no tunnel daemon, no TLS setup. Full details: webhooks to localhost without a tunnel.

Cleanup

When you're done inspecting, point the webhook back at your real endpoint (or deleteWebhook to resume polling). Add drop_pending_updates=true if you don't want the queued backlog replayed at your bot.

No signup needed. Or from your terminal: curl https://hookden.pages.dev/new

← All guides · Docs · Hookden vs webhook.site