Telegram Bot API: getUpdates and webhooks
How a bot receives messages through the Telegram Bot API: getUpdates with offset and timeout, setWebhook with HTTPS and secret_token, deleteWebhook, getWebhookInfo, common mistakes and curl examples.
A Telegram bot receives incoming messages and button presses in one of two ways: it asks for them with the getUpdates method (long polling), or Telegram delivers them to your HTTPS address after you call setWebhook. You can use only one at a time: while a webhook is set, getUpdates does not work. Every request to the Bot API goes to https://api.telegram.org/bot<token>/METHOD, and you get the token from @BotFather — how to create a bot.
How a Bot API request works
- Both GET and POST are supported. Parameters can go in the query string, as
application/x-www-form-urlencoded, asapplication/json(except for file uploads) or asmultipart/form-data(for files). - The response is a JSON object with a Boolean field
ok. Ifokistrue, the result is in theresultfield. If the request failed,okisfalseand the fieldsdescriptionanderror_codeexplain why. - An incoming event is called an Update. It has an
update_idand exactly one of the optional fields:message,edited_message,channel_post,callback_query,pre_checkout_queryand others.
Option 1. getUpdates — long polling
Your program asks Telegram for new events itself. You don't need a public address, so this is the easiest way to start and to debug a bot on your own computer.
The method's parameters:
offset— theupdate_idto start from. Pass theupdate_idof the last update you received plus one.limit— how many updates to return at once: 1 to 100, 100 by default.timeout— how many seconds Telegram holds the request open when there is nothing new. The default is 0; for long polling set a positive number, such as 30.allowed_updates— a list of the update types you want, for example["message", "callback_query"]. An empty list means every type exceptchat_member,message_reactionandmessage_reaction_count. If you leave the parameter out, the previous setting stays. The filter doesn't affect updates created before the call, so unwanted ones may still arrive for a short time.
Example: curl "https://api.telegram.org/bot<TOKEN>/getUpdates?timeout=30"
Confirmation works like this: an update counts as received once you call getUpdates with an offset higher than its update_id. Until then Telegram keeps returning it. Unconfirmed updates are stored for no longer than 24 hours. The identifiers increase in order, so you can use them to skip repeats.
The next call after an update with update_id 123456: curl "https://api.telegram.org/bot<TOKEN>/getUpdates?offset=123457&timeout=30"
Option 2. setWebhook — Telegram delivers events to you
You give Telegram an address, and for each event it sends an HTTPS POST request there with the Update in the body.
url— required, the HTTPS address of your server.- Ports supported for webhooks: 443, 80, 88 and 8443.
secret_token— an optional string of 1–256 characters (Latin letters, digits,_and-). If you set it, Telegram adds the headerX-Telegram-Bot-Api-Secret-Tokenwith this value to every request. Compare it on your side to be sure a request comes from your own setup and not from someone else.max_connections— simultaneous connections from 1 to 100, 40 by default.allowed_updates— a list of update types, as ingetUpdates.drop_pending_updates— discard the updates that have piled up.certificate— your public certificate, if you use a self-signed one.
Example: curl "https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://example.com/telegram&secret_token=my_secret_123"
Your server should answer with an HTTP 2xx code. For any other response Telegram repeats the request and gives up after a reasonable number of attempts.
To go back to polling, call deleteWebhook. The state of the webhook is shown by getWebhookInfo: the response has pending_update_count (how many updates wait for delivery), last_error_date and last_error_message (when and why delivery last failed).
Common mistakes
- A webhook and getUpdates at the same time. While a webhook is set,
getUpdatesdoes not work. CalldeleteWebhookfirst. - The offset is not advanced. If you send the same
offsetevery time, or none, the bot gets the same updates again and again. - An unreachable webhook address. The address must be reachable from the internet over HTTPS on one of the four ports. If events don't arrive, call
getWebhookInfoand readlast_error_message. - The events you need don't arrive.
chat_member,message_reactionandmessage_reaction_countare not sent by default: list them inallowed_updates. And remember that an omitted parameter keeps the previous setting. - The token in code. Never push the token to a repository: how to store the token and what to do if it leaks.
Sending messages also takes just one request from the command line: sendMessage with curl.
What next
Once the bot receives events, it needs to answer them. If it will sell digital goods, add payments: accepting Stars in your bot. Want your program to buy Stars or Premium for its users? The Shiba Bank bot has an API for that, described in the API documentation.
Frequently asked questions
Which is better for a bot — getUpdates or a webhook?
getUpdates is easier for development and testing because it needs no public address. A webhook suits a bot that has a server with HTTPS and should get events instantly.
How do I receive messages in a Telegram bot through the API?
Call getUpdates in a loop with a timeout of about 30 seconds, and after each batch pass the last update_id plus one as offset. Or set an address with setWebhook.
Why doesn't getUpdates work?
Most likely a webhook is set on the bot: while it is active, getUpdates does not work. Remove it with deleteWebhook.
How do I check that a webhook works?
Call getWebhookInfo: it shows how many updates are waiting and the last delivery error, if there was one.
How long does Telegram keep messages for a bot?
No longer than 24 hours. If the bot stays offline for longer, the events are lost.
Which ports can a webhook use?
443, 80, 88 and 8443.


