📖 Interactive API documentation Open Swagger UI →

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

  1. Prerequisites
  2. Running the API
  3. Authentication flow
  4. API Reference
  5. Configuring n8n
  6. Security notes

Prerequisites

1 – Get a Telegram API ID & Hash

  1. Go to https://my.telegram.org/auth
  2. Log in with your phone number.
  3. Click API Development Tools.
  4. Fill in the form (any app name / short name) and click Create application.
  5. Note down api_id (integer) and api_hash (string).

Running the API

# 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

  1. In n8n go to Credentials → New Credential → Generic Credential Type (or Header Auth).
  2. 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.

  1. Make first request (no offset_id).
  2. Take the minimum id from the response array.
  3. Pass it as offset_id in the next request.

In n8n, use an IF node to stop the loop when the response length is less than limit.


Security notes