Getting started
About Pabal
What Pabal is and how it's built, what works today and what doesn't yet.
What is Pabal?
Pabal (파발, 擺撥) was the relay courier system of Joseon-era Korea, in which riders changed horses at relay stations to rush urgent news onward. Pabal.me is a messenger named after it: a Telegram-compatible messenger that an organization or community runs on its own server.
- You run the server yourself. Accounts, conversations and photos are all stored on the operator's server and database (PostgreSQL). The server program is called HunsTelegram (Java 21).
- It speaks the same language as Telegram. Between the app and the server it uses MTProto 2.0 (layer 216), just like Telegram, and between bots and the server the same HTTP Bot API as Telegram. That's why apps, libraries and bots built for Telegram connect to Pabal by changing only the address.
- It is a separate world, not connected to Telegram. Pabal accounts exist only on the Pabal server, and you can't exchange messages with Telegram users.
Conversations with AI agents: once voice bots are on, bots answer messages and take calls too. You can ask the same bot something in writing on your computer, call it from your phone or Apple Watch, and anyone can build such a bot with @BotFather. It is still in the works; what works and where the data goes is collected in AI agents.
How it's built
About this diagram
- Three areas: on the left is what runs outside the server (apps, bot programs, browsers), in the middle are the server's two entrances, and on the right is the inside of the server. Bot programs run outside the server too, on the operator's or developer's own computer.
- There are only two entrances: the app connects directly to the MTProto port (8443) (MTProto encrypts on its own, so it needs no HTTPS), while the website and the Bot API come in over HTTPS (443).
- A bot connects in one of two ways: usually through the Bot API over HTTPS (solid line), or, if you prefer, over MTProto just like the app (blue dashed line). Either way it is the same bot account and the same message box.
- The red dashed line is the only arrow that points the other way: when a bot sets a webhook, the server sends new updates to the bot program's HTTPS address. Everything else is a request coming into the server from outside.
- There is one record: every change goes through the services and is kept in PostgreSQL's event store; only the original photos are stored as files. Messages sent from the app and messages sent by bots travel the same path, so pushes, chat lists and catching up after reconnecting work the same for everyone.
The picture above shows the paths messages take. A server with voice bots turned on has extra entry points for calls — the call relay (UDP 3478) and the Apple Watch's audio edge (WSS). Those paths are drawn in AI agents.
What works today, and what doesn't yet
| Feature | Status | Notes |
|---|---|---|
| Sign-up and sign-in (phone number + code) | Works | The operator chooses how codes are delivered: by SMS, by email or passed on by an administrator |
| One-to-one chats, real-time delivery, multiple devices | Works | A device that was off catches up on what it missed when it's switched back on |
| Editing and deleting messages | Works | Shows up on the other person's screen right away |
| Basic groups (create, add and remove members, rename) | Works | Members are added directly from the group info |
| Sending photos, profile photos | Works | Stored in one size, the original |
| Sending files (any type) | Works | The name and the type are kept. Files over 10 MB go through upload.saveBigFilePart; the default limit is 2 GB |
| Bots — @BotFather, HTTP Bot API, webhooks, MTProto bots | Works | Buttons, callbacks, command menu, photos, files, groups |
| Admin page, operational settings | Works | Open only on the server's 127.0.0.1 |
| Website in 10 languages, username and invite link pages | Works | The developer docs are in 10 languages too |
| One-to-one calls | Works | Calls between different networks depend on the server's relay (TURN) settings |
| Push notifications — Android | Works | Message notifications and ringing calls even while the app is closed. The operator has to set up Firebase (Server installation) |
| Notifications — macOS · Windows | Works | Shown as your computer's notifications while the app is running (no push) |
| Seeing and ending signed-in devices (Devices in settings) | Works — not yet checked in the real apps | A device signed in less than 24 hours ago cannot end other devices (the Android and desktop apps show no notice when that happens). Checked by the server tests; the end-to-end check with the real apps is still to come — Using the app — Keeping your account safe |
| Data export (desktop app) | Works — not yet checked in the real app | Chats, photos, files and account information. Up to three starts a day; a server restart means starting over. Telegram's waiting period, approval from another device and the record of exports are not there yet. Tested with the requests the desktop app sends, in its order; the end-to-end check with the real app is still to come |
| Changing your phone number | Off by default | When the operator turns it on, a code goes to the new number by SMS (only on servers with SMS set up) — Administration and settings — Sign-up and sign-in codes |
| Channels, supergroups | Not yet | May not display properly in the app |
| Video and voice messages | Not yet | You can send them as files, but they won't play inside the app |
| Albums (several items grouped together) | Not yet | If you send several at once they do arrive, but they're shown one by one instead of grouped |
Formatted text (bold, italic), parse_mode for bots | Not yet | Sent as plain text. Commands, mentions, links and hashtags are highlighted automatically |
| Group calls, secret chats | Not yet | |
| Two-step verification (cloud password) | Not yet | Rejected if you try to set it up |
| iPhone app | Coming soon | The first version (1.0) was submitted for App Store review (2026-09-23). Version 1.0 has no push notifications, so you receive messages only while the app is open. Version 1.1, with push, is in internal testing (TestFlight) |
| Joining a group through an invite link | Not yet | Links can be created, but opening one doesn't make you a member |
Inline mode (@bot query), payments, games | Not yet | |
| Voice bots (an AI answers when you call a bot) | Coming soon | Turns on only once the server, the legal documents and an app with the confirmation sheet are all in place. Off on pabal.me, being tested on a development server — Voice bots |
| Apple Watch app (voice-bot calls) | Coming soon | Internal testing (TestFlight) only. Call a voice bot from the watch without an iPhone — Using the app — Apple Watch |
| Keeping the conversation (a call's conversation as text in your own chat) | Coming soon | The confirmation sheet's wording is awaiting legal review — Using the app — Voice bots |
| Calls from bots (a bot you allowed calls you with an AI voice) | Off | Waiting for the legal review; no app build with the permission sheet yet either — Using the app — Letting a bot call you |
Relationship with Telegram
Pabal is a separate server that follows Telegram's published protocol. It is not affiliated with Telegram (the company), and it never connects to Telegram's servers.
- What's compatible: MTProto 2.0 (all four transports, the handshake, temporary key binding), the request and response formats of layer 216, and the HTTP Bot API's address format, requests, responses and error format. We confirmed this by connecting the official Telegram Desktop 6.2.6 without modifying it (changing only the server address and public key).
- What's different: accounts and data are separate for each server. User IDs, message IDs and file IDs only mean something within this server. Bot tokens you used on Telegram won't work; you need to get a new one from Pabal's @BotFather.
Link format
Links that the app and the server create start with https://pabal.me/. Opening one in a browser shows a small page that opens the app.
| Link | Meaning | Address opened in the app |
|---|---|---|
pabal.me/<username> | Opens a chat with a person or bot | tg://resolve?domain=<username> |
pabal.me/+<invite code> | Group invite link (the app opens, but joining through a link doesn't work yet) | tg://join?invite=<invite code> |
pabal.me/joinchat/<invite code> | Invite link in the older format (same meaning) | tg://join?invite=<invite code> |
A username is 5–32 characters of letters, digits and underscores, starting with a letter (bot usernames end in bot). Names that match paths the site itself uses, such as docs, admin and health, can't be opened as links.
Security model
- App ↔ server: encrypted with MTProto 2.0. The app is built with the server's RSA public key inside it, so no other server can pretend to be the Pabal server. Conversations are like Telegram's "cloud chats", so the server can read their contents (this is not end-to-end encryption). That's why the server must be run by someone you can trust.
- Bot ↔ server: the Bot API is exposed over HTTPS only. A bot token is the bot's password — if it leaks, replace it with
/revokeat @BotFather. The old token, and any connections made with it, are cut off immediately. - Server → webhook: the server only sends requests to webhooks that use HTTPS and have a public address. Internal addresses such as private networks, loopback and cloud metadata are refused. A bot can use
secret_tokento check that a request really came from the Pabal server. - Server → Android notifications: push notifications go through Google's Firebase Cloud Messaging (FCM). The server encrypts a notification's contents (the sender's name, a message preview) with a key only that phone has, so Google can't read them; it sees only delivery information such as the device token and the time sent. The operator can also leave the message text out of notifications altogether.
- Server → iPhone notifications: iPhone push notifications go through Apple's APNs. Just as on Android, the only visible text Apple sees is "You have a new notification"; the sender and the contents are encrypted with a key only that device has and are decrypted inside the phone. This starts with the app build that has push (1.1).
- Voice-bot calls (coming soon): unlike calls between people, calls with a bot are not end-to-end encrypted. Pabal's voice gateway decodes the audio and hands it to an AI model, and with the default engine the call audio goes to Google in the USA (Google Cloud
us-central1). What the operator can decide — running the server themselves, the bot owner's model key, stream mode, operator switches — is in AI agents — What you can decide. - Administration: the admin page is open only on the server itself (127.0.0.1), and you need a token to see any data. Operators get in through an SSH tunnel.
- Storage: auth keys are stored unencrypted in the database, because the server needs them for decryption. Guard the database and its backups as carefully as the server's RSA private key.
Glossary
| Term | Meaning |
|---|---|
| MTProto | The encryption protocol between app and server, designed by Telegram. Pabal uses version 2.0. |
| Layer | The version of the request and response formats exchanged on top of MTProto. Pabal uses 216. |
| Auth key | A 2048-bit secret the app creates together with the server when it first connects. Sign-ins are attached to this key. |
| DC | Telegram's data center number. In Pabal, a single server handles all of DCs 1–5. |
| Updates, pts | Changes such as new messages, edits and deletions. pts is a per-user sequence number of changes that lets a device that was disconnected know what it missed. |
| Push notification | Waking the phone to tell you about something while the app is closed or off the screen. Pabal sends them to the Android app through Google FCM and to the iPhone app through Apple APNs. |
| Peer | The other side of a conversation — a person, a bot or a group. |
| Bot token | A string of the form <bot ID>:<secret>. Put it in the Bot API address to prove you are the bot. |
| Webhook | Instead of the bot coming to fetch new updates, the server sends them to the bot's HTTPS address. |
| AI agent | A bot that answers messages and takes calls too. On Pabal, a bot with voice turned on (coming soon). |
| Voice bot | A bot that people can call. The call is answered by an AI voice model, not by the bot owner's code. |
| Voice gateway | The Pabal component (pabal-voice) that becomes one end of the call on the bot's behalf, decodes the audio and talks with the AI model. It is not the MTProto gateway the apps connect to. |
| Stream mode | A way of running a voice bot in which the bot developer's server receives the call audio directly instead of an AI model. |
| Keeping the conversation | If the caller chooses it, the call's conversation is kept as text after the call, only in the caller's own chat. It does not go to the bot or the bot owner. |