CTA URL best practices for Telegram Ads
How to design the destination URL of a Telegram sponsored message — t.me deeplinks, external URLs, tracking parameters, common mistakes that hurt conversion.
6 min · updated 2026-05-19
Every Telegram sponsored message has exactly one click target — the URL behind the CTA button. Choice of destination dictates whether a click converts into a follow, a bot subscription, an app install, or a website visit. This guide covers the four canonical CTA URL shapes, what they actually do inside the Telegram client, and the conventions that matter for conversion and attribution.
#The four shapes
Every Telegram Ads CTA URL falls into one of four buckets:
1. **`t.me/<channel_username>`** — opens the channel preview inside Telegram. User taps "Join" → joins. This is the most common shape for B2C audience-building campaigns.
2. **`t.me/<bot_username>` or `t.me/<bot_username>?start=<param>`** — opens a bot conversation. The optional `?start=` parameter is delivered to the bot as the first message and is the standard way to pass campaign context (utm-equivalent for bots).
3. **`t.me/<bot_username>?startapp=<param>` or `?startapp=`** — opens the bot's Main Mini App (full-screen web view inside Telegram). The parameter becomes the `start_param` on the launched mini-app. Use for mini-app installs / direct cashier offers.
4. **`https://your-domain.com/...`** — opens the link in Telegram's in-app browser (or external browser if user has chosen that). Used when the destination is a regular landing page, app store listing, payment page, etc.
t.me links keep users inside Telegram — far higher conversion for in-platform actions. External HTTPS links lose ≈30–60 % of the click for app-store walls / login walls / context switches. Choose t.me whenever possible.
#What works inside the t.me deeplink param
When you use `t.me/<bot>?start=foo`, the bot receives the message `/start foo` on first contact. Best practices:
- Keep the param short — Telegram allows ≤64 chars for `start`, ≤512 for `startapp`.
- Use a campaign-id you control (e.g., `?start=ad_2026q2_crypto_ru`) so the bot can attribute the install to a specific creative. Most ad-cabinet attribution stops at impression level; `start` parameter is the only deterministic per-creative attribution channel for bot conversions.
- Don't put PII in the param — it ends up in user logs.
- For mini-apps with `?startapp=`, the mini-app reads `window.Telegram.WebApp.initDataUnsafe.start_param` on launch.
#External URLs — what to do and avoid
When the destination is a website (not Telegram), the URL must:
- Be **HTTPS** — Telegram silently drops HTTP CTAs from the cabinet.
- Use a **direct landing page** — no link shorteners (bit.ly, t.co etc. — Telegram moderation often rejects them; even when approved, they break attribution by adding an extra hop).
- Have a **mobile-first layout** — ≈85 % of Telegram traffic is mobile. A desktop-only landing kills conversion.
- Avoid redirect chains — every redirect hop loses click. Many cabinets count the click as "successful" only when the final landing page returns 200.
UTM-style query params (`?utm_source=tgads&utm_campaign=q2_launch`) work on external URLs and feed into your analytics like any other paid-traffic source. They do **not** work for `t.me` URLs — the Telegram client strips unknown query params before launching the deeplink.
#How tgadsspy parses CTA URLs
Every creative in the archive exposes four parsed fields derived from its CTA URL:
- **`ctaUrl`** — the raw URL as served by Telegram.
- **`ctaHost`** — hostname (e.g., `t.me` or `example.com`).
- **`ctaIsTelegram`** — boolean shortcut: true when host is `t.me` / `telegram.me` / `telegram.dog`.
- **`ctaTargetUsername`** — when the URL is a t.me deeplink, the username after the slash (e.g., `durov`, `tribute`). Populated only when the URL matches `t\.(me|dog)/[a-zA-Z0-9_]{3,32}`.
This lets you filter creatives by destination type — "all ads going to a specific bot", "all ads with external landing page", "all ads targeting `@crypto_signals_pro`" — using the public API or UI filters. See the API reference for the exact query params.
#Common mistakes that hurt conversion
1. **External URL when t.me would do.** Sending users to a website when the offer is a bot install or channel join doubles the friction. Always use t.me when the destination is in-platform.
2. **Generic landing page.** "Visit our site" CTAs convert 2–4× worse than "Join the channel" or "Open the mini-app" because the user has to figure out where the offer lives. Match CTA URL specificity to ad copy.
3. **Missing campaign attribution.** No `?start=` param on a bot CTA = no way to know which creative drove the install. Telegram won't tell you per-creative bot installs — only `start` parameter does.
4. **Shortener URLs.** Even if moderation lets them through, the extra hop adds ≈100–300 ms latency, breaks attribution for Telegram's own reporting, and triggers anti-phishing warnings in some clients.
5. **Stale t.me handles.** If you rename your channel or bot, old creatives still pointing at the old username will 404 the Telegram deeplink and show "Channel not found." Refresh creatives whenever a CTA target changes.
#See also
For creative copy alongside the CTA URL: /wiki/telegram-ads-creative-best-practices. For mini-app campaigns specifically: /wiki/mini-app-launch-playbook. For the launch workflow including cabinet setup: /wiki/how-to-launch-telegram-ads. Glossary references: /info/cta-button, /info/sponsored-message, /info/mini-app, /info/telegram-bot.