Ferogram API Layer 225
Raw Telegram MTProto API reference generated from Telegram's TL schema for Layer 225. Use the search box above or browse by section.
What is ferogram?
ferogram is a modern Telegram MTProto library written in Rust, built for speed, reliability, and full access to Telegram's protocol.
ferogram-py is the Python wrapper for ferogram. It lets you build Telegram bots and userbots using a clean high-level API, while still giving you direct access to raw TL methods whenever needed.
Index
- Methods (full list)
- Types (full list)
- Constructors (full list)
- TL definition
- Core types
- Full example
TL definition
Every method and constructor page shows a block like this at the top:
---functions--- users.getUsers#0d91a548 id:Vector<InputUser> = Vector<User>
This isn't Python code. It's Telegram's TL schema format. It gives a quick overview of the parameters and the returned result type.
In most cases, you only need to look at the parameter names and their types.
Methods
772 methods across Layer 225. Browse the full list.
Methods are used to make requests to Telegram's API.
You can call them using await app.invoke(...),
await app(raw.functions...),
or through the raw proxy shorthand.
Only methods can be executed. Telegram will then return a result, such as users, chats, messages, dialogs, or updates.
Types
594 abstract types. See the full list.
Types are abstract Telegram objects returned by the API. A single type can have multiple constructors.
For example, User can be returned as
User or UserEmpty.
You can check the returned constructor using
isinstance(result, Constructor).
When a method expects a Telegram type as a parameter, you usually create it using one of its constructors.
Constructors
1573 constructors. See the full list.
Constructors are concrete Telegram objects used throughout the API.
They are used to create request parameters, and are also the actual objects returned by Telegram.
6 ways to call a raw method
# Recommended: call the client directly with a typed TL object
from ferogram import Client, raw
app = Client("my_session", api_id=12345, api_hash="...")
result = await app(raw.functions.messages.GetHistory(peer=..., limit=100))# Explicit invoke() - identical to way 1, just more descriptive
from ferogram import Client, raw
app = Client("my_session", api_id=12345, api_hash="...")
result = await app.invoke(raw.functions.messages.GetHistory(peer=..., limit=100))# Namespace import - keeps the call site short, good for repeated use
from ferogram import Client
from ferogram.raw.functions.messages import GetHistory
app = Client("my_session", api_id=12345, api_hash="...")
result = await app(GetHistory(peer=..., limit=100))# Raw proxy - peer strings auto-resolved, primitives get safe defaults
# Add raw only when a field takes a TL object (e.g. InputMedia)
from ferogram import Client
app = Client("my_session", api_id=12345, api_hash="...")
result = await app.raw.messages.GetHistory(peer="@username", limit=5)# Inside an update handler - use client, not app
from ferogram import Client, filters, raw
app = Client("my_session", api_id=12345, api_hash="...")
@app.on_message(filters.text)
async def handler(client, message):
result = await client(raw.functions.messages.GetHistory(
peer=message.chat_id, limit=10
))
print(result)# Dict invoke - no generated types needed, plain Python dicts
# "_" key is the TL name in camelCase. Used internally by the proxy layer.
from ferogram import Client
app = Client("my_session", api_id=12345, api_hash="...")
result = await app.invoke({
"_": "messages.getHistory",
"peer": {"_": "inputPeerSelf"},
"limit": 10,
"offset_id": 0,
"offset_date": 0,
"add_offset": 0,
"max_id": 0,
"min_id": 0,
"hash": 0,
})Which way should I use?
| Way | Import needed | Peer strings | Type safety | Verdict | Use when | Avoid when |
|---|---|---|---|---|---|---|
1. Callableawait app(...) |
Client, raw |
✗ manual | ✓ full | ✓ recommended | Default choice for scripts, bots, userbots. IDE autocomplete works. Errors are caught at construction time. | Nothing. This is the safe default. |
2. invoke()await app.invoke(...) |
Client, raw |
✗ manual | ✓ full | ▶ situational | When you want to be explicit that a network call is happening, or when passing the method object around before invoking. | Everyday use. Way 1 is shorter and identical. |
3. ns importfrom ferogram.raw... |
Client + specific class |
✗ manual | ✓ full | ▶ situational | When you call the same method many times in one file and want to avoid repeating raw.functions.messages.. |
Scripts that call many different methods. The import block grows fast. |
4. raw proxyawait app.raw.ns.Method(...) |
Client (+ raw if TL objects needed) |
✓ auto | △ partial | ▶ situational | Quick scripts and exploration. Passing "@username" or "me" directly without resolving peers manually. Required primitives auto-fill to safe defaults. |
Production bots. Missing required TL-object fields silently get empty defaults, which can cause unexpected Telegram errors. |
5. handler@app.on_message |
Client, filters, raw |
✗ manual | ✓ full | ✓ recommended | All event-driven code. Use client (the handler argument), not the outer app, so the correct session context is used. |
Never call await app(...) inside a handler. Use await client(...). |
6. dictawait app.invoke({"_": ...}) |
Client only |
✗ manual | ✗ none | △ advanced | Dynamic dispatch. Use when the method name or fields are only known at runtime. Building generic tools or proxies on top of ferogram. No generated types required. | Normal bot or userbot code. No autocomplete, no type checking, typos in "_" fail at runtime only. |
Rule of thumb: use way 1 by default. Switch to way 4 (proxy) for quick scripts where peer strings save time. Use way 5 in all handlers. Reach for way 6 only when the method name is dynamic.
Core types
The primitive types everything else is built from:
| int | 32-bit signed integer. Check bit length with a.bit_length(). |
| long | 64-bit signed integer. |
| int128 | 128-bit integer. Pass as a Python int with at most 128 bits. |
| int256 | 256-bit integer. Pass as a Python int with at most 256 bits. |
| double | 64-bit float, such as 123.456. |
| string | Valid UTF-8 string. Python strings work as-is, no extra encoding needed. |
| bytes | Arbitrary binary data, e.g. b'hello'. |
| bool / true | True or False. true flag fields are not sent. Any truthy value enables the flag; use True or omit entirely. |
| date | Unix timestamp stored as int. You can also pass a datetime or date object. The library uses UTC+0. |
| Vector<T> | A Python list of T. For example, a valid value for Vector<int> is [1, 2, 3]. |
Full example
Every method page includes a code sample. The syntax is correct, but placeholder values
('username', dummy IDs, empty TL objects) won't do anything useful until you swap them
for real data. They're there so you can see the call shape at a glance.
For real working examples, check the examples folder on GitHub. To see what high-level APIs are already covered, FEATURES.md is the best place to look since friendly high-level docs are not available yet.