Self-hosted service
xtrime-ru/TelegramApiServer avatar
xtrime-ru/TelegramApiServer

TelegramApiServer puts the MTProto API behind plain HTTP requests

Fast, simple, async php telegram api server: MadelineProto + Amp HTTP Server

650 stars153 forksPHPMIT

At a glance

What is it?
TelegramApiServer is an asynchronous PHP server that exposes the Telegram API, bot and user, over GET and POST requests, on top of MadelineProto and the Amp HTTP server. It is quick to run with Docker compose, and the README is unusually blunt about the two ways it can hurt you: a new account gets banned, and a session exposed to the internet is a lost account.
Who is it for?
Adopt TelegramApiServer when you want to script or service a Telegram account over ordinary HTTP, with sessions you manage yourself and the full MadelineProto method set available. Do not expose it to the internet as shipped, and do not use it with an account you cannot afford to lose, because the README warns that new accounts get banned and that a leaked session is a lost account.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An HTTP shell around MadelineProto

The project describes itself as a fast, simple, async PHP Telegram API server built on MadelineProto and the Amp HTTP server, and the design is easier to understand once you split it into two layers. MadelineProto is the MTProto client that knows how to speak to Telegram. Amp is the HTTP server that exposes an interface to it. TelegramApiServer sits between them and turns an HTTP request into a method call.

The feature list says the same thing in a different order. There is a fast async Amp HTTP server, full access to the Telegram API for both bots and users, multiple sessions, media streaming so you can view files in a browser, media upload, and websocket endpoints for events and logs. The last item is the one with the interesting engineering behind it, because MadelineProto's settings are tuned to reduce memory consumption.

That last point matters when you run several sessions in one container, and the README supports that: if you need multiple sessions you create a `docker-compose.override.yml`, add additional containers there, and give each a unique port and session name in its `command`.

The project is written in PHP, licensed under MIT, and the homepage is tg.i-c-a.su, which hosts an online demo of history retrieval and media download. The author also points at a content aggregator and a separate project that turns Telegram channels into RSS. The recent tags are v2.7.2 from 2026-06-19, v2.7.1 from 2026-06-06 and v2.7.0 from 2025-07-13, and the last push was on 2026-10-13.

Four commands and a phone number

Installation is the part most people will judge the project by, and it is short.

shell
git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer
cd TelegramApiServer
cp .env.docker.example .env.docker
docker compose pull

Then you get credentials. Get app_id and app_hash at my.telegram.org, and the README notes that only one app_id is needed for any amount of users and bots. Fill app_id and app_hash in `.env.docker`, then start the server in the container:

shell
    1. Start container interactively: `docker compose run --rm api`  

After the prompt, fill your phone number, or your bot hash, and you will receive a Telegram code to type in. The README adds a diagnostic that is worth remembering: if you are not receiving the code, your server IP or hosting may be blocked by Telegram, and the advice is to try another server or change server IP. If you have two factor authentication enabled, you enter the two factor password as well.

Then you wait ten to thirty seconds for the session to start, and the logs tell you it worked:

text
   TelegramApiServer ready. 
   Number of sessions: 1.

You exit with Ctrl + C and start the container properly in the background with `docker compose up -d`.

There is a caution in the README that belongs in the middle of this sequence rather than at the end of the article: please only use old and valid accounts, because all new accounts will be banned by Telegram. The linked MadelineProto documentation explains how to get permission to use the Telegram API at all, and a project like this exists because that permission is not granted automatically.

The URL scheme and the method list

Once it is running, the API is addressed by URL. The pattern is `http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val%`, so the class is optional, the session is optional, and the method is addressed by name.

Every method MadelineProto supports is available, and the README links the full method list. When a method lives inside a class, such as messages or contacts, a dot separates the class from the method. The examples make the shape obvious:

code
* get_info about channel/user: `http://127.0.0.1:9503/api/getInfo/?id=@xtrime`
  curl --user username:password "http://127.0.0.1:9503/api/getSelf"
* repost: `http://127.0.0.1:9503/api/messages.forwardMessages/?from_peer=@xtrime&to_peer=@xtrime&id=1234`
* get messages from channel/user: `http://127.0.0.1:9503/api/messages.getHistory/?peer=@breakingmash&limit=10`
* get messages with text in HTML: `http://127.0.0.1:9503/api/getHistoryHtml/?peer=@breakingmash&limit=10`
* search: `http://127.0.0.1:9503/api/searchGlobal/?q=Hello%20World&limit=10`
* sendMessage: `http://127.0.0.1:9503/api/messages.sendMessage/?peer=@xtrime&message=Hello!`
* copy message from one channel to another (not repost): `http://127.0.0.1:9503/api/copyMessages/?from_peer=@xtrime&to_peer=@xtrime&id[0]=1`

Reading the list tells you what the server is for. There is channel and user information, information about the current account, a repost through `messages.forwardMessages`, history from a channel, the same history rendered as HTML, a global search, a plain text send, and a copy between chats that is explicitly not a repost. The last one is the interesting entry, because copying into a channel without the forward attribution is exactly the operation a channel owner wants and Telegram's own client does not offer.

Both regular and application/json POST bodies are supported, and the README recommends using `http_build_query` when you use GET requests.

Updates arrive three ways, and files upload last

Telegram is an event driven platform, the README explains, so every time your account receives a message you immediately get an update. There are three ways of getting them out of the server.

The first is the websocket endpoint, with an example file in the repository at `examples/websocket-events.php`. The second is long polling, by sending a request to the getUpdates endpoint:

code
`curl "127.0.0.1:9503/api/getUpdates?limit=3&offset=0&timeout=10.0" -g`  

The third is a webhook, where you redirect all updates to your own endpoint, just like the bot API does:

code
`curl "127.0.0.1:9503/api/setWebhook?url=http%3A%2F%2Fexample.com%2Fsome_webhook" -g `  

The example uses a urlencoded URL in the query string, which is worth copying exactly.

Uploading media has one rule that will bite you if you miss it. When passing files in POST forms, if the name of the field is `file`, it must always come last in the field list, and all fields after `file` will be ignored. The README notes that this limit does not apply to file fields named in another way, such as thumbnail fields. The stream upload from a client looks like this:

code
    curl --location --request POST 'http://127.0.0.1:9503/api/sendDocument' -g \
    -F peer=me \
    -F caption=key \
    -F [email protected]

The custom sendDocument, sendVideo and similar methods can also take a document, video, audio or voice by URL, by local path, or as a stream, which is what makes the streaming feature work in the browser.

The security model is a whitelist and a password

The README's security section is short and the warnings are severe, which is appropriate because what this server holds is a logged in Telegram session.

By default the settings allow access to the API only from localhost or 127.0.0.1. Two settings change that. `IP_WHITELIST` allows specific IPs to make requests without a password, and `PASSWORDS` protects the API with basic auth, where a request with the correct username and password overrides the whitelist, and where specifying a password means the whitelist is ignored. The README shows both ways of authenticating:

shell
  curl --user username:password "http://127.0.0.1:9503/api/getSelf"
  curl "http://username:[email protected]:9503/api/getSelf"

The Docker side is the part that catches people. The `port` setting is the forwarding rule from host to container, and the shipped compose file binds it to `127.0.0.1:9503:9503`. Remove the 127.0.0.1 to listen on all interfaces and forward all requests to the container, and the README says to make sure you use the whitelist and or the password settings to protect your account. It also says the only protection in that configuration is `IP_WHITELIST`, and that there are no warranties that it will secure your accounts. The MySQL service is bound the same way, to `127.0.0.1:9507:3306`, and the session tables live in that database.

The first line of the section is the summary to remember: please be careful with settings, otherwise you can expose your Telegram session and lose control.

What the .env file actually controls

The example environment file is the full configuration surface, and it is worth reading once before anything else.

`SERVER_ADDRESS` and `SERVER_PORT` set where the server listens, defaulting to 127.0.0.1 and 9503, and `REAL_IP_HEADER` is where you name the client header if you sit behind nginx, for example x-real-ip or x-forwarded-for. `MEMORY_LIMIT` defaults to 256M and `TIMEZONE` to UTC.

`REQUESTS_BULK_INTERVAL` is the one with a real behavioural effect. Requests are grouped into bulks and executed as a single bulk, the value is in seconds, and the comment says to decrease it to reduce latency and increase it to reduce load on the server, with 0 disabling the behaviour. For a service where you care about the time to first response, that knob is the one you will tune.

The Telegram side is `TELEGRAM_API_ID`, `TELEGRAM_API_HASH` and `LOGGER_LEVEL`, where the level comment maps 0 to fatal up to 5 for ultra verbose. A SOCKS5 proxy for Telegram is optional, with address, port, username and password.

The database choice is `DB_TYPE`, and the comment explains the trade. The `memory` type keeps all data in memory or in a session file and is the default behaviour, while `mysql` keeps part of the data in a MySQL database, reduces memory consumption and session size, and is marked as a beta function with MariaDB and InnoDB preferred, with tables created if they do not exist. Switching to MySQL is how you keep a session across restarts without holding it all in memory.

Editorial conclusion

Adopt TelegramApiServer when you want to script or service a Telegram account over ordinary HTTP, with sessions you manage yourself and the full MadelineProto method set available. Do not expose it to the internet as shipped, and do not use it with an account you cannot afford to lose, because the README warns that new accounts get banned and that a leaked session is a lost account. Verify first that the container port stays bound to 127.0.0.1, that `IP_WHITELIST` and `PASSWORDS` are set before you change the port mapping, that your `TELEGRAM_API_ID` and `TELEGRAM_API_HASH` are filled in, and that the `DB_TYPE` you choose matches whether you want session data in memory or in MySQL.

Frequently asked questions

What does TelegramApiServer do?

It is an asynchronous PHP server that exposes the Telegram API, both bot and user, over GET and POST requests. It is built on MadelineProto for the MTProto client and the Amp HTTP server, and it supports multiple sessions, media streaming and upload, and websocket endpoints for events and logs.

How do I install and authorize TelegramApiServer?

Clone the repository, copy `.env.docker.example` to `.env.docker`, run `docker compose pull`, then fill in app_id and app_hash from my.telegram.org and start the container with `docker compose run --rm api`. You then enter your phone number or bot hash, type the code Telegram sends, and wait ten to thirty seconds for the session to start.

How is the TelegramApiServer API addressed?

The URL pattern is `http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val%`, and every method supported by MadelineProto is available, with a dot separating class from method for calls such as `messages.getHistory` and `messages.sendMessage`.

How is TelegramApiServer protected?

The default settings only allow access from localhost or 127.0.0.1. `IP_WHITELIST` allows specific client addresses without a password, and `PASSWORDS` enables basic auth, where a correct username and password overrides the whitelist. The README warns that exposing the port to the internet leaves only the whitelist as protection, with no warranty that it will secure your accounts.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. xtrime-ru/TelegramApiServer on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/xtrime-ru-telegramapiserver.svg)](https://hysenlabs.com/projects/xtrime-ru-telegramapiserver)

Was this useful?