A Telethon session is a key, not a Telegram app
I have watched someone double-click a .session file and wait for Telegram to open. Nothing happens that looks like an app, so they decide the file is broken. The file is doing what it was built to do: sit there as a key until a Python process asks Telegram a question.
A Telethon session is a key, not a Telegram app. It does not have a chat list you can scroll with a mouse. It does not install. It authorizes a library to speak MTProto as a user. If you wanted a window, you wanted TData, or you wanted a login code on a client you already trust. If you wanted code to call get_me() and get a user object back, this is the object.
I wrote a shorter version of the format choice elsewhere. This is the session, opened up.
What is actually in the file
The default Telethon session is a SQLite database, usually named something like anon.session or work.session. Telethon creates it when you construct TelegramClient('anon') and complete a login. After that, the file is the login.
Inside, the useful bits are dull. Which data center to dial. Which port. The authorization key that encrypts the traffic so Telegram believes this process is already that user. A cache of entities the client has seen, because Telegram will not keep resending access_hash values it thinks you already have. That cache is why a session file can grow past "a tiny key" without being a chat export. It is still not your message history sitting in a folder for you to browse.
A dead file fails in boring ways. The auth key is unregistered. The server rejects the session. You get a two-step verification prompt and nobody gave you the cloud password. Until that password is in your hands, the file is a paperweight. Do not open the SQLite file and go hunting for messages. The live test is a connection, not a treasure hunt.
StringSession is the same key, worse at sitting still
Telethon can take that authorization data and encode it as a long string. StringSession holds the session in memory and can save() it to text. You paste the string into another process, wrap it in StringSession(...), and the new process is the same login without carrying a .session file across a disk.
That is convenient on a machine that throws its filesystem away. It is also easier to leak. Telethon's own docs say the quiet part: anyone with the string can log in as you. Same true of the .session file. The string just travels better. I keep strings in a secret store, not in the repo. You can export a SQLite session to a string with StringSession.save(client.session). That means one live login can become two keys. Count the copies.
Telethon and Pyrogram are not the same drawer
Both libraries speak MTProto. Both will write something called a session. They are not interchangeable formats.
Telethon's on-disk session is a SQLite layout Telethon knows how to read. Pyrogram has its own file storage and its own session string. You cannot feed a Telethon .session to a Pyrogram Client and expect a polite handshake. You cannot paste a Pyrogram session string into StringSession and call it a day. People still try. Then they decide the account is dead.
I pick Telethon when I already have Telethon code. I pick Pyrogram when the project is already Pyrogram. I do not pick one because a listing said "session."
A bot token is a third object: an HTTP secret for a bot, used with Bot API. It is not a user session. If your test needs a user to press Start, you want a user session. If your test needs the bot to answer, you want the token. I have seen those two files dropped in the same zip.
Telethon .session |
StringSession | TData | Bot token | |
|---|---|---|---|---|
| What it is | SQLite file with an auth key and a cache | The same key, encoded as text | Telegram Desktop's working directory | An HTTP secret for a bot |
| What opens it | Telethon | Telethon | Telegram Desktop | Bot API, any HTTP client |
| Looks like an app? | No | No | Yes, on a desktop | No |
| Live test | Connect and get_me() |
Connect and get_me() |
Settings shows the number | getMe on Bot API |
| Treat it as | A password | A password that is easier to paste | A password in a folder | A password |
TData is for Desktop. A session is for code. If you want a chat list on a laptop, go get TData or a login code.
get_me() is the live test
I do not trust a file because it has the right extension. I do not trust a string because it is long. I connect once, with the api_id and api_hash for my application, and I ask who I am.
get_me() returns a user object if the key is accepted. You want the user id and the phone to match the account you thought you bought. A vanity username can change. The id does not. A mismatch on the handle is a support question. A mismatch on the phone is a different person.
If the client cannot connect, you do not have a live session. If it connects and immediately wants a cloud password you were not given, you are missing the second lock. If you get AuthKeyUnregistered, the key in the file is no longer registered with Telegram. That is a souvenir.
get_me() does not prove the account is "aged." It proves this key can still speak. Then I set or change two-step verification. The cloud password is a lock on new logins. It does not vacuum up session files that already left the building. If a cloud password arrived with the session, I change it. I do not reuse the password from my personal Telegram.
Treat the file like a password, because it is one
Anyone who has the .session or the string is logged in as that user, from wherever they run the client. That is the whole security model, said without makeup.
So I do not paste it into a group "just to check." I do not commit it. Two machines with two copies is two keys. If I revoke the wrong row in the device list, the .session is now AuthKeyUnregistered and the script is done.
I use this shape of login for dull, legitimate work. A test harness that needs a real user to talk to a bot. A support script that pulls a chat a human already asked it to pull. A staging inbox for a Mini App. I do not use it as a mailing system. Buying the key does not buy a waiver.
After the first get_me(), I stop poking. I put the file where the process can read it and I treat every extra copy as a hole.
Code, not a window
Why the file should come from a format picker
A Telethon essay that never names a shop is homework for PyPI. This one is here because we sell the key as a delivery option.
On Telegram accounts you pick Session (Telethon) the same way someone else picks TData or a live login code. Same owned inventory. Same country and age band. The file lands when the wallet is debited, on a signed, expiring link. If get_me() fails, it is a replacement, not a debate about SQLite.
I still run get_me() myself. I still change the cloud password. I still treat every extra copy as a hole. The catalog does not do that part. It just stops you from buying a zip labelled "session" that is a screenshot.
A telegram session is that key. Telethon is just the Python that asks Telegram a question. If you searched telethon telegram, you still bought a file, not an app.
FAQ
Can I convert a Telethon .session into a Pyrogram session string?
Not with a blessing from either project. They store the same kind of secret in different layouts. If your code is Pyrogram, get a Pyrogram session.
If I revoke other sessions in Settings, does my .session die?
It dies if you revoke that session. The device list is a list of keys. Tap the wrong row and the next get_me() fails.
What does AuthKeyUnregistered actually mean?
The authorization key in your file is no longer registered. The file can still sit on disk. It is no longer a login. Replace it. Do not edit the SQLite by hand.
The file is 40KB. Did I get a dump of chats?
Probably not. Telethon caches entities. A larger file is metadata for the library, not a readable archive of chats.
Can I keep the same session on two servers?
You can copy the file. Both processes then share one key and step on each other. If I need two places, I prefer two deliberate logins. A copied .session is not a cluster strategy.
Is a session safer than TData because it is smaller?
No. Both are keys. A session is easier to copy and easier to run from anywhere with Python. Safety is what you do after get_me(), not the file extension.
Is the Telethon file a different inventory than TData?
Same accounts. Different delivery. Pick Session at checkout if your code is Telethon. Pick TData if you sit in Desktop.