Telegram clients must handle special tg://
and t.me
deep links encountered in messages, link entities and in other apps by registering OS handlers.
Links are generally available in two flavors: t.me
HTTPS links and tg:
URIs.
t.me
link syntax examples:
t.me/path?query
http://t.me/path?query
https://t.me/path?query
Where t.me
can also be telegram.me
, telegram.dog
, and the domain specified in the me_url_prefix
field of the global configuration, obtainable using help.getConfig.
tg:
link syntax examples:
tg:path?query
tg://path?query
The #fragment
part is always ignored when parsing Telegram deep links.
Also note that whenever a <username>.t.me
link is encountered and <username>
is not equal to www
, is not a single letter and is a valid username, it should be treated exactly as a t.me/<username>/
link (generate a t.me/<username>/
link and append the rest of the path (if present) and the query string (if present)).
Used to link to public users, groups and channels, see here for more info on how to handle them ».
t.me
syntax:
t.me/<username>
tg:
syntax:
tg://resolve?domain=<username>
Parameters:
Name | Optional | Description |
---|---|---|
username |
Required | Username to check or import » |
Note that message links have the same syntax, with extra parameters.
Used to link to user profiles, generated using contacts.exportContactToken.
These links can be generated even for profiles that don't have a username, and they have an expiration date, specified by the expires
field of the exportedContactToken constructor returned by contacts.exportContactToken.
t.me
syntax:
t.me/contact/<token>
tg:
syntax:
tg://contact?token=<token>
Parameters:
Name | Optional | Description |
---|---|---|
token |
Required | Profile token to import using contacts.importContactToken, will return user information. |
Used to link to public and private users by their phone number.
t.me
syntax:
t.me/+<phone_number>
tg:
syntax:
tg://resolve?phone=<phone_number>
Parameters:
Name | Optional | Description |
---|---|---|
phone_number |
Required | Phone number to resolve using contacts.resolvePhone |
Note that chat invite links have the same syntax, but <phone_number>
won't be a valid phone number.
Used to invite users to private groups and channels, see here for more info on how to generate such links ».
t.me
syntax:
t.me/+<hash>
t.me
syntax (legacy):
t.me/joinchat/<hash>
tg:
syntax:
tg://join?invite=<hash>
Parameters:
Name | Optional | Description |
---|---|---|
hash |
Required | Invite hash to check or import » |
Used to invite users to private groups and channels, see here for more info on how to generate such links ».
t.me
syntax:
t.me/addlist/<slug>
tg:
syntax:
tg://addlist?slug=<slug>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Invite slug to check or import » |
Used to link to specific messages in public or private groups and channels.
t.me
syntax (public links):
t.me/<username>/<thread_id>/<id>?single&comment=<message_id>&t=<media_timestamp>
t.me/<username>/<id>?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
t.me
syntax (private links):
t.me/c/<channel>/<id>?single&thread=<thread_id>&comment=<message_id>&t=<media_timestamp>
t.me/c/<channel>/<thread_id>/<id>?single&comment=<message_id>&t=<media_timestamp>
tg:
syntax (public links):
tg://resolve?domain=<username>&post=<id>&single&thread=<thread_id>&comment=<comment>&t=<media_timestamp>
tg:
syntax (private links):
tg://privatepost?channel=<channelid>&post=<id>&single&thread=<thread_id>&comment=<comment>&t=<media_timestamp>
Parameters:
Name | Optional | Description |
---|---|---|
username |
Required if public link | Dialog username. |
channel |
Required if private link | Channel or supergroup ID. |
id |
Required | Message ID. |
single |
Optional | For albums/grouped media, if set indicates that this is a link to a specific media in the album; otherwise, it is a link to the entire album. |
thread_id |
Optional | For message threads, contains the thread ID. |
comment |
Optional | For channel comments, username will contain the channel username, id will contain the message ID of the channel message that started the comment section and this field will contain the message ID of the comment in the discussion group. |
media_timestamp |
Optional | Timestamp at which to start playing the media file present in the body or in the webpage preview of the message, in the following formats: - Seconds: 123 , regex ^(\d+)$ - Minutes and seconds: 10:23 , example regex ^(\d+):(\d{1,2})$ - Hours, minutes and seconds: 1h23m10s , example regex ^(?:(\d+)h)?(?:(\d{1,2})m)?(?:(\d{1,2})s)$ |
Note that since a forum topic ID is actually the ID of the service message that created the topic, whenever the client resolves a message link that points to a messageActionTopicCreate service message, it should open the topic, instead.
Also, if the message ID is 1
and the linked-to supergroup is a forum, the "General" topic should be opened instead of the first message of the supergroup.
Used to link to a specific forum topic.
The syntax is exactly the same as for message links, because the topic ID is actually the ID of the service message that created the topic, so whenever the client resolves a message link that points to a messageActionTopicCreate service message, it should open the topic, instead.
Also, if the message ID is 1
and the linked-to supergroup is a forum, the "General" topic should be opened instead of the first message of the supergroup.
Used to share a prepared message and URL into a chosen chat's text field.
These links should be handled as follows:
text
, if presentt.me
syntax:
t.me/share?url=<url>
t.me/share?url=<url>&text=<text>
tg:
syntax:
tg://msg_url?url=<url>&text=<text>
Parameters:
Name | Optional | Description |
---|---|---|
url |
Required | URL to share (urlencoded) |
text |
Optional | Message to share |
Used to join video/voice chats in groups, and livestreams in channels.
Such links are generated using phone.exportGroupCallInvite.
Note that voicechat
links are deprecated, the API will always export videochat
links for video and voice chats in groups, clients should support parsing the old link format only for backwards compatibility.
t.me
syntax:
t.me/<username>?videochat
t.me/<username>?videochat=<invite_hash>
t.me/<username>?livestream
t.me/<username>?livestream=<invite_hash>
t.me/<username>?voicechat
t.me/<username>?voicechat=<invite_hash>
tg:
syntax:
tg://resolve?domain=<username>&videochat
tg://resolve?domain=<username>&videochat=<invite_hash>
tg://resolve?domain=<username>&livestream
tg://resolve?domain=<username>&livestream=<invite_hash>
tg://resolve?domain=<username>&voicechat
tg://resolve?domain=<username>&voicechat=<invite_hash>
Parameters:
Name | Optional | Description |
---|---|---|
invite_hash |
Optional | Invite hash exported if the can_self_unmute flag is set when calling phone.exportGroupCallInvite: should be passed to phone.joinGroupCall, allows the user to speak in livestreams or muted group chats. |
Used to import stickersets or custom emoji stickersets as described here ».
t.me
syntax:
t.me/addstickers/<slug>
t.me/addemoji/<slug>
tg:
syntax:
tg://addstickers?set=<slug>
tg://addemoji?set=<slug>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Stickerset short name, used when installing stickers. |
Used to import custom emoji stickersets as described here ».
t.me
syntax:
t.me/addemoji/<slug>
tg:
syntax:
tg://addemoji?set=<slug>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Stickerset short name, used when installing stickers. |
Used to share a proxy server that can be used to connect to Telegram.
Used for MTProxies ».
t.me
syntax:
t.me/proxy?server=<server>&port=<port>&secret=<secret>
tg:
syntax:
tg://proxy?server=<server>&port=<port>&secret=<secret>
Parameters:
Name | Optional | Description |
---|---|---|
server |
Required | MTProxy server IP address or host |
port |
Required | MTProxy server port |
secret |
Required | MTProxy secret » |
Used for socks5 proxies.
t.me
syntax:
t.me/socks?server=<server>&port=<port>&user=<user>&pass=<pass>
tg:
syntax:
tg://socks?server=<server>&port=<port>&user=<user>&pass=<pass>
Parameters:
Name | Optional | Description |
---|---|---|
server |
Required | Proxy server IP address or host |
port |
Required | Proxy server port |
user |
Optional | Proxy server username |
pass |
Optional | Proxy server password |
Used to install themes ».
t.me
syntax:
t.me/addtheme/<name>
tg:
syntax:
tg://addtheme?slug=<name>
Parameters:
Name | Optional | Description |
---|---|---|
name |
Required | Theme short name used when installing themes » |
Used to share and install chat backgrounds (wallpapers): see here for more info on the various wallpaper and fill types ».
Used for image-based wallpapers ».
t.me
syntax:
t.me/bg/<slug>?mode=<mode>
tg:
syntax:
tg://bg?slug=<slug>&mode=<mode>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Wallpaper slug used to obtain the image file using account.getWallPaper. |
mode |
Optional | A combination of blur and motion (joined by + ) to enable blurring and/or parallax motion as specified in the docs ». |
Used for fill wallpapers » with a solid fill ».
t.me
syntax:
t.me/bg/<hex_color>
tg:
syntax:
tg://bg?color=<hex_color>
Parameters:
Name | Optional | Description |
---|---|---|
hex_color |
Required | Fill color in hex RGB format. |
Used for fill wallpapers » with a gradient fill ».
t.me
syntax:
t.me/bg/<top_color>-<bottom_color>?rotation=<rotation>
tg:
syntax:
tg://bg?gradient=<top_color>-<bottom_color>&rotation=<rotation>
Parameters:
Name | Optional | Description |
---|---|---|
top_color |
Required | Top gradient color in hex RGB format. |
bottom_color |
Required | Bottom gradient color in hex RGB format. |
rotation |
Optional | Clockwise rotation angle of the gradient, in degrees; 0-359. Must be always divisible by 45, default to 0 if not set. |
Used for fill wallpapers » with a freeform gradient fill ».
t.me
syntax:
t.me/bg/<hex_color1>~<hex_color2>~<hex_color3>
t.me/bg/<hex_color1>~<hex_color2>~<hex_color3>~<hex_color4>
tg:
syntax:
tg://bg?gradient=<hex_color1>~<hex_color2>~<hex_color3>
tg://bg?gradient=<hex_color1>~<hex_color2>~<hex_color3>~<hex_color4>
Parameters:
Name | Optional | Description |
---|---|---|
hex_color1 |
Required | First gradient color in hex RGB format. |
hex_color2 |
Required | Second gradient color in hex RGB format. |
hex_color3 |
Required | Third gradient color in hex RGB format. |
hex_color4 |
Optional | Fourth gradient color in hex RGB format. |
Used for pattern wallpapers » with a solid fill ».
t.me
syntax:
t.me/bg/<slug>?intensity=<intensity>&bg_color=<bg_color>&mode=<mode>
tg:
syntax:
tg://bg?slug=<slug>&intensity=<intensity>&bg_color=<bg_color>&mode=<mode>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Wallpaper slug used to obtain the pattern file using account.getWallPaper. |
intensity |
Required | A value ranging from -100 to 100, used to combine the pattern with the fill as specified in the docs. |
bg_color |
Required | Fill color in hex RGB format. |
mode |
Optional | motion to enable parallax motion as specified in the docs. |
Used for pattern wallpapers » with a gradient fill ».
t.me
syntax:
t.me/bg/<slug>?intensity=<intensity>&bg_color=<top_color>-<bottom_color>&rotation=<rotation>&mode=<mode>
tg:
syntax:
tg://bg?slug=<slug>&intensity=<intensity>&bg_color=<top_color>-<bottom_color>&rotation=<rotation>&mode=<mode>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Wallpaper slug used to obtain the pattern file using account.getWallPaper. |
intensity |
Required | A value ranging from -100 to 100, used to combine the pattern with the fill as specified in the docs. |
top_color |
Required | Top gradient color in hex RGB format. |
bottom_color |
Required | Bottom gradient color in hex RGB format. |
rotation |
Optional | Clockwise rotation angle of the gradient, in degrees; 0-359. Must be always divisible by 45, default to 0 if not set. |
mode |
Optional | motion to enable parallax motion as specified in the docs. |
Used for pattern wallpapers » with a freeform gradient fill ».
t.me
syntax:
t.me/bg/<slug>?intensity=<intensity>&bg_color=<hex_color1>~<hex_color2>~<hex_color3>&mode=<mode>
t.me/bg/<slug>?intensity=<intensity>&bg_color=<hex_color1>~<hex_color2>~<hex_color3>~<hex_color4>&mode=<mode>
tg:
syntax:
tg://bg?slug=<slug>&intensity=<intensity>&bg_color=<hex_color1>~<hex_color2>~<hex_color3>&mode=<mode>
tg://bg?slug=<slug>&intensity=<intensity>&bg_color=<hex_color1>~<hex_color2>~<hex_color3>~<hex_color4>&mode=<mode>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Wallpaper slug used to obtain the pattern file using account.getWallPaper. |
intensity |
Required | A value ranging from -100 to 100, used to combine the pattern with the fill as specified in the docs. |
hex_color1 |
Required | First gradient color in hex RGB format. |
hex_color2 |
Required | Second gradient color in hex RGB format. |
hex_color3 |
Required | Third gradient color in hex RGB format. |
hex_color4 |
Optional | Fourth gradient color in hex RGB format. |
mode |
Optional | motion to enable parallax motion as specified in the docs. |
Used to link to bots.
t.me
syntax:
t.me/<bot_username>?start=<parameter>
tg:
syntax:
tg://resolve?domain=<bot_username>&start=<parameter>
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Bot username |
parameter |
Optional | Start parameter, up to 64 base64url characters: if provided and the bot_username is indeed a bot, the text input bar should be replaced with a Start button (even if the user has already started the bot) that should invoke messages.startBot with the appropriate parameter once clicked. |
Used to add bots to groups or channels.
First of all, check that the <bot_username>
indeed links to a bot.
Then, for group links:
admin
parameter is not provided:parameter
is provided, invoke messages.startBot with the appropriate parameter
admin
parameter is provided:admin
parameter
is provided, invoke messages.startBot with the appropriate parameter
For channel links:
admin
t.me
syntax (groups):
t.me/<bot_username>?startgroup=<parameter>&admin=<permissions>
t.me/<bot_username>?startgroup&admin=<permissions>
tg:
syntax (groups):
tg://resolve?domain=<bot_username>&startgroup=<parameter>&admin=<permissions>
tg://resolve?domain=<bot_username>&startgroup&admin=<permissions>
t.me
syntax (channels):
t.me/<bot_username>?startchannel&admin=<permissions>
tg:
syntax (channels):
tg://resolve?domain=<bot_username>&startchannel&admin=<permissions>
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Bot username |
parameter |
Optional for group links, absent in channel links | Start parameter, only for group links, up to 64 base64url characters: if provided and the bot_username is indeed a bot, messages.startBot with the appropriate parameter should be invoked after adding the bot to the group. |
admin |
Optional for group links, required for channel links | A combination of the following identifiers separated by + , each corresponding to the appropriate flag in the chatAdminRights » constructor: - change_info - chatAdminRights.change_info - post_messages - chatAdminRights.post_messages - edit_messages - chatAdminRights.edit_messages - delete_messages - chatAdminRights.delete_messages - restrict_members - chatAdminRights.ban_users - invite_users - chatAdminRights.invite_users - pin_messages - chatAdminRights.pin_messages - manage_topics - chatAdminRights.manage_topics - promote_members - chatAdminRights.add_admins - manage_video_chats - chatAdminRights.manage_call - anonymous - chatAdminRights.anonymous - manage_chat - chatAdminRights.other |
Used to share games.
These links should be handled as follows:
bot_username
is indeed a bot username, if so thent.me
syntax:
t.me/<bot_username>?game=<short_name>
tg:
syntax:
tg://resolve?domain=<bot_username>&game=<short_name>
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Username of the bot that owns the game |
short_name |
Required | Game short name |
Used to share named bot web apps.
These links are different from bot attachment menu deep links, because they don't require the user to install an attachment menu, and a single bot can offer multiple named web apps, distinguished by their short_name
.
These links should be handled as specified in the named bot web app documentation ».
t.me
syntax:
t.me/<bot_username>/<short_name>?startapp=<start_parameter>
tg:
syntax:
tg://resolve?domain=<bot_username>&appname=<short_name>&startapp=<start_parameter>
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Username of the bot that owns the game |
appname |
Required | Web app short name, to pass to inputBotAppShortName.short_name when invoking messages.getBotApp |
startapp |
Optional | start_param to pass to messages.requestAppWebView |
Used to bring the user to the app settings.
tg:
syntax:
tg://settings
No parameters.
Used to bring the user to the phone number modification page, invoking account.sendChangePhoneCode and account.changePhone.
tg:
syntax:
tg://settings/change_number
No parameters.
Used to bring the user to the active sessions page, calling account.getAuthorizations.
tg:
syntax:
tg://settings/devices
No parameters.
Used to bring the user to the folder settings.
tg:
syntax:
tg://settings/folders
No parameters.
Used to bring the user to the language settings.
tg:
syntax:
tg://settings/language
No parameters.
Used to bring the user to the privacy and security settings.
tg:
syntax:
tg://settings/privacy
No parameters.
Used to bring the user to the message autodeletion settings.
tg:
syntax:
tg://settings/auto_delete
No parameters.
Used to bring the user to the profile settings menu.
tg:
syntax:
tg://settings/edit_profile
No parameters.
Used to bring the user to the theme settings section of the app.
tg:
syntax:
tg://settings/theme
No parameters.
Contains the phone number verification code to use during user authorization ».
t.me
syntax:
t.me/login/<code>
tg:
syntax:
tg://login?code=<code>
Parameters:
Name | Optional | Description |
---|---|---|
code |
Required | Login code. |
Used to initiate payment of an invoice », generated using payments.exportedInvoice.
t.me
syntax:
t.me/invoice/<slug>
t.me/$<slug>
tg:
syntax:
tg://invoice?slug=<slug>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | The invoice slug to be used during payment ». |
Used to import custom language packs using langpack.getLangPack.
t.me
syntax:
t.me/setlanguage/<slug>
tg:
syntax:
tg://setlanguage?lang=<slug>
Parameters:
Name | Optional | Description |
---|---|---|
slug |
Required | Name of language pack to import using langpack.getLangPack |
See the Telegram Passport documentation for parameters and usage ».
tg:
syntax:
tg://passport?params
tg://resolve?domain=telegrampassport¶ms
Different from login code links.
These links are used to confirm ownership of the phone number, to prevent account deletion: see the account deletion docs for more info on how to handle them ».
t.me
syntax:
t.me/confirmphone?phone=<phone>&hash=<hash>
tg:
syntax:
tg://confirmphone?phone=<phone>&hash=<hash>
Parameters:
Name | Optional | Description |
---|---|---|
phone |
Required | Phone number |
hash |
Required | Confirmation hash to handle as described here » |
Used by official apps to show the Telegram Premium subscription page.
tg:
syntax:
tg://premium_offer?ref=<referrer>
Parameters:
Name | Optional | Description |
---|---|---|
referrer |
Optional | Used by official apps for analytics using help.saveAppLog |
Used by QR code login.
tg:
syntax:
tg://login?token=<base64encodedtoken>
Parameters:
Name | Optional | Description |
---|---|---|
server |
Required | Base64URL-encoded QR code login token |
Used to install and optionally open a bot attachment menu » in a certain chat.
For all link types, clients should:
peer_types
field.Installs and opens an attachment menu web app in the currently open chat.
t.me
syntax:
t.me/<bot_username>?startattach
t.me/<bot_username>?startattach=<start_parameter>
tg:
syntax:
tg://resolve?domain=<bot_username>&startattach
tg://resolve?domain=<bot_username>&startattach=<start_parameter>
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Username of the bot that owns the attachment menu |
start_parameter |
Optional | If provided, should be passed to messages.requestWebView.start_param |
Installs and opens an attachment menu web app in a specific chat.
t.me
syntax:
t.me/<username>?attach=<bot_username>
t.me/<username>?attach=<bot_username>&startattach=<start_parameter>
t.me/+<phone_number>?attach=<bot_username>
t.me/+<phone_number>?attach=<bot_username>&startattach=<start_parameter>
tg:
syntax:
tg://resolve?domain=<username>&attach=<bot_username>
tg://resolve?domain=<username>&attach=<bot_username>&startattach=<start_parameter>
tg://resolve?phone=<phone_number>&attach=<bot_username>
tg://resolve?phone=<phone_number>&attach=<bot_username>&startattach=<start_parameter>
Parameters:
Name | Optional | Description |
---|---|---|
username |
Required for username links | Username of chat where to open web app |
phone_number |
Required for phone number links | Phone number of private chat where to open web app |
bot_username |
Required | Username of the bot that owns the attachment menu |
start_parameter |
Optional | If provided, should be passed to messages.requestWebView.start_param |
Installs an attachment menu, opens a dialog selection form that will open the attachment menu web app in a specific chat.
t.me
syntax:
t.me/<bot_username>?startattach&choose=users+bots+groups+channels
t.me/<bot_username>?startattach=<start_parameter>&choose=users+bots+groups+channels
tg:
syntax:
tg://resolve?domain=<bot_username>&startattach&choose=users+bots+groups+channels
tg://resolve?domain=<bot_username>&startattach=<start_parameter>&choose=users+bots+groups+channels
Parameters:
Name | Optional | Description |
---|---|---|
bot_username |
Required | Username of the bot that owns the attachment menu |
start_parameter |
Optional | If provided, should be passed to messages.requestWebView.start_param |
choose |
Optional | A combination of users , bots , groups , channels separated by + : indicates the dialog types to show in the dialog selection popup: must be intersected with the dialog types contained in the attachMenuBot.peer_types field before use. |
ID links are merely an abstraction offered by the bot API to simplify construction of inputMessageEntityMentionName and inputKeyboardButtonUserProfile constructors, and should be ignored by normal clients.
tg:
syntax:
tg://user?id=<id>
Parameters:
Name | Optional | Description |
---|---|---|
id |
Required | User ID |
Emoji links are merely an abstraction offered by the bot API to simplify construction of messageEntityCustomEmoji constructors, and should be ignored by normal clients.
tg:
syntax:
tg://emoji?id=<id>
Parameters:
Name | Optional | Description |
---|---|---|
id |
Required | Custom emoji ID |
If a client encounters a tg:
link type not listed on this page, help.getDeepLinkInfo should be invoked with just the path
component of the link.
Schema:
help.deepLinkInfoEmpty#66afa166 = help.DeepLinkInfo;
help.deepLinkInfo#6a4ee832 flags:# update_app:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = help.DeepLinkInfo;
---functions---
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
The method may return formatted text, containing for example:
And/or an invitation to upgrade to the latest version of the client app to be able to use the link: in this case, the result update_app
flag will also be set, and the app should directly link to a store or attempt updating to the latest version.
Example links that can be used for testing:
tg://need_update_for_some_feature?test=a
tg:some_unsupported_feature?test=b
In these cases, help.getDeepLinkInfo should be invoked with the following parameters:
help.getDeepLinkInfo({path: "need_update_for_some_feature"})
help.getDeepLinkInfo({path: "some_unsupported_feature"})
Note that this method should not be called for unrecognized t.me
links, the usual HTTP link handling logic should be used, instead.