UTM tracking for a Telegram bot: a funnel from click to payment
UTM tags work fine on a website but never reach a Telegram bot: from a t.me link the bot gets only the start parameter. That is why bot ads are often judged by gut feeling. Here is how to tie an ad click to a bot start, a sign-up and a payment, and see which source pays off.
In short. From a link, Telegram passes your bot only the start parameter — up to 64 characters, no UTM tags. To know where every user came from, send ad traffic through an MGRAM UTM short link: on click it records the source and puts the click number {click_id} into the bot's address. The bot reports steps — start, sign-up, payment — with that number, and the panel builds the funnel and revenue for every link.
Why UTM tags don't work in a Telegram bot
On a website, analytics reads UTM tags from the address. A bot can't: from https://t.me/your_bot?start=oct_mailing it receives only the command /start oct_mailing, and Telegram drops everything else. The start parameter holds up to 64 characters: Latin letters, digits, _ and -.
You can put the source straight into the start parameter, but then everything else is on you: storing the tag per user, counting clicks, separating repeat starts, matching sign-ups and payments to sources. And you never learn how many people clicked the link but didn't start the bot.
How an MGRAM UTM funnel works
| Part | What it is |
|---|---|
| Project | Where traffic goes — a bot, a website or a Mini App — and the steps after the click, for example «start → sign-up → payment» |
| Link | A short address like https://utm.mgram.biz/abc1234 with its own UTM tags — one per traffic source |
| Click | MGRAM records the click, fills the placeholders in the address and sends the person on |
| Step | Your bot, website or server reports what the person did, with the click number — the step is credited to the link and its tags |
The link's UTM tags are stored by MGRAM, so you don't squeeze them into the start parameter: only the click number goes there.
Placeholders in the address
Placeholders go in curly braces right in the project's address and are filled on every click.
| Placeholder | What it becomes |
|---|---|
{click_id} | The click number — pass it down the funnel: into the bot's /start or the website address |
{utm_source} … {utm_term} | The link's UTM tags |
{sub1} … {sub5} | Values from the click address, for example …/abc1234?sub1=vk |
{project}, {link} | The project number and the link code |
{country} | The visitor's country |
{ts} | Click time, Unix format |
Ready-made addresses:
- bot —
https://t.me/your_bot?start={click_id}; - Mini App —
https://t.me/your_bot/app?startapp={click_id}; - website —
https://your-site.com/?mgram_cid={click_id}. The link's UTM tags are added to a website address automatically if it has none.
How to set up a funnel
- Open the panel app.mgram.biz → «Реклама» → «UTM-воронки» (Ads → UTM funnels) and click «Новый проект» (New project). The panel is in Russian for now.
- Pick a template: Telegram bot (steps start → sign-up → payment), website (visit → lead → purchase), Mini App (open → target action) or your own.
- Check the address with
{click_id}, set a name and the UTM tags of the first link. - Save the write key: it is shown once. Keep it in the server's environment variables, for example
MGRAM_UTM_KEY. - Create a link for every source: a broadcast, Reply Ads, your channel, a blogger.
- Copy the step-sending code from the «Интеграция» (Integration) tab into your bot or website.
Clicks are counted right away, with no code. Code is needed for the steps after the click.
How the bot reports steps
A step is a POST request to https://utm.mgram.biz/api/v1/events with the write key in the header Authorization: Bearer utm_sk_…. The panel has ready code for Python, aiogram, JavaScript, PHP, cURL and websites.
| Field | Why |
|---|---|
step | The step key: start, register, pay. A new key is added to the funnel automatically |
click_id | The click number — ties the step to the link and its source |
link | The link code when there was no click, for example the bot was opened by its own link |
user_id | Your user ID |
value, currency | The step's amount and currency — the panel sums revenue per link from them |
event_id | Your event number: sending it again won't double the step |
unique | true — the step counts once per click or user |
In a bot it looks like this:
- A person taps the ad link and starts the bot — the bot gets
/start <click number>. - In the /start handler the bot sends the
startstep with that number and saves the number for the user. - After sign-up the bot sends
registerwith the same number, after payment —paywith the amount.
Example request body: {"step": "register", "click_id": "…", "user_id": "42", "unique": true}. Events can be sent in batches of up to 100 per request.
On a website, add the script https://utm.mgram.biz/t.js with the project's public key: from the browser only steps marked «site» in the project are counted. Never put the write key into page code — it is for servers and bots only.
UTM links in MGRAM ads
- Broadcasts and Reply Ads. Put the link into the post's button. To compare the services, make a copy of the post for each — with its own link.
- Bot launches. At the «link» step of a launches order, send the address with the link code:
https://t.me/your_bot?start=<link code>. The bot passes this code asclick_idin its steps — they are credited to that link, and so to that order. - AI assistant. With MGRAM in ChatGPT and Claude the assistant creates the project, links and post copies itself and later shows clicks and funnel steps for every order.
What the stats show
- Overview: clicks, unique visitors, the funnel — how many people reached each step and the conversion between steps, a daily chart, sources.
- Links: numbers for every link, to compare sources and orders.
- Activity: a feed of clicks and steps, newest first.
Clicks from link-preview bots — Telegram, VK, Facebook and others — are counted separately and don't skew the stats. MGRAM does not store IP addresses: unique visitors are counted by a daily anonymised fingerprint.
How to compare sources
| Metric | How to calculate |
|---|---|
| Cost per click | Spend on the source ÷ clicks on its link |
| Cost per start | Spend ÷ start steps |
| Cost per sign-up | Spend ÷ register steps |
| Cost per payment | Spend ÷ pay steps |
| Return on ad spend (ROAS) | Sum of pay steps ÷ spend |
A cheap click is not a cheap customer: decide by cost per payment and return on ad spend.
Common mistakes
- The bot didn't save the click number. The
startstep arrives, but sign-ups and payments come withoutclick_id, and the source is lost. Save the number for the user right at /start. - One link for all sources. Then the funnel is shared and there is nothing to compare — create a link per placement.
- The write key in the browser. Anyone can take it from the page code. On a website use only the public key and «site» steps.
- Duplicate payments. Pass
event_id: resending the same event won't double the revenue.
Limits
Up to 50 projects, up to 500 links per project, up to 20 funnel steps, up to 1,200 events per minute and 100 per request. Full API reference (in Russian) — MGRAM UTM docs.