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.

