NEWASK is live: the AI brain that answers anything about your business.Meet ASK →
Blog/Telegram Channel Joins
Telegram

Telegram Channel Joins: What Is Technically Observable and What Is Not

7 day free trialNo credit card requiredSet up in 5 minutes
Direct answer

A bot can observe a Telegram channel join only if it is an administrator and has explicitly subscribed to the chat_member update. That update names the joining user and, if they used an invite link, which link. Joins made through a chat folder invite link or an approved join request carry no link attribution at all.

Telegram channel attribution is treated as either impossible or trivial depending on who is describing it, and both descriptions are wrong. Telegram exposes a precise, documented set of join signals, and a precise set of blind spots. This page is the map of both, quoted from the Bot API reference, which documented Bot API 10.2 dated 14 July 2026 when we checked it.

Can a Telegram bot see who joins a channel?

Only under two conditions, both of which have to be arranged deliberately. The bot must be an administrator, and it must ask for the update by name. Telegram states this in the Update object reference:

"chat_member ChatMemberUpdated Optional. A chat member's status was updated in a chat. The bot must be an administrator in the chat and must explicitly specify "chat_member" in the list of allowed_updates to receive these updates."

Telegram, Bot API, Update. core.telegram.org/bots/api#update. Bot API 10.2, 14 July 2026. Checked 14 August 2026.

The second condition is the one that catches people. chat_member is excluded from the default subscription set. Telegram's getUpdates reference states that an empty allowed_updates list means "receive all update types except chat_member, message_reaction, and message_reaction_count (default)". A bot that is a full administrator and receives nothing on join is almost always a bot that never listed the update.

Telegram has also been explicit that this is now the intended mechanism. Its changelog entry for Bot API 5.2 carries a warning: "Service messages about non-bot users joining the chat will be soon removed from large groups. We recommend using the "chat_member" update as a replacement."

What is in a ChatMemberUpdated?

Eight fields, three of which carry attribution information. Telegram describes the object as representing "changes in the status of a chat member", and the full field list is short enough to reproduce in full.

FieldTypeTelegram's description
chatChat"Chat the user belongs to"
fromUser"Performer of the action, which resulted in the change"
dateInteger"Date the change was done in Unix time"
old_chat_memberChatMember"Previous information about the chat member"
new_chat_memberChatMember"New information about the chat member"
invite_linkChatInviteLink"Optional. Chat invite link, which was used by the user to join the chat; for joining by invite link events only"
via_join_requestBoolean"Optional. True, if the user joined the chat after sending a direct join request without using an invite link and being approved by an administrator"
via_chat_folder_invite_linkBoolean"Optional. True, if the user joined the chat via a chat folder invite link"

That is the complete list. There are no other fields, and in particular there is no campaign field, no referrer and no source. Attribution has to be carried in the invite link itself, because the invite link is the only channel available.

The qualifier on invite_link is the whole design constraint: "for joining by invite link events only". A person who joins any other way produces a ChatMemberUpdated with no invite_link, and no amount of processing recovers what was never sent.

How do you attribute a join to a specific ad?

By minting an invite link per visitor before they arrive, and binding that link to the click record you already stored. When the join event arrives carrying that link, the join inherits the click's campaign, ad set and creative.

Telegram's createChatInviteLink gives you four levers:

ParameterTelegram's descriptionWhy it matters for attribution
name"Invite link name; 0-32 characters"32 characters is enough for a campaign code, not for a click record. Treat it as a label, not a payload
expire_date"Point in time (Unix timestamp) when the link will expire"Expiring a per-visitor link limits how long a shared screenshot can misattribute a join
member_limit"The maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999"Setting this to 1 is what makes a link genuinely per-person
creates_join_request"True, if users joining the chat via the link need to be approved by chat administrators. If True, member_limit can't be specified."Manual approval and a member limit are mutually exclusive. You choose one

The mutual exclusion in the last row is a real fork in the road. A link with member_limit set to 1 is single use and cannot be gated by approval. A link that creates join requests can be approved manually but can be used by any number of people, so it identifies a campaign rather than a person unless you mint one per visitor anyway.

One further constraint from the Bot API is easy to trip over: "Each administrator in a chat generates their own invite links. Bots can't use invite links generated by other administrators." Links created by a human admin in the Telegram app are not visible to your bot. Your bot has to create its own.

What does the invite link object tell you?

Less than you would expect. The Bot API's ChatInviteLink object exposes pending join requests but no cumulative usage count.

Its fields are invite_link, creator, creates_join_request, is_primary, is_revoked, name, expire_date, member_limit, pending_join_request_count, subscription_period and subscription_price. Telegram describes pending_join_request_count as the "Number of pending join requests created using this link".

There is no field for total joins through a link. That number exists in Telegram's underlying client API, where the chatInviteExported object carries a usage field, but it is not surfaced in the Bot API. The practical consequence: you count joins by counting chat_member updates as they arrive, not by polling a link for its total. Build the counter yourself, and make it idempotent, because a user who leaves and rejoins generates a second update.

A useful detail on link display

Telegram notes that on the invite_link string, "If the link was created by another chat administrator, then the second part of the link will be replaced with "…"." So an invite link you read from an update is not necessarily a link you can reuse or display. Store the identifier you minted it against rather than relying on the string.

Per-visitor invite links, generated automatically

FlowTracker mints a link per click, binds it to the stored click record, listens for the join and carries the attribution through to the sale. No invite link bookkeeping by hand.

Start 7 day free trial

What about join requests?

Join requests are a separate update with a richer payload, and they give you something the plain join does not: a short window in which the bot may message the person directly.

Telegram's ChatJoinRequest carries chat, from, user_chat_id, date, an optional bio, an optional invite_link described as the "Chat invite link that was used by the user to send the join request", and an optional query_id. The interesting field is user_chat_id:

"Identifier of a private chat with the user who sent the join request. [...] The bot can use this identifier for 5 minutes to send messages until the join request is processed, assuming no other administrator contacted the user."

Telegram, Bot API, ChatJoinRequest. core.telegram.org/bots/api#chatjoinrequest. Bot API 10.2, 14 July 2026. Checked 14 August 2026.

Five minutes is short, and it is a genuine opportunity: it is the one moment where you can open a private conversation with someone who has never messaged your bot. Telegram documented this change deliberately, noting in its changelog that "Bots are now allowed to contact users who sent a join request to a chat where the bot is an administrator with the can_invite_users administrator right - even if the user never interacted with the bot before."

To receive these updates at all, the bot needs a specific right: Telegram states the chat_join_request update requires that "The bot must have the can_invite_users administrator right in the chat to receive these updates."

Which joins can never be attributed?

Four kinds, and they are structural rather than fixable. Telegram does not publish a sentence saying so, but each follows directly from the field definitions quoted above.

There is a further asymmetry worth knowing. The Bot API provides no method that lists ordinary members. getChatAdministrators returns administrators, and getChatMember answers for one user ID at a time, with Telegram noting that it "is only guaranteed to work for other users if the bot is an administrator in the chat". getChatMemberCount returns a number and nothing else. You cannot enumerate a channel's membership and reconcile it against your click records after the fact. Attribution has to be captured at the moment of the join or not at all.

Does Telegram Ads give you a click ID?

No. Telegram's own advertising platform publishes no click identifier, no postback, no pixel and no conversion API. It measures joins internally and shows them as an aggregate chart in its dashboard.

Telegram describes what its statistics tab contains:

"Underneath, you will see a detailed graph showing views of your sponsored message and the number of times a user joined your channel or started the bot after viewing the sponsored message, able to be displayed in increments of minutes or days."

Telegram, Telegram Ads, Getting Started. promote.telegram.org/getting-started. Checked 14 August 2026.

Telegram also states on its ads homepage that "Ads on Telegram do not rely on users' personal information and are based on the channels where they are shown." That is a design position, not an omission, and it explains the absence of an advertiser-facing identifier.

The practical consequence: Telegram Ads spend is measurable only inside Telegram's own dashboard, at aggregate level. Traffic from Meta, Google or TikTok into the same channel is measurable at person level, because those platforms do issue click identifiers and the bridge page can store them. Do not expect one reporting view to cover both cleanly.

One link per person, or one link per campaign?

Per person if you need to attribute revenue, per campaign if you only need to compare traffic sources. The tradeoff is real and choosing the heavier option by default is a mistake.

 One link per campaignOne link per visitor
Setup effortMinutes, done by handNeeds a bridge page and a bot that mints links
Tells you joins per campaignYesYes
Tells you which ad produced a specific memberNoYes
Survives someone forwarding the linkAttributes the friend to the campaign tooContained, if member_limit is 1
Supports revenue per sourceNoYes
Supports a conversion sent back to the ad platformNoYes

Per-campaign links are genuinely useful and cost nothing, and for a channel that is not monetised per member they may be all you need. The moment you want to know which creative produced buyers rather than joiners, you need the per-visitor link, because that is the only structure that carries an identity rather than a label.

Putting it together

The working shape for a paid funnel into a Telegram channel is short:

  1. Bridge page stores the click. Click identifier, UTMs, timestamp, all written server side before the app switch. The reasons this cannot be skipped are in why the pixel cannot follow into a messaging app.
  2. Mint a per-visitor invite link. member_limit of 1, a sensible expire_date, and a name that carries a short campaign code for human readability.
  3. Listen for chat_member. Bot as administrator, chat_member explicitly in allowed_updates, and idempotent handling of rejoins.
  4. Join on invite_link. The link identifies the visitor, the visitor identifies the click, the click identifies the ad.
  5. Return the conversion. Within the platform's upload window, which for Meta is seven days from the event, as set out in conversion upload windows compared.

Where the funnel runs through a bot rather than a channel, the start parameter replaces the invite link and gives you the same handshake with less machinery. Both routes are covered on the Telegram ad tracker page, and the community-specific version is in signal groups and communities.

Sources

Every link below was fetched and read on 14 August 2026. Where a vendor does not document something, this article says so rather than filling the gap with an estimate.

Telegram, Bot APISource for the ChatMemberUpdated field list, the chat_member subscription requirement, the getUpdates default exclusion, createChatInviteLink parameters and ranges, the ChatInviteLink field list, ChatJoinRequest and the 5 minute user_chat_id window, and the getChatMember administrator caveat. The page documented Bot API 10.2, dated 14 July 2026, at time of checking. core.telegram.org/bots/api. Checked 14 August 2026.
Telegram, Bot API ChangelogSource for the recommendation to use the chat_member update in place of service messages, and for the change allowing bots to contact users who sent a join request. core.telegram.org/bots/api-changelog. Checked 14 August 2026.
Telegram, Invite links (client API)Source for the existence of a usage field on the underlying chatInviteExported object, which is not surfaced in the Bot API. core.telegram.org/api/invites. Checked 14 August 2026.
Telegram Ads, Getting StartedSource for what the Telegram Ads statistics tab reports, and for the absence of any advertiser-facing click identifier or conversion API. promote.telegram.org/getting-started. Checked 14 August 2026.
Meta, Server Event ParametersSource for the seven day event_time limit referenced in the final section. Page shows "Updated: Feb 12, 2026". developers.facebook.com/documentation/ads-commerce/conversions-api/parameters/server-event. Checked 14 August 2026.
Marked as inferenceTelegram publishes no statement that a join without an invite link cannot be attributed. That conclusion follows from the quoted field definitions, specifically the qualifier "for joining by invite link events only" on invite_link, and from the absence of any Bot API method that lists ordinary chat members. It is presented as reasoning, not as Telegram's words.

Last reviewed 14 August 2026

Telegram Attribution

Know which ad filled your channel

Per-visitor invite links, join matching and revenue attribution for Telegram channels, groups and bots, without building the invite link machinery yourself.

FAQ

Telegram Attribution, answered

Can a Telegram bot see who joined a channel?

Only if it is an administrator and has explicitly subscribed to the chat_member update. Telegram states: "The bot must be an administrator in the chat and must explicitly specify "chat_member" in the list of allowed_updates to receive these updates." That update is excluded from the default subscription set, which is why many correctly configured admin bots still receive nothing.

What does the ChatMemberUpdated object contain?

Eight fields: chat, from, date, old_chat_member, new_chat_member, and three optional attribution fields. Those are invite_link, described as the "Chat invite link, which was used by the user to join the chat; for joining by invite link events only", plus via_join_request and via_chat_folder_invite_link. There is no campaign, source or referrer field.

How do you attribute a Telegram channel join to a specific ad?

By creating an invite link per visitor before they arrive and binding it to the click record you stored on your bridge page. When the join arrives carrying that link, the join inherits the click's campaign and creative. Setting member_limit to 1 is what makes the link genuinely per-person.

What are the limits on a Telegram invite link?

Telegram documents the name as "0-32 characters", member_limit as "1-99999", an optional expire_date, and creates_join_request with the note "If True, member_limit can't be specified." A bot also cannot use invite links generated by other administrators, so it has to create its own.

Can you see how many people used a Telegram invite link?

Not through the Bot API. The ChatInviteLink object exposes pending_join_request_count but no cumulative usage count. A usage field exists on the underlying client API object, but it is not surfaced to bots. You count joins by counting chat_member updates as they arrive, and you make that counter idempotent because a user who leaves and rejoins generates a second update.

Which Telegram joins can never be attributed?

Joins through a chat folder invite link, direct join requests made without a link, arrivals from a username search or a forwarded screenshot, and any join in a chat where your bot is not an administrator. In each case the update either carries no invite_link or is never delivered at all.

Does Telegram Ads provide a click ID or conversion API?

No. Telegram publishes no advertiser-facing click identifier, postback, pixel or conversion API for its own ad platform. Its dashboard shows an aggregate graph of views and of "the number of times a user joined your channel or started the bot after viewing the sponsored message". Telegram states that its ads "do not rely on users' personal information".

Can a bot message someone who sent a join request?

Yes, briefly. The ChatJoinRequest object carries user_chat_id, and Telegram states: "The bot can use this identifier for 5 minutes to send messages until the join request is processed, assuming no other administrator contacted the user." The bot needs the can_invite_users administrator right to receive join request updates at all.

Keep reading