Repository navigation
sessions
Read this page when you connect tg to your Telegram account for the first time, when you add a
second account, or when tg says you are not logged in. At the end you know how to log in, how to
check who you are logged in as, how to log out, and where tg keeps what it needs to stay logged in.
First, the words this page uses:
-
Session: the login of
tgon this computer. Telegram issues it when you log in, and lists it in the Telegram app as one more device.tgkeeps it in a file. Whoever has that file can read your chats, so treat it like your password. -
App (
api_idandapi_hash): two values from my.telegram.org that identify the program to Telegram. Each user registers their own app once;tgcan do it for you. -
Keyring: the password store of your operating system.
tgkeeps the app values there. -
Profile: a name for one login on this computer, with its own session, app and settings. Every
command that uses an account names it, so you pick one name at setup (
tg personal setup) and use it from then on (profiles).
Do not confuse tg personal session with tg personal account sessions. tg personal session is the login of tg itself;
tg personal account sessions lists every other device and app logged in to your account.
tg personal setup guides a first run through the app and the session, checks five chats and offers an agent
skill. Allow about five minutes; history downloads are a separate step. Run it in a terminal. Use
tg personal setup --app browser for manual app registration or --method phone for a phone login.
tg personal session start remains the command for login alone, including resuming an interrupted login.
Setup checks an existing session and does not silently log in again if it is rejected.
Every user registers their own app. Telegram gives one app per phone number, so an app id is never
shared or built into tg. You need it once per profile; tg personal session start asks only when the profile
has none.
Two ways to get it:
-
--app browseropens my.telegram.org/apps. Log in there, create an app if you have none (any title and short name, platform Desktop), and pasteApp api_idandApp api_hashwhentgasks. The hash is not shown as you type. This is the default fortg personal session start. -
--app autofills in the site for you. It asks your phone number and the code my.telegram.org sends you as a message in Telegram, then reads your app, or creates one if you have none. The site has no API, sotgfollows its web form; a change on Telegram's side can break this.--app browserstill works then. This is the default fortg setup.
The app is stored only after Telegram has accepted the login.
tg personal session start # a QR code in the terminal
tg personal session start phone # a phone number, the code Telegram sends, and your 2FA password
tg personal session start phone --sms # the same, asking Telegram for the code by SMSQR: scan the code in the Telegram app: Settings → Devices → Link Desktop Device. The code is renewed while you wait.
Phone: type the number in international format, then the login code. If the account has a
cloud password (2FA), tg asks for it without showing what you type. With --app auto, the phone
number is asked only once. The code usually arrives in the Telegram app; --sms asks for an SMS
instead, but Telegram chooses, and tg says which way it was sent. When Telegram has no SMS for the
account, tg says so and asks for the code from the app.
After either, Telegram lists a new device in the app's list of sessions.
Logged in as <your name> (@<username>, id <id>) — profile default.
Session: ~/.local/share/tg-cli/sessions/default.session
App keys: in the keyring
Next: tg personal chats list · tg personal server install to keep the archive current
Your AI agent can start the login for you, but it has no terminal to draw the QR code in.
--qr-file writes the code as a picture (PNG) instead, and the agent shows it to you to scan:
tg personal session start --qr-file login.pngThe file is replaced when Telegram renews the code, and removed when the login ends, whether it
worked or not. Without a terminal this works only when the profile already has its app and the
account has no 2FA password: anything else you have to type yourself. tg personal setup takes the same
--qr-file option.
tg personal account show # who this profile is logged in as
tg account list # every profile on this computer, and the account each is logged in as
tg personal account sessions list # every device and app logged in to the account; ends nothing
tg personal session end # log out on Telegram's side, and delete the session file heretg personal session end ends the session on Telegram's side too: the device disappears from the list in
the app. It does not delete the app id and hash from the keyring, and it leaves the local store as
it is.
Until it is ended: by tg personal session end, from the list of devices in a Telegram app, or by Telegram
itself once the session has gone unused for longer than the account's limit for inactive sessions
(authorization_ttl_days in
Telegram's API), which the apps let
you set in the list of devices. A profile that runs every day never reaches it. When a session has
ended, every command answers "not logged in, or the session was ended" with exit code 4; log in
again with tg personal session start
(what to do when the session was ended).
A profile is a separate login: its own session, app, settings, recipients and runs. It is named by the first word, not by an option:
tg personal chats list # profile "personal"
tg work chats list # profile "work"
export TG_PROFILE=work # the same for the whole shell sessionThe first word is the profile when it is not a command. A profile therefore cannot be called
chats, messages or any other command word; tg personal session start refuses such a name. Names are
letters, digits, dot, dash and underscore, starting with a letter or a digit.
The order, first match wins: the first word, TG_PROFILE, default_profile in the config file. With
none of them, a command that uses an account stops with exit code 2 and lists the profiles on this
computer; with none there yet, it says to run tg personal setup. tg never picks one, not even the
only one. Commands that use no account run without a profile: --help, --version, commands,
skill show, account list and config show.
A word that is not a command and has no command after it is an error that says so:
"nonsense" is not a command, so it was read as a profile name — and no command followed it.
TG_PROFILE_LOCK pins a process to one profile. Set it where an agent runs, and a first word or
TG_PROFILE naming any other profile is refused (exit code 5). Without it, an agent could pick a
profile with fewer limits.
What each profile is for, and how a profile works with a bot: profiles and bots.
| What | Where |
|---|---|
| the session |
sessions/<profile>.session in the state directory |
| the app id and hash | the OS keyring, service tg-cli, entry <profile>:api
|
| the app id and hash, with no keyring |
credentials.json in the settings directory |
| the app id and hash, for CI |
TG_API_ID and TG_API_HASH; they win over the keyring |
The directories are listed in where files go.
On a machine with no keyring (a container, often), the app goes into credentials.json beside the
settings, and tg says so once on stderr.
⚠
TG_CONFIG_DIR,TG_STATE_DIRandTG_CACHE_DIRmove the keyring entry too. With any of them set, the service name includes the settings directory. A login made without them is invisible with them, and the other way round. Set them always, or never.
⚠ On Linux the keyring is reached through
XDG_RUNTIME_DIR. cron, ssh and some MCP clients starttgwithout it, and every command then says the app credentials were not found "although it has logged in on this machine". Do not log in again: that adds another device and does not fix the environment. SetXDG_RUNTIME_DIR(app credentials not found after a login).