UTM start-param builder
Build Telegram bot deep links that carry marketing attribution all the
way into the user's first /start interaction. Copy the URL
for ads/QR/email; copy the matching Python or JS snippet to decode the
payload server-side.
Why this exists
Telegram lets you append ?start=xxx to any bot URL. The
xxx string (≤64 chars, alphanumeric + _ and
-) is delivered to your bot the first time the user opens
it. That's the only attribution channel Telegram gives you — no
referrer header, no campaign cookie, no UTM passthrough.
The trick is to encode your full UTM tuple into that single token, decode it server-side, and write the resulting source / medium / campaign to your user record. Then your funnel analysis works exactly like it does on the web.
Compact vs. encoded modes
| Compact | Joins fields with _: instagram_story_summer25. Human-readable, well under 64 chars. Recommended default. |
| Base64 | JSON-encode the UTM object, then base64url it. Slightly more capacity. Use only when compact mode overflows. |
Server-side decode
Common pitfalls
- Only first
/startcarries the param. Subsequent/startcommands (without a query) won't. Record the attribution the first time the user appears. - Don't reuse the same payload across campaigns. You want one URL per ad/banner/QR so the data is partitionable later.
- Special chars get rejected silently. Stick to
[A-Za-z0-9_-]. Spaces, commas, and emojis cause Telegram to drop the start_param. - Group invites use
?startgroup=…instead. Same encoding rules apply.