TG Selfhost Bot API

Getting started

Requirements

The application API ID/hash identify your Telegram application. They are different from a bot token issued by BotFather.

Prepare

git clone https://github.com/ichinya/tg-selfhost-botapi.git
cd tg-selfhost-botapi
cp .env.example .env

Fill in API_ID and API_HASH in .env. Keep that file private.

The gateway binds to 127.0.0.1 by default and does not expose the state directory. If remote clients, including a webhook receiver, must reach the Bot API, set GATEWAY_BIND=0.0.0.0 in .env and provide HTTPS and network access controls.

Start

Before the first GHCR publication, build locally:

docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build

Once a published image is available:

docker compose pull
docker compose up -d

For a private GHCR package, authenticate with an account that has package access; for anonymous pulls, the repository owner must make the package public. Local compilation can take a long time. The default build uses one compilation job.

Verify

docker compose ps
docker compose logs --tail=100 botapi gateway
curl --connect-timeout 5 --max-time 10 -i http://127.0.0.1:18080/

A response from the Bot API path confirms HTTP reachability, even if it reports a missing method or token. It does not confirm a bot session or webhook delivery.

The application endpoint is:

http://127.0.0.1:18080/bot<TOKEN>/<METHOD>

Use token-bearing calls only on the chosen server at the appropriate migration stage. To check a bot already assigned to this server:

read -rsp 'Bot token: ' BOT_TOKEN; printf '\n'
curl --connect-timeout 5 --max-time 15 \
  "http://127.0.0.1:18080/bot$BOT_TOKEN/getMe"
unset BOT_TOKEN

These command examples use Bash. A token expanded into curl’s URL can be visible in process arguments and access logs; run diagnostics in a trusted environment.

Configure the service · Move an existing bot