setWebhook
Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized Update. In case of an unsuccessful request (a request with response HTTP status code different from 2XY), we will repeat the request and give up after a reasonable amount of attempts. Returns True on success.
If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter secret_token. If specified, the request will contain a header “X-Telegram-Bot-Api-Secret-Token” with the secret token as content.
Parameters
urlStringRequiredip_addressStringOptionalmax_connectionsIntegerOptional Default: 40allowed_updatesString[]Optional["message", "editedchannelpost", "callbackquery"] to only receive updates of these types. See Update for a complete list of available update types. Specify an empty list to receive all update types except chat\member, message\reaction, and message\reaction\_count (default). If not specified, the previous setting will be used. Please note that this parameter doesn't affect updates created before the call to the setWebhook, so unwanted updates may be received for a short period of time.drop_pending_updatesBooleanOptionalsecret_tokenStringOptionalminLen 1maxLen 256A-Z, a-z, 0-9, _ and - are allowed. The header is useful to ensure that the request comes from a webhook set by you.Returns
On success, True is returned.
GramIO Usage
GramIO handles webhook setup automatically when you call bot.start({ webhook: ... }). Direct setWebhook calls are only needed for advanced configurations.
// GramIO recommended way — webhook is configured automatically
bot.start({
webhook: {
url: "https://example.com/bot",
},
});// Direct API call — useful for manual setup or when bot.start() isn't used
await bot.api.setWebhook({
url: "https://example.com/bot",
secret_token: "my-secret-token-abc123",
allowed_updates: ["message", "callback_query", "inline_query"],
max_connections: 100,
drop_pending_updates: true,
});// Set webhook with a self-signed certificate
import { MediaUpload } from "gramio";
await bot.api.setWebhook({
url: "https://my-server.com/bot",
certificate: await MediaUpload.path("./public.pem"),
drop_pending_updates: false,
});// Remove webhook (fall back to getUpdates / long polling)
await bot.api.setWebhook({ url: "" });Errors
| Code | Error | Cause |
|---|---|---|
| 400 | Bad Request: bad webhook: HTTPS URL must be provided for webhook | The url is not HTTPS — Telegram requires a valid HTTPS URL (not HTTP) |
| 400 | Bad Request: bad webhook: Failed to resolve host | DNS lookup failed for the webhook host — verify the domain exists and resolves |
| 400 | Bad Request: bad webhook: Wrong response from the webhook: N UNKNOWN | Telegram received a non-2xx response from your server during the test probe at registration — ensure your endpoint is live and returns 200 |
| 400 | Bad Request: bad webhook: IP address N is not allowed | The resolved IP is in a reserved/private range — Telegram doesn't allow webhooks to internal IPs |
| 400 | Bad Request: bad webhook: SSL certificate verification failed | Certificate is self-signed without being uploaded, expired, or uses an untrusted CA — upload it via certificate or use a CA-signed cert |
| 429 | Too Many Requests: retry after N | Rate limit hit — check retry_after, use auto-retry plugin |
Tips & Gotchas
- HTTPS is mandatory. Telegram only sends webhook requests to HTTPS endpoints. Port 443, 80, 88, or 8443 are supported — other ports are blocked.
allowed_updatesomission keeps the previous setting. If you omitallowed_updates, Telegram continues using whatever was set before. Pass an explicit list to ensure your bot receives exactly what it needs, nothing more. Unneeded update types add overhead.drop_pending_updates: trueis useful on redeploy. When restarting a bot that was down, there may be a backlog of updates. Set this totrueto start fresh and avoid processing stale messages.secret_tokenprevents spoofed requests. Always set asecret_tokenin production and verify theX-Telegram-Bot-Api-Secret-Tokenheader in your webhook handler — without it, anyone who knows your URL can send fake updates.- You cannot use long polling (getUpdates) while a webhook is active. Call deleteWebhook first, or pass
url: ""to switch back to polling mode. max_connectionsaffects concurrency, not throughput. Higher values allow Telegram to send more parallel requests, but your server must be able to handle them. Start with the default 40 and increase if you're a high-traffic bot.
See Also
- deleteWebhook — remove the webhook and switch to getUpdates polling
- getWebhookInfo — check current webhook configuration and error info
- WebhookInfo — the webhook info object returned by getWebhookInfo
- Media Upload guide — how to upload a self-signed certificate