Telegram User API
A stateless FastAPI service that wraps Telethon to read Telegram messages as a real user account (not a bot). Credentials are never stored on the server — they are passed per-request via HTTP headers.
Table of Contents
Prerequisites
1 – Get a Telegram API ID & Hash
- Go to https://my.telegram.org/auth
- Log in with your phone number.
- Click API Development Tools.
- Fill in the form (any app name / short name) and click Create application.
- Note down
api_id(integer) andapi_hash(string).
Running the API
With Docker (recommended)
# Build
docker build -t teleapi .
# Run
docker run -p 8000:8000 teleapi
Locally (dev)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload
Interactive docs available at http://localhost:8000/docs
Authentication flow
Because the server is stateless, you need to perform the login once to get a session string, then pass it in every subsequent request.
Step 1 – Send OTP
POST /auth/send-code
Content-Type: application/json
{
"api_id": 12345678,
"api_hash": "abcdef1234567890abcdef1234567890",
"phone": "+34612345678"
}
Telegram will send a code to your phone / Telegram app.
Step 2 – Verify OTP and get session string
POST /auth/verify-code
Content-Type: application/json
{
"api_id": 12345678,
"api_hash": "abcdef1234567890abcdef1234567890",
"phone": "+34612345678",
"code": "12345",
"password": "optional-2fa-password"
}
Response:
{
"detail": "Authenticated successfully.",
"session_string": "1BVtsOKABu..."
}
Store the session_string securely (e.g. n8n Credential, environment variable, secrets manager). It does not expire unless you explicitly log out from Telegram.
API Reference
All endpoints (except /auth/*) require these headers:
| Header | Description |
|---|---|
X-Api-Id |
Telegram API ID (integer) |
X-Api-Hash |
Telegram API Hash (string) |
X-Session-String |
Session string from Step 2 |
| Method | Path | Description |
|---|---|---|
POST |
/auth/send-code |
Send OTP to phone |
POST |
/auth/verify-code |
Verify OTP → session string |
GET |
/me |
Current user info |
GET |
/dialogs |
List chats, groups, channels |
GET |
/messages?chat_id=… |
Get messages from a dialog |
GET |
/messages/{id}?chat_id=… |
Get a single message |
GET |
/search?query=… |
Global message search |
Full interactive docs: http://<host>:8000/docs
Configuring n8n
A – Store credentials
- In n8n go to Credentials → New Credential → Generic Credential Type (or Header Auth).
- Create three credentials (or use one Generic with a JSON field — see below):
| Name | Value |
|---|---|
TelegramApiId |
your api_id |
TelegramApiHash |
your api_hash |
TelegramSession |
your session_string |
Alternatively, store all three as n8n environment variables and reference them with
{{ $env.TELEGRAM_API_ID }}.
B – HTTP Request node setup
Use an HTTP Request node for every call.
Common settings
| Field | Value |
|---|---|
| Method | GET (or POST for auth) |
| URL | http://<your-host>:8000/<endpoint> |
| Authentication | None (credentials go in headers) |
| Send Headers | ✅ Enabled |
Headers (add all three)
| Header Name | Header Value |
|---|---|
X-Api-Id |
{{ $credentials.TelegramApiId }} or {{ $env.TELEGRAM_API_ID }} |
X-Api-Hash |
{{ $credentials.TelegramApiHash }} or {{ $env.TELEGRAM_API_HASH }} |
X-Session-String |
{{ $credentials.TelegramSession }} or {{ $env.TELEGRAM_SESSION }} |
C – Example workflows
List dialogs
HTTP Request
Method : GET
URL : http://localhost:8000/dialogs
Params : limit = 20
Headers : (see above)
Response will be an array — connect to a Split In Batches or Loop node to process each dialog.
Get messages from a group
HTTP Request
Method : GET
URL : http://localhost:8000/messages
Params :
chat_id = -1001234567890 ← from /dialogs response
limit = 50
search = invoice ← optional keyword filter
Headers : (see above)
Search globally
HTTP Request
Method : GET
URL : http://localhost:8000/search
Params : query = meeting notes
Headers : (see above)
D – Pagination
The /messages endpoint supports offset_id for cursor-based pagination.
- Make first request (no
offset_id). - Take the minimum
idfrom the response array. - Pass it as
offset_idin the next request.
In n8n, use an IF node to stop the loop when the response length is less than limit.
Security notes
- Never commit your
api_id,api_hash, orsession_stringto version control. - The session string grants full access to your Telegram account. Treat it like a password.
- Consider putting the API behind a VPN or firewall — it is not designed to be exposed to the public internet.
- The
/auth/*endpoints use an in-memory pending-auth store that is cleared after completion or server restart. They are only needed once to bootstrap your session string. - If the server restarts mid-OTP-flow you simply call
/auth/send-codeagain.