How Telegram delivers updates to a bot, how to set, test and secure a webhook step by step, how to fix the usual errors, and when long polling is the better choice.
To set a webhook, you tell Telegram's Bot API the HTTPS address of your server by calling the setWebhook method with your bot token, and from then on Telegram sends every new update to that address as it happens. Polling is the alternative: your bot repeatedly asks Telegram for new updates with getUpdates. Webhooks suit bots running on a public server; polling suits development, small bots and machines that cannot accept incoming connections.
This guide explains both delivery methods, walks through setting and checking a webhook without assuming a particular programming language, covers security, and then works through each common failure with its own fix. It describes methods and parameters in words rather than code. The authoritative reference is Telegram's Bot API documentation on core.telegram.org, which you should keep open while you work, because parameters are added over time.
Everything that happens to a bot arrives as an update: a new message, a button press, a user joining a group the bot is in, a payment, an inline query. Each update has a numeric update ID that increases over time.
Telegram holds updates for your bot until they are delivered. The Bot API documentation says incoming updates are kept on Telegram's servers until the bot receives them, but not for longer than 24 hours. If your bot is down for longer than that, the oldest updates are gone.
There are two mutually exclusive ways to collect them:
You cannot use both at once. While a webhook is set, getUpdates returns an error. To go back to polling, you delete the webhook first.
Neither is "better". They trade different things.
Speed is rarely a reason. Well-configured long polling delivers updates almost as soon as they arrive, because the open request is answered the moment an update comes in. Choose on where the bot runs, not on latency.
Gather these things before setting a webhook:
You call Bot API methods by making HTTPS requests to Telegram's Bot API address, with your token in the path and the method name at the end. Parameters can be passed as query parameters, as a form, or as JSON in the request body. Any HTTP tool works: your bot library, a command-line HTTP client, or an API testing app.
Before telling Telegram about the URL, make sure your server is listening on it and returns a success status (any 2xx response) to a POST request. Test it from outside your network, for example from your phone's mobile data, so you know the outside world can reach it.
Create a random string of letters, digits, underscores and hyphens. The Bot API documentation allows between 1 and 256 characters. Longer and random is better. Store it in your server's configuration, not in your source code.
Call the setWebhook method with these parameters:
Telegram replies with a JSON object. A field named ok set to true means the webhook was accepted. If ok is false, the description field says why, for example a bad URL or an unreachable host.
Call getWebhookInfo with no parameters. It returns the current webhook state, including:
Open a chat with your bot and send a message. Your server should receive a POST within a moment. Check your server logs, then call getWebhookInfo again and confirm pending_update_count is zero and there is no fresh error.
Setting the webhook is the short part. How your endpoint behaves decides whether the bot is reliable.
On every request, compare the X-Telegram-Bot-Api-Secret-Token header with your stored secret. If it is missing or wrong, return an error and stop. Without this check, anyone who discovers your URL can send fake updates that look like real users pressing buttons or sending commands.
Telegram waits for your response before considering the update delivered. If your bot does slow work, such as calling an AI model, querying a slow database or downloading files, do not make Telegram wait for it. Acknowledge the request with a success status straight away, then do the work in the background and send the result with a separate Bot API call.
If your endpoint is slow or returns an error, Telegram treats the delivery as failed and tries again later. Updates pile up behind it, and users see a bot that seems to lag.
Because failed deliveries are retried, a request that timed out on Telegram's side may already have been processed on yours. Make your handler safe to run twice. The simplest way is to remember recent update IDs and skip any you have already handled. This matters most for actions with side effects, such as sending a payment confirmation or posting to a channel.
Telegram retries any delivery that does not get a success status. That is helpful for temporary problems and harmful for permanent ones. If an update can never be processed, for example because it is a type your bot does not handle or it refers to a chat the bot has left, answering with an error makes Telegram send it again and again until it gives up, wasting work on both sides and cluttering your error logs. For updates you have deliberately decided to ignore, return success and move on. Reserve error responses for real, temporary failures where a retry might work, and for requests that fail the secret check.
The Bot API allows a shortcut: instead of an empty success response, your endpoint can answer with a Bot API method call in the response body, as JSON naming the method and its parameters. Telegram executes it. It saves one request per update, but you do not learn whether the call succeeded, so use it only for simple replies where failure does not matter.
Every update type you subscribe to is traffic your server must accept and answer. If your bot only reacts to messages and button presses, set allowed_updates to those. You can change it with another setWebhook call at any time.
If you cannot get a certificate from a recognised authority, for example on an internal test server, you can use a self-signed one:
Telegram's documentation has a separate page on self-signed certificates. If you can use a free certificate from a recognised authority, do that instead; it removes one moving part.
A bot has one delivery method at a time. If you poll from your laptop while the production server expects a webhook, you will delete the production webhook and break the live bot. Create a separate bot with @BotFather for development, with its own token. It is free and avoids a whole category of accidents.
If polling is the right choice for your bot, a few details make it as reliable as a webhook.
The getUpdates method takes a timeout parameter in seconds. With a timeout of zero, Telegram answers immediately even when there is nothing new, so a bot calling it in a loop sends a constant stream of pointless requests. With a timeout of a few tens of seconds, the request stays open until an update arrives or the time runs out. That is the "long" in long polling, and it gives near-instant delivery with very little traffic.
Make sure your HTTP client's own timeout is longer than the one you pass to Telegram, or your client will give up before Telegram answers.
Each call passes an offset equal to the highest update ID you have processed plus one. That tells Telegram everything before it has been handled and can be forgotten. Two consequences follow:
Only one getUpdates call can be active for a bot at a time. If two copies of your bot poll with the same token, for example an old process that was never stopped and a new one, Telegram answers one of them with a conflict error saying another getUpdates request terminated it. The two keep knocking each other off, and updates go to whichever happened to be connected. When you see that conflict error, find and stop the second process.
getUpdates also accepts a limit on how many updates to return per call and an allowed_updates list, which works the same way as for webhooks. Filtering here reduces work for your bot just as it does for a server.
A webhook fails silently from the user's point of view: the bot just stops answering. A little monitoring catches it before users do.
You run a web server with a certificate, your bot code behind it, and a firewall that allows incoming HTTPS. This is the classic setup and gives you full control over timeouts and background work.
Each update starts a function that handles it and stops. Webhooks are the only option here. Watch three things: function time limits (answer fast and hand slow work to a queue), cold starts (the first request after a quiet period is slower), and retries (the same update may arrive twice, so keep your handler safe to repeat).
Many automation tools give you a webhook URL that you can register with setWebhook, so a workflow runs for each message. Our guide on automating Telegram with n8n, Zapier or Make shows that approach, and building a bot without coding covers the wider options.
Your laptop has no public HTTPS address. Tunnelling tools can give a temporary public URL that forwards to your machine. Set that URL as the webhook of your development bot, never your production one, and remember that the URL usually changes each time the tunnel restarts, so you will need to call setWebhook again.
Start every investigation with getWebhookInfo. The last_error_message usually names the cause. Then use the section that matches.
How to recognise it: the last error mentions SSL, a certificate, verification or a handshake.
If it still fails, test the URL with an online TLS checker and fix what it reports.
How to recognise it: the last error mentions a connection refused, timeout, or host unreachable.
Telegram's webhook guide lists the network ranges Telegram's servers send from. If your firewall only allows specific sources, take the current ranges from that guide rather than an old blog post.
How to recognise it: the last error includes an HTTP status code, such as a 4xx or 5xx error.
How to recognise it: your server answers with a redirect status, often because it sends HTTP traffic to HTTPS or adds a trailing slash.
Set the webhook to the final address exactly, including the trailing slash if your server expects one, so no redirect is needed.
How to recognise it: errors mention a timeout, pending updates grow during busy periods, and users see delays.
How to recognise it: your polling bot reports a conflict error mentioning an active webhook.
Call deleteWebhook, check that getWebhookInfo shows an empty url, and start polling again. If it keeps coming back, another deployment of your bot is setting the webhook on startup. Find and stop it, or give that deployment its own bot token.
How to recognise it: messages arrive but button presses, member changes or reactions never do.
Our guide on whether Telegram bots are safe looks at the same questions from the user's side, which is a useful reminder of what you are protecting.
These are illustrative examples.
A volunteer runs a bot that welcomes new members and answers a handful of commands. It runs on a cheap home computer behind a router. Long polling is the right choice: no certificate, no port forwarding, and the bot only makes outgoing connections.
A shop bot runs as serverless functions. It sets a webhook with a secret token, subscribes only to messages, callback queries and payment-related updates, and acknowledges each request immediately while a queue handles order processing. It stores processed update IDs for a day to ignore repeats. Our guide to bot payments for developers covers the payment updates it handles.
A team's polling bot outgrows a single process. They stop the poller, set a webhook pointing at a load balancer with several instances, drop pending updates during a short planned maintenance window, and watch getWebhookInfo for errors for the first hour.
Not meaningfully for most bots. Long polling answers as soon as an update arrives. Choose based on where the bot runs and how it scales.
No. The two delivery methods are exclusive, so delete the webhook before you start polling.
Telegram keeps them and keeps retrying, but not for longer than 24 hours according to the Bot API documentation. Check pending_update_count when you come back.
You need an HTTPS URL that Telegram can reach with a valid certificate. With a self-signed certificate whose common name is your IP address, you can use an IP. A domain with a normal certificate is simpler.
Yes. Give each bot its own path and its own secret token, and route requests by path.
Call deleteWebhook and do not poll. Updates will queue for up to a day and then expire.
A webhook makes Telegram push each update to your HTTPS endpoint; polling makes your bot ask for them. Use polling for development and for bots that cannot accept incoming connections; use a webhook for public servers and serverless platforms. Set it with setWebhook, including a secret token and only the update types you need, confirm it with getWebhookInfo, answer requests quickly, and make your handler safe to run twice. When something breaks, the last error in getWebhookInfo almost always tells you which of the causes above you are dealing with.
Ownership confirmed through our claim process — not an endorsement of their content.
Founder of Telegram.
The official Telegram on Telegram. Much recursion. Very Telegram. Wow.
Telegram Premium – a subscription that unlocks dozens of exclusive features.
Binance Official English Group Binance Official Chinese Group Binance English Announcements Binance Chinese Announcements
is a modern crypto news and research platform covering the latest developments across digital assets, markets, regulation, and blockchain technology.
Technical analysis & high-probability trade setups. Price action, market structure, risk control.
BlackBlock Markets exists to observe how capital moves before it becomes obvious.
This channel focuses exclusively on what shapes global finance. Macroeconomics, markets, liquidity, central banks.
Clear long & short signals for BTC, ETH & liquid altcoins. AI-backed analysis, real-time execution.