Use deep links to see where your bot's users come from

A deep link is a bot link with a short code on the end. It opens your bot like any other link, but it also tells the bot which link was used. That one detail lets you see which channel, post or ad brought each user, and it's the basis of every referral system on Telegram.

Video Saverbot
/start ig_bio
👋 Welcome! Send me any link and I'll download the video.
Someone tapped t.me/your_bot?start=ig_bio, so you know they came from your Instagram bio.

What a deep link is

Every bot has a normal link: https://t.me/your_bot. Add ?start= and a code, and you have a deep link:

https://t.me/your_bot?start=summer_post

Here's what happens when someone taps it:

  1. Telegram opens the chat with your bot, the same as the normal link.
  2. The user taps Start.
  3. Instead of a plain /start, your bot receives /start summer_post.

The code after start= is called the start parameter. The user doesn't have to type anything, and nothing about the experience changes for them. The bot simply gets one extra piece of information it can save or act on.

Two things a deep link can't do: it can't make the bot message someone who hasn't tapped Start, and it doesn't tell you anything about people who opened the link but closed the chat without starting the bot.

The rules for the start parameter

Telegram is strict about what can go after start=:

RuleDetail
LengthUp to 64 characters
Allowed charactersA-Z, a-z, 0-9, underscore _ and hyphen -
Not allowedSpaces, dots, slashes, =, &, emoji and letters outside the Latin alphabet

Some quick examples:

  • ?start=insta_bio works.
  • ?start=ad-nov-2026 works.
  • ?start=black friday doesn't, because of the space. Use black_friday.
  • ?start=site.com/page doesn't, because of the dot and slash.

If you need to pass something longer or with other characters, don't squeeze it into the link. Keep a short code in the link and a list somewhere else that says what each code means. Developers sometimes encode data with URL-safe base64, which uses only allowed characters once the trailing = padding is removed, but for tracking, short readable codes are easier to work with.

Track where users come from

The idea is simple: give every place you share the bot its own link. Then, when a user starts the bot, the parameter tells you which place it was.

Where you share itExample link
Pinned post in your channelt.me/your_bot?start=ch_pinned
Your channel's descriptiont.me/your_bot?start=ch_about
Your website's headert.me/your_bot?start=web_header
Instagram biot.me/your_bot?start=ig_bio
Swap with a partner channelt.me/your_bot?start=p_cookingdaily
Paid post, Novembert.me/your_bot?start=ad_nov26_a
Same post, second versiont.me/your_bot?start=ad_nov26_b
QR code on a flyert.me/your_bot?start=qr_flyer

After a week or two, count new users per code. You'll often find that one source you barely thought about brings more people than the one you spent the most time on. That's the whole point: it replaces guessing with a count.

Two versions of the same ad, like _a and _b above, let you test which wording works better. Change one thing between them, such as the first line or the image, so you know what made the difference.

Name your codes so they stay readable

After a few months you'll have dozens of links. A naming pattern keeps them usable:

source_placement_date
ch_pinned_nov26
p_cookingdaily_nov26
ad_techchannel_nov26_b
  • Start with the source type (ch for your channel, p for partner, ad for paid), so similar links sort together.
  • Use lowercase and underscores only. Mixing Ad_Nov and ad_nov creates two codes for the same thing.
  • Keep a simple sheet with each code, where you posted it, the date, and what it cost.
  • Never put personal data in a code. Links get forwarded and posted publicly, so anyone can read them.

Using the parameter for more than tracking

Because the bot reads the parameter the moment someone taps Start, it can also change what happens next. A few common uses:

  • Open a specific item. A shop bot can use ?start=item_204 to show one product straight away, instead of the main menu.
  • Match the message to the ad. If an ad promised a free guide, a link like ?start=guide lets the bot send the guide first, so the user gets what they clicked for.
  • Join something. Giveaway bots use a parameter to drop the user straight into one contest.
  • Pick a language. A link on your Spanish page can start the bot in Spanish, although many bots already follow the user's app language.

Whatever you do with it, make sure the plain link without a parameter still works well. Many people will find your bot by searching its name, and they should get a good first message too.

Referral links

A referral link is a deep link where the parameter identifies the person who shared it. The usual pattern puts the user's numeric Telegram ID in the code:

https://t.me/your_bot?start=ref_123456789

When a new user arrives with that parameter, the bot knows user 123456789 invited them and can credit them. That's how "invite friends to earn points" features work. The contests template uses exactly this idea: in a points contest, each participant gets a personal link, and people who invite more friends get a better chance to win.

A few things to get right if you build or use referrals:

  • Credit only new users. Someone who already used the bot and taps a friend's link shouldn't count as a new referral.
  • Don't let people refer themselves. Check that the ID in the link isn't the user's own.
  • Expect gaming. If the reward is valuable, some people will create extra accounts to collect it. Rewarding activity, not just the tap on Start, makes this less worthwhile.

Adding a bot to a group with ?startgroup

There's a second kind of deep link for bots that work in groups:

https://t.me/your_bot?startgroup=from_site

Instead of opening a private chat, this link asks the user to pick one of their groups to add the bot to. The parameter follows the same rules: up to 64 characters, letters, numbers, underscores and hyphens.

It's useful on any page that promotes a group bot, such as a giveaway or verification bot. Group admins skip the steps of searching for the bot, opening its profile and finding the add button. Once it's in the group, the bot may still need admin rights to do its job. The steps are in how to add a bot to a Telegram group.

Reading the results honestly

Deep links only produce data if your bot saves the parameter when someone starts it. Check that before you print a hundred flyers. If your bot doesn't record it, there's a rougher method: share in different places on different days and compare new users per day. If Echo Maker runs your bot, the admin panel's statistics show new and active users by day and month, which is enough for this kind of check.

Keep in mind what the numbers can't tell you:

  • Forwarded links keep their code. If someone forwards your channel post to a friend, that friend counts as "channel" too. That's usually fine, because the channel post still started it.
  • Starts aren't loyal users. A source that brings many starts but few people who come back is worse than it looks. Compare how many users from each source are still active a week later.
  • Small numbers are noisy. Five users from one link and eight from another isn't a real difference. Wait until each source has enough users to compare.

For what to do with the results, see how to get your first 1,000 users. For the other technical numbers, like command length and message rates, see Telegram bot limits.

Common questions

How long can a Telegram deep link parameter be?

Up to 64 characters, using only A-Z, a-z, 0-9, underscores and hyphens.

Does the user see the start parameter?

It's part of the link, so anyone who looks at the link can read it. Don't put private information in it.

Do deep links work if the user already started the bot?

The link still opens the chat, but a returning user isn't a new user. Good tracking records the source only the first time someone appears, so returning users don't distort your numbers.

Can I use deep links without coding?

You can create the links yourself, since they're just text. Counting them requires a bot that saves the parameter when someone starts it.