HTTP API
Base path /v1 on the gateway (http://localhost:8080/v1 in the examples).
- Every request needs
Authorization: Bearer <BOT_TOKEN>. OnlyGET /healthzandPOST /hooks/<secret>go without it. - Bodies are JSON (
Content-Type: application/json) unless said otherwise. - Ids are strings, times are Unix milliseconds.
- The id of a private chat is the id of the other person.
- Requests that return nothing answer
{}.
Errors
An error is an HTTP status and a body:
{"error": "message text is too long", "code": "bad_request"}code | Status | When |
|---|---|---|
unauthorized | 401 | No token or a wrong one. |
bad_request | 400 | Bad parameters, or the core refused: text too long, not your message, poll closed… |
not_found | 404 | No such chat, message, hook or route. |
webhook | 409 | GET /v1/updates while a webhook is set or UPDATES=off. |
The bot
Get the bot
GET /v1/me→ {id, name, invite_url, about, commands}. invite_url is the link that opens a chat with the bot in the apps.
Change name or description
PATCH /v1/me
{"name": "Weather", "about": "Forecasts for any city"}Fields left out stay as they are. about is up to 512 characters.
Set commands
PUT /v1/me/commands
{"commands": [{"name": "weather", "description": "Forecast", "args": "<city>"}]}Up to 100 commands; [] removes them. See Commands and buttons.
Set the avatar
PUT /v1/me/avatar
Content-Type: image/jpeg
<picture bytes>JPEG, PNG or WebP up to 20 MB; it is cropped to a square and scaled down.
Chats
List chats
GET /v1/chats→ an array of Chat.
Get a chat
GET /v1/chats/{chat}→ Chat.
Accept a request
POST /v1/chats/{chat}/acceptAccepts a chat request or a group invitation (needed with ACCEPT_REQUESTS=contacts) → Chat.
Create a group
POST /v1/groups
{"name": "On-call", "members": ["u7f…", "u2c…"]}→ Chat.
Messages
List messages
GET /v1/chats/{chat}/messages?before=&limit=Messages stored in the bot's database, oldest first. before — a timestamp in ms; limit — 1–100, default 50. → an array of Message.
Get a message
GET /v1/chats/{chat}/messages/{msg}Send text
POST /v1/chats/{chat}/messages
{"text": "Hi @Anna", "reply_to": "m1…",
"mentions": [{"user": "u7f…", "offset": 3, "length": 5}],
"buttons": [[{"text": "OK", "data": "ok"}]]}Only text is required. offset and length of mentions count UTF-16 code units, as in JavaScript strings. Buttons: up to 3 rows of 2. → Message.
Send a file
POST /v1/chats/{chat}/files
Content-Type: multipart/form-data| Field | |
|---|---|
file | The file (up to 300 MB). |
caption | Text under it. |
reply_to | A message id. |
kind | photo, video, voice or file; by default from the file type. Photos: JPEG, PNG, WebP. |
duration_ms, width, height | For video and voice. |
The gateway makes the photo preview itself. → Message.
curl -H "Authorization: Bearer $BOT_TOKEN" -F file=@chart.png -F caption='CPU, last hour' \
localhost:8080/v1/chats/u7f…/filesDownload an attachment
GET /v1/chats/{chat}/messages/{msg}/fileThe file's bytes with its Content-Type. It is downloaded and decrypted on the first request.
Edit a message
PATCH /v1/chats/{chat}/messages/{msg}
{"text": "Deployed ✅", "buttons": []}Edits the bot's own text or caption. Left-out text stays; left-out buttons stay, [] removes them. Messages with buttons can be edited at any time. → Message.
Delete a message
DELETE /v1/chats/{chat}/messages/{msg}?for=allfor=all (default) — for everyone, own messages only; for=me — only in the bot's database.
React
PUT /v1/chats/{chat}/messages/{msg}/reaction
{"emoji": "👍"}DELETE /v1/chats/{chat}/messages/{msg}/reaction removes the bot's reaction.
Mark as read
POST /v1/chats/{chat}/read
{"up_to": "m9…"}Marks messages read up to up_to, or all of them if it is empty.
Polls
Send a poll
POST /v1/chats/{chat}/polls
{"question": "Lunch?", "options": ["Pizza", "Khinkali"], "multiple": false,
"close_ts": 1791373600000, "reply_to": ""}→ Message with poll.
Vote
POST /v1/chats/{chat}/messages/{msg}/vote
{"options": [1]}Option indexes from 0; [] takes the vote back.
Close a poll
POST /v1/chats/{chat}/messages/{msg}/closeOnly the bot's own polls.
Buttons
Answer a press
POST /v1/presses/{press_id}/answer
{"text": "Done"}A toast shown only to who pressed; up to 200 characters, within a minute of the press.
Updates
GET /v1/updates?offset=&timeout=&limit=→ an array of Update. See Receiving updates.
Hooks
Available when HOOKS_URL is set. See Incoming hooks.
| Request | |
|---|---|
GET /v1/hooks?chat= | The chat's hooks (all hooks without chat). |
POST /v1/hooks {chat_id, format} | Create → {id, chat_id, format, ts, url}; url is shown only here. |
DELETE /v1/hooks/{id} | Remove. |
POST /hooks/<secret> | Post to a hook; no token. |