API overview¶
The API is versioned in the path (/v1/...), speaks JSON over HTTP and needs
no authentication. An OpenAPI 3.1 document is served at /openapi.json and
rendered as Swagger UI at /api (both can be turned
off with DISABLE_DOCS).
The same data is also available through a GraphQL API at
/graphql, where clients select only the fields they need and can combine
several requests into one.
Conventions¶
Channels are public usernames without @: 5–32 characters, starting with
a letter, then letters, digits or _ (^[a-zA-Z][a-zA-Z0-9_]{3,31}$).
Anything else is rejected with 422 before t.me is contacted.
Post IDs and positions are integers from 1 to 10 000 000.
Text in two forms. Wherever Telegram shows formatted text, the API returns
an object with string (plain text, line breaks as \n) and html (the
original markup):
Counters are strings exactly as Telegram formats them ("10.3M",
"14.2K", "10 281 023 subscribers"); the API does not reinterpret them.
Absent values are null. Optional fields are always present in responses
and set to null when Telegram does not provide them, so clients can rely on
a stable shape.
Dates are ISO-8601 strings with offset plus a Unix timestamp:
Response headers¶
| Header | When | Meaning |
|---|---|---|
X-App-Node |
always | Host name of the server that answered — handy behind a load balancer |
X-Process-Time |
always | Time spent in the application, e.g. 3 ms |
Cache-Control |
requests with a CF-RAY header (Cloudflare) |
public, max-age=10, stale-while-revalidate=10 (normal) or public, max-age=120, stale-while-revalidate=240 (aggressive); none for off |
X-RateLimit-Limit, X-RateLimit-Remaining |
rate limiting enabled | Per-IP budget for the current minute |
Retry-After |
429 responses |
Seconds to wait (always 60) |
CORS is open (Access-Control-Allow-Origin mirrors the request origin) unless
restricted with CORS_ALLOW_ORIGINS.
Freshness¶
Responses come from a cache that lives for a few seconds up to an hour,
depending on the endpoint and CACHE_MODE:
| Endpoint | off |
normal |
aggressive |
|---|---|---|---|
/v1/body, /v1/post, /v1/more |
always live | 10 s | 120 s |
/v1/preview, /v1/previews |
PREVIEW_CACHE_TTL (1 h) |
same | same |
/v1/feed |
see Feed |
Identical requests that arrive while t.me is being queried share that single upstream request.
Status codes¶
| Code | Meaning |
|---|---|
200 |
Success |
404 |
Channel or post does not exist (or is private) |
422 |
Invalid input — see Errors |
429 |
Rate limit exceeded |
502 |
t.me answered with a page the parser could not interpret |
503 |
t.me is unreachable / answered with an error, or the feature is disabled |
All error bodies are described in Errors.