Telegram api_id and api_hash: getting them, security and rules
api_id and api_hash identify your application to Telegram's MTProto API. You get them for free on my.telegram.org by signing in with your Telegram number and filling in the form under “API development tools”; each number can have only one api_id. The keys don't grant account access — login still takes a phone, a code and the 2FA password, producing a secret session string.
Updated:
What are api_id and api_hash?
api_id (a number) and api_hash (a string) tell Telegram's servers which application a request comes from. They are sent together with the phone number when logging in over MTProto, for example in auth.sendCode. They are not a user password: many accounts can log in through one api_id, each with its own code and session.
The Bot API doesn't need an api_id — a BotFather token is enough there. api_id is for integrations that act as a user account: full chat history, group member lists, scheduled messages and other capabilities bots don't get.
The Telegram API is free. But every app must follow the API Terms of Service, and Telegram can cut off API access for apps that don't.
How to get an api_id on my.telegram.org
Sign up in an official app
Telegram requires an account created through an official Telegram app. Use an active number you own — Telegram sends important developer notifications to it.
Log in to my.telegram.org
Open https://my.telegram.org, enter the number in international format (+1..., +998...) and type the confirmation code you receive.
Open “API development tools”
This section holds the form for creating an application.
Fill in the form
Enter the app title, short name and the remaining fields. Per the ToS, the title must not contain “Telegram” (unless preceded by “Unofficial”), and you can't use the official Telegram logo.
Store api_id and api_hash
The page shows your api_id, api_hash and MTProto server addresses. Keep the keys out of code: use TELEGRAM_API_ID and TELEGRAM_API_HASH environment variables or a secrets manager.
Connect in Socialift (optional)
In the dashboard, add api_id and api_hash under Keys (Kalitlar) → Telegram; they are stored encrypted and checked against Telegram. Then connect the account under Connections (Ulanishlar) → Telegram account: phone → code → 2FA password if enabled.
Telegram API Terms of Service: what matters
Key points from the official “Creating your Telegram Application” page and the API Terms of Service.
| Rule | What it says | In practice |
|---|---|---|
| Your own api_id (2.1) | Every app must obtain its own api_id. The sample api_id shipped with open-source code is limited server-side | Don't reuse someone else's api_id — the sample key causes API_ID_PUBLISHED_FLOOD for your users |
| User consent (1.4) | Acting on a user's behalf without their knowledge and consent is forbidden, as is tampering with read statuses (a “ghost mode”) | The account owner must know about and agree to every automated action |
| Spam and fake metrics | Using the API for flooding, spamming or faking channel subscriber and view counts leads to a permanent ban | Skip mass messaging, mass inviting and counter inflation |
| Observation | All accounts that log in through unofficial clients are automatically put under observation | Use the account moderately, like a real person would |
| Transparency (2.2–2.4) | Users must know the app uses the Telegram API; no “Telegram” in the title and no official logo | For a public app, say so in its description |
| Data and AI (1.5) | Using Telegram data to train or fine-tune AI and ML models is prohibited | Don't feed exported chats into model training |
| Breaches (4.1–4.2) | Telegram notifies the account responsible for the app; if issues aren't fixed within 10 days, API access is discontinued | Keep the my.telegram.org number active and watch for notices |
Login flow: phone → code → 2FA password
In a web app, login spans two HTTP requests. The phone_code_hash from step one is only valid inside the same intermediate session, so pass both to step two.
import os
from socialift import TelegramAccount
API_ID = int(os.environ["TELEGRAM_API_ID"])
API_HASH = os.environ["TELEGRAM_API_HASH"]
async def start_login(phone: str) -> dict:
async with TelegramAccount(api_id=API_ID, api_hash=API_HASH) as tg:
return await tg.send_code(phone) # phone_code_hash + intermediate session
async def finish_login(phone: str, code: str, sent: dict, password: str | None = None) -> str:
async with TelegramAccount(api_id=API_ID, api_hash=API_HASH,
session=sent["session"]) as tg:
result = await tg.sign_in(phone, code, phone_code_hash=sent["phone_code_hash"])
if result["two_factor_required"]:
result = await tg.sign_in_password(password)
return tg.export_session() # as sensitive as a password — encrypt itIf the account is signed in on another device, the code may arrive as a service message in the Telegram app; in some conditions SMS codes go to official apps only. With two-step verification on, Telegram returns SESSION_PASSWORD_NEEDED — the SDK reports that as two_factor_required: True rather than an error. The password is checked via the SRP protocol.
Telegram invalidates a login code as soon as it's sent or forwarded to another chat. Never ask users to send you the code in a Telegram message — only through your app's form.
Reconnecting with a stored session
import os
from socialift import TelegramAccount
async def get_account() -> TelegramAccount:
tg = TelegramAccount(api_id=int(os.environ["TELEGRAM_API_ID"]),
api_hash=os.environ["TELEGRAM_API_HASH"],
session=os.environ["TELEGRAM_SESSION"])
await tg.connect()
if not await tg.is_authorized():
await tg.disconnect()
raise RuntimeError("Session revoked — log in again")
return tgconnect() only opens the connection and doesn't check authorization, hence the separate is_authorized() call. If the user terminated the session under Devices, it returns False.
Storing the session string safely
The string from export_session() grants full account access — no code, password or 2FA needed.
- Store it encrypted at rest (for example with KMS or a dedicated encryption key), and keep the key away from the database.
- Never write the session to logs, error trackers or the browser.
- Don't use one session in two processes at once: parallel main connections for one authorization trigger AUTH_KEY_DUPLICATED, which invalidates the session and forces a new login.
- One session per account; don't copy a single string across servers.
- Close unused sessions with
log_out(); review and terminate unknown devices withsessions()andreset_session(). - Other sessions get a notification on every new login — tell the account owner in advance.
Ban and FLOOD_WAIT risk: responsible use
Telegram automatically observes accounts that log in through unofficial clients. Call a method more often than allowed and the server returns 420 FLOOD_WAIT_X: the action can't be repeated until X seconds pass. Login attempts are limited too — each phone number gets a capped number of attempts per day (Telegram gives 5 as an example and notes it may change).
Lowering the risk is straightforward: act at human speed, don't mass-message strangers or bulk-add them to groups, wait out FLOOD_WAIT and don't retry endlessly. The SDK converts FLOOD_WAIT into RateLimitError with the wait time in retry_after.
If you broke no rules but the account was banned after using the API, Telegram suggests emailing recover@telegram.org, explaining what you intend to do with the API. A human reads these emails, and auto-generated ones are detected and banned.
Handling FLOOD_WAIT
import asyncio
from socialift import RateLimitError
async def send_report(tg, text: str) -> None:
try:
await tg.send_message("@my_group", text)
except RateLimitError as exc: # Telegram: FLOOD_WAIT_X
if (exc.retry_after or 0) > 300:
raise # long wait — reschedule the job
await asyncio.sleep(exc.retry_after or 5)
await tg.send_message("@my_group", text)The SDK deliberately doesn't sleep through long FLOOD_WAITs for you. Moving long waits to a background job queue keeps the app responsive.
Frequently asked questions
Is getting an api_id and api_hash free?
Yes. Telegram offers its API free of charge, and creating keys on my.telegram.org costs nothing. The condition is compliance with the API Terms of Service.
How many api_ids can one phone number have?
Per the official docs, each number can currently have only one api_id. Any number of user accounts can log in through that one api_id, each with its own session.
Can I share my api_hash?
It's not advisable. The api_hash identifies your application: abuse through it counts against your app, and Telegram sends breach notices to the account responsible for the app. Keep the keys in a secrets manager.
Does a Telegram bot need an api_id?
Not for a Bot API bot — the BotFather token is enough. If you log a bot in over MTProto (auth.importBotAuthorization), api_id and api_hash are required there as well.
My account was banned after using the API. What now?
If you didn't break the rules, email recover@telegram.org, explain what you use the API for and ask for the ban to be lifted. Write the email yourself: auto-generated emails are detected and banned.
What if my session string is stolen?
Terminate the unknown session right away under Devices in the Telegram app, or with sessions() and reset_session() in the SDK. Then store the new session encrypted only and find where the leak came from.