Skip to main content

TGConvertor

TGConvertor — Telegram session converter

CI Web panel Latest release Python 3.10–3.14 License: MIT

Convert Telegram authorizations between Telethon, Pyrogram / Kurigram, GramJS, and Telegram Desktop tdata. File reads and conversions are offline. Telegram clients are optional and only needed for explicit network operations.

Open web converter Install from PyPI

Quick start · Python API · Releases · Discussions · Report a bug

Try the browser workspace — free, no installation. Convert files, strings and tdata ZIPs locally on your device, or click Try a demo. Sessions are not uploaded and Telegram is not contacted. Web panel details and self-hosting.

Use it your way Start here
Browser Open the web converter. Russian/English UI, file and string conversion, tdata ZIPs, installable PWA. After Available offline, reopening works without internet.
Command line Install from PyPI, then run tgconvertor convert. Supports stdin and automation.
Python Call convert() or SessionManager from your own application.

Session files and strings grant access to an account. Keep them private, use only accounts you own or are authorized to manage, and never commit them or paste them into issue reports.

Installation

Requires Python 3.10+. CI tests Python 3.10–3.14, with additional Windows and macOS checks.

python -m pip install --upgrade tgconvertor

The base package converts Telethon, GramJS and Pyrogram/Kurigram files and strings without either client installed. Install extras only for the features you need:

python -m pip install --upgrade 'tgconvertor[telethon]'  # Telethon client / network validation
python -m pip install --upgrade 'tgconvertor[kurigram]'  # Kurigram client
python -m pip install --upgrade 'tgconvertor[pyrogram]'  # Legacy Pyrogram 2 client
python -m pip install --upgrade 'tgconvertor[tdata]'     # tdata via OpenTele2 (no PyQt5)

Telethon and Kurigram can be installed together: pip install 'tgconvertor[telethon,kurigram,tdata]'. Do not install Pyrogram and Kurigram together: both provide the pyrogram import namespace. Use separate virtual environments when testing both.

Quick start

# Pyrogram or Kurigram file → Telethon file
# Choose a new output path; existing files/directories are never overwritten.
tgconvertor convert original.session -f pyrogram -t telethon -o converted.session

# File → string (only the string is written to stdout)
tgconvertor convert original.session -f pyrogram -t telethon > converted-string.txt

# String → file, without putting the authorization in shell history
cat private-session-string.txt | tgconvertor convert - -f pyrogram -t telethon -o converted.session

# Inspect local metadata without connecting to Telegram or displaying the key
tgconvertor info original.session -f pyrogram

tgconvertor --help
tgconvertor convert --help
tgconvertor list-formats
python -m TGConvertor --version

--output string also selects stdout. Omitting --output never writes over the input. Diagnostics and file-save messages go to stderr. --input-type file or --input-type string overrides automatic detection, including for unusual filenames.

Telethon / GramJS → Pyrogram / Kurigram

Telethon strings/SQLite files and GramJS strings do not reliably store the owner's user ID. A cached contact is not the owner. Supply the real ID explicitly:

tgconvertor convert telethon.session -f telethon -t pyrogram \
  --user-id 123456789 -o kurigram.session --backend kurigram

--backend pyrogram writes Pyrogram 2's SQLite schema. --backend kurigram writes Kurigram's schema. The default auto selects the installed client; with neither installed, it writes Pyrogram 2's schema. Both use the same current string-session format. Reading either schema never requires the corresponding client.

Pyrogram output preserves a source Pyrogram API ID. Sources without an API ID use the selected API configuration (Desktop compatibility preset by default). For a custom application, set both TGCONVERTOR_API_ID and TGCONVERTOR_API_HASH in your environment, or pass APIData through the Python API. Obtain your application credentials from my.telegram.org.

GramJS (JavaScript / TypeScript)

Convert the version 1 StringSession used by GramJS 2. No Node.js dependency is needed for Python conversion.

# Telethon → GramJS string; no owner ID is needed
tgconvertor convert telethon.session -f telethon -t gramjs > gramjs.txt

# GramJS string saved in a UTF-8 file → Kurigram SQLite
tgconvertor convert gramjs.txt -f gramjs -t pyrogram --user-id 123456789 \
  --backend kurigram -o kurigram.session

# GramJS string from stdin → Telethon SQLite
cat gramjs.txt | tgconvertor convert - -f gramjs -t telethon -o telethon.session

In JavaScript, read the exported text and pass it to the native client:

import fs from 'node:fs';
import { TelegramClient } from 'telegram';
import { StringSession } from 'telegram/sessions/index.js';

const session = new StringSession(fs.readFileSync('gramjs.txt', 'utf8').trim());
const client = new TelegramClient(session, apiId, apiHash, {});
await client.connect();
try {
  const me = await client.getMe();
} finally {
  await client.disconnect();
}

gramjs file output is a private UTF-8 .txt containing a StringSession, not a SQLite database. GramJS StoreSession folders / browser localStorage are not supported: copy the connected session’s DC, address, port and auth key into a new StringSession, then call its save() method. GramJS strings retain DC, authorization key, address and port, but have no owner ID, bot flag, API ID or takeout ID. Supply user_id for Pyrogram or tdata output. IPv4 and IPv6 endpoints convert in all directions. ASCII hostnames are preserved for GramJS output; Telethon and Pyrogram endpoint codecs require IP addresses and conversion never resolves DNS. GramJS uses signed 16-bit ports (1–32767); its address field must fit 4–100 bytes for reliable native loading.

Telegram Desktop tdata

Install the tdata extra. Pass the actual tdata directory, not its parent:

# tdata already contains the owner ID
tgconvertor convert ./desktop/tdata -f tdata -t pyrogram -o account.session

# Writes directly into ./export/tdata, without adding another tdata level
tgconvertor convert account.session -f pyrogram -t tdata -o ./export/tdata

# Choose another account from a multi-account directory (zero-based loaded-account index)
tgconvertor convert ./desktop/tdata -f tdata -t telethon --account-index 1 -o second.session

The main account is selected by default. For directories protected by a local passcode, set TGCONVERTOR_TDATA_PASSCODE for input and TGCONVERTOR_OUTPUT_PASSCODE for output. These are local Desktop passcodes, not your Telegram two-step verification password. The current adapter supports ASCII passcodes.

Export to tdata requires the real user ID and a production user account; bots and Telegram test-server sessions are rejected. Each export uses a fresh local encryption key. Converting a Telethon source to tdata also requires --user-id.

Python API

One-call conversion

import asyncio
from TGConvertor import convert


async def main():
    output = await convert("original.session", "pyrogram", "telethon", "converted.session")
    print(f"Saved to {output}")


asyncio.run(main())

convert(source, from_format, to_format, output=None, *, user_id=None, api=..., input_type="auto", backend="auto", passcode="", output_passcode="", account_index=None) returns a Path for file/directory output or a session string when output is omitted. tdata always requires an output path. This function never connects to Telegram.

Work with a session

import asyncio
from TGConvertor import SessionManager


async def main():
    session = await SessionManager.from_pyrogram_file("original.session")
    await session.to_telethon_file("converted.session")
    await session.to_pyrogram_file("kurigram.session", backend="kurigram")
    await session.to_tdata_folder("export/tdata")  # requires the tdata extra


asyncio.run(main())
Source Loader
Telethon SQLite await SessionManager.from_telethon_file(path, api=...)
Telethon string SessionManager.from_telethon_string(value, api=...)
Pyrogram / Kurigram SQLite await SessionManager.from_pyrogram_file(path, api=...)
Pyrogram / Kurigram string SessionManager.from_pyrogram_string(value, api=...)
GramJS UTF-8 text await SessionManager.from_gramjs_file(path, api=...)
GramJS string SessionManager.from_gramjs_string(value, api=...)
Desktop tdata SessionManager.from_tdata_folder(path, passcode="", account_index=None, api=...)

String exports are synchronous: session.to_telethon_string() , session.to_pyrogram_string() and session.to_gramjs_string(). File exports are asynchronous, including await session.to_gramjs_file("gramjs.txt"). The tdata loader is synchronous; use await asyncio.to_thread(SessionManager.from_tdata_folder, path) in an application where blocking the event loop matters.

Explicit network validation and owner lookup

Install the telethon extra, then use your own API credentials:

import asyncio
import os
from TGConvertor import APIData, SessionManager


async def main():
    api = APIData(
        api_id=int(os.environ["TGCONVERTOR_API_ID"]),
        api_hash=os.environ["TGCONVERTOR_API_HASH"],
    )
    session = await SessionManager.from_telethon_file("original.session", api=api)
    await session.get_user_id()  # explicit network request; caches the actual owner and bot flag
    await session.to_pyrogram_file("converted.session")


asyncio.run(main())

await session.validate() contacts Telegram and returns whether it can obtain the account. Connection/RPC errors propagate to the caller. Local TeleSession.validate(path) and PyroSession.validate(path) only check whether the local authorization can be parsed; they cannot prove it remains authorized on Telegram.

session.telethon_client() and session.pyrogram_client() create in-memory clients. Create and use them inside your asynchronous application, then disconnect them. async with session as client: connects a Telethon client and disconnects it on exit, including on errors. Conversion itself neither logs in nor creates a new Telegram authorization.

Compatibility presets remain available through API.TelegramDesktop, API.TelegramAndroid, API.TelegramIOS, and API.TelegramMacOS, or CLI --api desktop|android|ios|macos. They are fixed compatibility identities, not a promise to track the latest official client version.

Supported formats and limits

Format Files Strings Notes
Telethon 1.x SQLite authorization schema v7/v8 Version 1, IPv4 and IPv6 Stored endpoint, port and file takeout ID are retained
Pyrogram 2 SQLite v3 (also reads the legacy schema without API ID) Current format and legacy 32/64-bit user-ID formats API ID, owner, bot flag and test mode are retained where representable
Kurigram 2 SQLite v7 Same session strings as Pyrogram Select backend="kurigram" for Kurigram file output
GramJS 2 UTF-8 StringSession text Version 1, IPv4/IPv6/ASCII hostname Distinct codec; no native Node.js dependency required
Desktop tdata Directory via OpenTele2 — One selected account; local ASCII passcodes supported

The package converts authorization data, not a complete client backup. Entity/peer caches, usernames, update states, temporary keys, media-DC keys, and Desktop settings are not copied. Telethon strings cannot carry user IDs, bot flags, API IDs or takeout IDs; Pyrogram strings cannot carry custom server addresses. A conversion through those strings cannot retain the missing fields. Telethon 2's experimental session format is not supported.

Reading uses read-only SQLite connections and never migrates the input. Close the original client before copying or converting its database. Writers reject existing destinations and create private files (0600) and tdata directories (0700) on POSIX. SQLite output is published only after it is complete. Filesystem permissions on Windows follow the platform's ACLs.

Malformed/incomplete authorizations raise ValidationError; missing optional dependencies raise MissingDependencyError; missing input and existing output paths raise FileNotFoundError and FileExistsError. CLI failures return a non-zero exit code without a traceback or printing the supplied session string.

Development and releases

See CONTRIBUTING.md for test commands, optional live verification, the CI matrix, and PyPI publishing setup. See CHANGELOG.md for migration from 0.1.x.

Use Discussions for questions and examples, or issue forms for reproducible bugs and feature requests. Read the security policy before reporting a vulnerability. Contributions are welcome; include a synthetic reproduction and the checks relevant to your change.

The offline suite uses synthetic authorizations and blocks outgoing network connections, including inside CLI subprocesses. It tests all 81 input/output representation combinations through convert(), SessionManager, the CLI, and the installed console command. CI verifies the base install, each extra independently, combined clients/tdata, lint/format checks, minimum CLI dependencies, package metadata, and installation of the built wheel. The publish workflow runs the same checks on the exact tagged commit before publishing the tested distributions. Native GramJS 2.26.22 interoperability and browser/PWA tests are release gates. Live verification is a separate opt-in local test.

Donate

USDT (BEP20): 0x34412717daaf427efa39c8508db4f62cce0d6d48

License

MIT.

Metadata

Release files for tgconvertor 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tgconvertor 0.3.0
File Size Uploaded
tgconvertor-0.3.0.tar.gz 58.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tgconvertor 0.3.0
File Interpreter ABI Platform
tgconvertor-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 86.3 kB

Release files / tgconvertor-0.3.0.tar.gz

Download URL tgconvertor-0.3.0.tar.gz
Size 58.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7b9605d55a496bc00e2c5fc0215a47a00932eb2be87ce7c0e763fa43488a00e8
BLAKE2b-256 checksum
How to use checksums
232245b85d294463af8c1e99f5ef604f4f8650ddeed24ce0282bfb5761730656
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / tgconvertor-0.3.0-py3-none-any.whl

Download URL tgconvertor-0.3.0-py3-none-any.whl
Size 27.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2f03f6231b2b0d4f794e1fad06ef54a47f13d4222c57a91df35e3e6c2fdf1fb6
BLAKE2b-256 checksum
How to use checksums
9ea444a5d81710e18914d4c3c99df7b28aad37aaa7f618557d95bebfa72f8875
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page