← back to blog

Migrating a Telegram bot token to a new owner safely

What a bot token actually controls

A Telegram bot token looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz. The number before the colon is the bot’s Telegram user ID. The string after it is the secret. Anyone who holds that string can call the Bot API as that bot: send messages, read updates, set commands, change the bio, answer callback queries, all of it.

What the token does not let you do is manage the bot’s registration. Deleting the token, transferring ownership, deleting the bot outright, these are BotFather actions, and BotFather only takes them from the Telegram account that originally created the bot. That split matters more than most people realize when a bot changes hands: the token is operational access, BotFather is ownership. You can hand someone the first without ever touching the second.

This is the root of almost every bad migration story. Someone buys, inherits, or takes over running a bot, gets the token, wires it into their own server, and everything works. Then weeks later the original creator revokes it, on purpose or by accident, and the bot goes dark with no warning to the new operator.

The wrong way to migrate a token

The failure mode is simple: copy the token, paste it into new hosting, done. It works right up until it doesn’t, because the account that created the bot in BotFather still has full authority over it. They can hit /revoke at any time and issue a fresh token. They can rename the bot. They can delete it. None of that requires touching the server the bot is actually running on.

If you’re the one receiving a bot this way, you are running someone else’s bot on borrowed credentials. That’s fine for a short-lived handoff where both sides are cooperative and the plan is to formalize things quickly. It’s not fine as a permanent arrangement, because there is no way to prove, from the token alone, who is supposed to have the kill switch.

The right way: BotFather’s transfer ownership feature

BotFather has a real ownership transfer command. From /mybots, select the bot, then Transfer Ownership. It moves the bot’s registration to another Telegram account by username, and it requires two-factor authentication (a cloud password, not just SMS login) on both the current owner’s account and the receiving account. Telegram added that 2FA requirement specifically because a bot token transfer is effectively a handover of everything the bot can do, so they gate it the same way they gate other high-trust account actions.

Once the transfer completes, the new owner’s account shows the bot under their own /mybots, and only they can revoke the token or delete the bot going forward. The token itself doesn’t necessarily change during this process, so if you want a clean break from any old credentials, revoke and regenerate it yourself right after the transfer lands, from the new owner’s account.

This is the only method that actually resolves the split-control problem. Everything else is a workaround.

When you can’t transfer ownership

Sometimes a real transfer isn’t practical. The original creator’s account might not have 2FA set up and the person is unreachable. The bot might need to stay registered under a specific account for internal recordkeeping. Or you’re not transferring ownership at all, you’re just moving the bot from one host to another while the same person keeps ownership.

In those cases, be honest with everyone involved about what’s actually happening: the token is moving, ownership isn’t. Put it in writing, even if it’s just a message thread, so the operator running the new host understands that the registered owner retains the ability to revoke access at any time. If the arrangement depends on the new operator having durable, independent control, a workaround token handoff isn’t the right tool. Push for the real transfer, or don’t do the handoff at all.

Handling webhooks and polling during the cutover

Whichever path you take, the token isn’t the only thing that needs to move cleanly. If the bot uses a webhook, Telegram is actively pushing updates to a URL registered against that token. If the old host is still up when the new host sets its own webhook, whoever calls setWebhook last wins, and there’s a window where updates might land on the host that’s about to be decommissioned.

If the bot uses long polling instead, running two instances of getUpdates against the same token at the same time produces a 409 Conflict error, because Telegram only allows one active polling consumer per token. That’s actually useful during migration: it tells you unambiguously when the old instance is still running and needs to be stopped.

The safe order is:

  1. Stop the bot process on the old host, or call deleteWebhook if it’s using a webhook.
  2. Confirm with getWebhookInfo that there’s no pending webhook URL and no backlog of pending updates.
  3. If you’re transferring ownership, do that in BotFather now.
  4. If you’re rotating the token, call /revoke and grab the new token from BotFather.
  5. Configure the new host with the current token, and either set the new webhook URL or start polling.
  6. Call getMe from the new host to confirm the token is live and matches the bot you expect.
  7. Watch for a short burn-in period before fully decommissioning the old host, in case you need to roll back.

Skipping step 2 is the most common cause of duplicate messages or missed updates during a migration, because leftover webhook configuration or an unread update queue doesn’t clear itself just because you changed hosts.

Rotating the token if you’re not transferring ownership

If the plan is operational handoff without an ownership transfer, rotate the token as part of the move rather than treating the existing one as good enough. Revoking and reissuing the token from BotFather instantly invalidates the old string. Any process still holding it starts getting 401 Unauthorized from the Bot API. That’s a clean, unambiguous cutover point, and it also closes off the old host as a lingering copy of a live credential sitting on a server nobody’s watching anymore.

If the bot receives updates over a webhook, set a secret token when you call setWebhook (the secret_token parameter), and check the X-Telegram-Bot-Api-Secret-Token header on incoming requests at the new host. That way the endpoint verifies the request actually came from Telegram’s servers and not from something replaying old webhook traffic or probing the URL after you’ve published it somewhere.

A practical migration checklist

  • Confirm which kind of migration this is: full ownership transfer, or operational handoff with the same registered owner. Don’t blur the two.
  • If it’s ownership transfer, make sure both accounts have a cloud password set before you start, since BotFather’s transfer command requires it on both ends.
  • Stop the bot on the old host and clear any webhook or pending update backlog before configuring the new one.
  • Rotate the token as part of the move unless there’s a specific reason not to, and update it everywhere it’s referenced, including any process managers, environment files, and secret stores.
  • Verify with getMe and getWebhookInfo from the new host before you consider the old host safe to shut down.
  • If the bot runs behind a reverse proxy or a specific egress path, check whether anything downstream, like an IP allowlist on a payment provider or an internal API, was tied to the old host’s address.

Where proxy configuration fits in

We run hosting and proxy infrastructure for Telegram bots, and the egress path a bot uses to reach the Bot API is part of what changes during a migration, not just the token. If the old host was routing outbound calls through a specific proxy or a fixed IP that’s allowlisted somewhere else in the stack, moving to new infrastructure without carrying that configuration over will produce failures that have nothing to do with the token itself and everything to do with where the request is coming from. Worth checking before you call the migration done, not after something downstream starts rejecting requests.

If you’re moving a bot to new hosting or handing one off to a new operator and want a second pair of eyes on the sequencing, that’s exactly the kind of thing we help with .

Get new guides and videos first — join the Telegram channel.

need infra for this today?