BuzzioDocs

Bot API

Who this is for: developers with a Forge token (bzbot_…) who want to receive updates and reply as their bot.

Console: developers.buzzio.dev · Product: Bots · Workers: Worker bots

This API copies Telegram’s developer experience (token, methods, { ok, result }), not Telegram’s whole product. There is no Buzzio file CDN, no sealed-chat access, and no acting as a person.


Quick start

  1. In the app: @forge_bot → /newbot → Service → copy bzbot_… once.
  2. On desktop: paste the token on developers.buzzio.dev.
  3. Terminal: getMe → leave getUpdates running → click Test /start on the site → sendMessage a welcome.
  4. Submit when Test passes. Approved + active plan → real users can Start.

Seed / 12-word phrase never goes on the website. The token is the bot login.


What you can do

Job Method
Check the token getMe
Poll for user messages (no public URL) getUpdates
Reply with text sendMessage
Reply with photo / video / audio / file URL you host sendPhoto / sendVideo / sendAudio / sendDocument
Push updates to your HTTPS server setWebhook
Stop webhook, return to polling deleteWebhook
See webhook status getWebhookInfo
Show / hide a typing pill sendChatAction
Inline buttons reply_markup on send, then answerCallbackQuery
Edit or delete a bot message editMessageText / editMessageCaption / editMessageMedia / editMessageReplyMarkup / deleteMessage / deleteMessages
Copy or forward in this bot DM copyMessage / forwardMessage
Composer slash list setMyCommands / getMyCommands / deleteMyCommands
Display name / bio / search subtitle setMyName / setMyDescription / setMyShortDescription
Profile photo (HTTPS URL they host) setMyProfilePhoto / removeMyProfilePhoto
Chat menu (commands or Mini App URL) setChatMenuButton / getChatMenuButton
Animation / voice / video note / sticker sendAnimation / sendVoice / sendVideoNote / sendSticker (URL or bzstk_…)
Bot-owned sticker set createNewStickerSet / getStickerSet / uploadStickerFile
Installs / stats / 7-day history / report / schedule getMyInstalls / getBotStats / getChatHistory / reportMessage / sendScheduledMessage
Location / venue / contact card sendLocation / sendVenue / sendContact
Poll, dice, album, checklist sendPoll / stopPoll / sendDice / sendMediaGroup / sendChecklist
Confirmable choices sendChoice
Live photo / streaming draft / live pin sendLivePhoto / sendMessageDraft / editMessageLiveLocation
React / vanish / rich blocks / getFile setMessageReaction / ephemeral edits / sendRichMessage / getFile

You cannot: read sealed 1:1 chats, Whisper private chat, Whisper Questions, or E2E groups; upload bytes for Buzzio to host; or use a service token as a worker (and the reverse). Payments, checkout, invoices, pay buttons, paid media, Stars, gifts, paid reactions, and subscriptions are permanently not offered: method names return 404, while equivalent fields, buttons, and rich blocks return 400 validation errors.


Base URL and auth

Host: https://developers.buzzio.dev

Telegram-style (primary):

https://developers.buzzio.dev/bot<token>/<method>

Example: https://developers.buzzio.dev/botbzbot_…/getMe

Also accepted (Bearer):

POST https://developers.buzzio.dev/v1/sendMessage
Authorization: Bearer <token>
Content-Type: application/json

Same pattern for /v1/getMe, /v1/getUpdates, and other methods.

Do not put the token in a ?token= query string (access logs). Path or Bearer only.

How to call

HTTPS. UTF-8. GET or POST.

Parameters from, in order (later wins):

  1. URL query string
  2. application/x-www-form-urlencoded
  3. application/json

Reject multipart/form-data file uploads. Outgoing media is an HTTPS URL you host, or a bzstk_… file_id from a set this bot registered. Incoming user media is a 7-day bzfile_…. Buzzio never GETs your URL (SSRF lock).


Success / error envelope

Success:

{ "ok": true, "result": { } }

Failure:

{ "ok": false, "error_code": 401, "description": "Unauthorized" }
HTTP error_code When
401 401 Bad / missing / rotated token
403 403 Shadow-banned, suspended, plan expired, user hid the bot
400 400 Bad chat_id, empty text, file bytes, bad URL
404 404 Unknown method, unknown chat_id
409 409 getUpdates while a webhook is set
429 429 Rate limit

Older /v1/sendMessage responses may also include "error": "…" alongside description for compatibility.


Two ways to receive updates

One at a time (same rule as Telegram):

                    ┌─ webhook URL set  → Buzzio POSTs Update to you
User taps Start  ───┤
                    └─ no webhook       → you poll getUpdates
Mode When Public URL?
Polling getUpdates Laptop, first bot, CI No
Webhook setWebhook Always-on server Yes (HTTPS)

If a webhook is set, getUpdates returns 409 (Conflict: can't use getUpdates while webhook is active).
deleteWebhook restores polling.

Pending polling updates: keep about 24 hours, then drop. Cap about 1000 per bot; drop oldest.

Website Test /start and a real user Start use the same Update shape. A terminal bot that answers Test will answer a real user.


Platform `/start`

Buzzio owns the Start button and the start event. You own the welcome text.

Layer Owner
Start button in the app Buzzio
POSTing /start to you Buzzio
Welcome sendMessage after Start You
Other commands (/help, /weather, …) You

Do not invent a custom “type hi to begin” as the only entry — users learn one Start for every bot.


Available methods

The Bot API publishes 151 HTTP methods. Each one is documented individually — heading, “Use this method to…”, then a Parameter / Type / Required / Description table — on Bot API methods. That is the same layout as Telegram Bot API.

Console copy (searchable, one page): developers.buzzio.dev/docs/api/.

Status Names
Live Waves 0–H and J (getMe, send*, edit*, stickers, room moderation, invites, forum/channels, native ops, …)
Documented, not enabled Wave I: stories, inline queries, Mini App answers, games, logOut / close. Calls return 404.
Permanently not offered Payments, checkout, invoices, pay buttons, paid media, Stars, gifts, paid reactions, subscriptions, and bot premium (setMyPremium, grantUserPremium, …). Method names return 404; equivalent request fields/controls fail validation.

chat_id is always a string. Outgoing media is an HTTPS URL you host; Buzzio never GETs it. Incoming user media is a 7-day bzfile_…. Forum topic methods create and manage community channels (message_thread_id is the channel id).

Worker grants: Worker bots.

JSON types

Update

{
  "update_id": 17,
  "message": { }
}

update_id is a positive integer, sequential per bot (needed for offset).

Wave A also delivers callback_query when a user taps an inline button, and start_parameter on /start <payload> (also in message.text). Interactive sends also deliver choice_answer, poll_answer, and—only for developer-mode checklists—checklist_update.

Wave F delivers chat_join_request when someone asks to join a room that requires approval:

{
  "chat_join_request": {
    "chat": { "id": "ohg:…", "type": "group", "title": "Mods" },
    "from": { "id": "bu_…", "is_bot": false, "first_name": "User" },
    "date": 1710000000,
    "invite_link": { "invite_link": "https://links.buzzio.dev/join?g=…&t=…" }
  }
}

User

{
  "id": "bu_a1b2c3…",
  "is_bot": false,
  "first_name": "User"
}

You do not receive the person’s Buzzio ID, Buzzio username, or avatar. id is a bot-scoped opaque handle (bu_…) stable for that person talking to your bot only — different bots get different ids for the same person. first_name is generic "User". Forge analytics stay counts-only.

Chat

{
  "id": "botdm_<botId>_<opaqueSuffix>",
  "type": "private"
}

Service-bot v1: type is always "private". The chat id never embeds a Buzzio ID.

Message

{
  "message_id": "msg_…",
  "from": { "id": "bu_…", "is_bot": false, "first_name": "User" },
  "chat": { "id": "botdm_…", "type": "private" },
  "date": 1710000000,
  "text": "/start",
  "chat_id": "botdm_…",
  "command": "start"
}
Field Why
chat.id Telegram style
chat_id Kept for playground / echo samples
command Platform Start ("start") so you cannot miss it
text "/start" or "/start <payload>"
start_parameter Present when the user opened me.buzzio.dev/<bot>?start= or buzzio://bot?u=&start=
User → bot Text, plus incoming photo/voice/file as file_id (7 days)
Bot → user media URL metadata on outgoing messages
photo / voice / … Incoming attachment fields on the Update
poll_answer User voted on a bot poll
choice_answer User confirmed or cancelled a sendChoice card
checklist_update A checklist item changed when update_mode is developer

Unix date is seconds.


Interactive messages

Buttons and keyboards

reply_markup inline keyboards allow at most 8 rows × 8 buttons. Button text is 1–64 characters and each button must have exactly one action: callback_data (1–64), an HTTPS url, copy_text.text (1–256), or disabled: true. Optional style is primary, success, or danger.

Reply keyboards allow at most 12 rows × 12 text buttons (1–64). Supported modifiers are resize_keyboard, one_time_keyboard, is_persistent, input_field_placeholder (1–64), and selective; remove_keyboard and force_reply are also supported. Unsafe Telegram button fields, including web_app, login/inline-switch/request fields, games, pay buttons, and all commerce fields, return 400.

Callback taps are accepted only when the value exists on that live bot-owned message and the button is enabled. They expire after 30 seconds, duplicate taps are deduplicated within that window, and each user/chat is limited to 20 callbacks/minute. answerCallbackQuery is idempotent; unknown or cross-bot ids return 404 and expired ids return 410.

`sendChoice`

Service-bot DMs can send a native confirmable choice:

  • question (or text / title): 1–4000 characters.
  • options: 2–10 strings or { id, text } objects. Text is 1–100; ids are unique 1–64-character letters/numbers/underscore/hyphen and default to opt_1, opt_2, …
  • Single is the default. mode: "multi" / "multiple" or a supported multiple flag enables multi-select.
  • min_selected defaults to 1; max_selected defaults to 1 for single and option count for multi.
  • confirm_label / cancel_label: max 64. Expiry is 1 minute–7 days via expires_at or whole-second expires_in.

The Message choice payload contains the normalized fields plus kind: "choice", title, selected_option_ids, and status. The app saves each selection first, then submits Confirm or Cancel. Confirm enforces min/max; repeated submit is idempotent. Final submission changes payload status to submitted or cancelled and emits:

{
  "choice_answer": {
    "choice_id": "msg_…",
    "message_id": "msg_…",
    "user": { "id": "bu_…", "is_bot": false, "first_name": "User" },
    "option_ids": ["opt_1"],
    "cancelled": false,
    "chat_id": "botdm_…"
  }
}

Polls and checklists

Polls have a 1–300-character question and 2–10 options of 1–100 characters. Regular polls are single-answer unless allows_multiple_answers: true; quiz polls are always single-answer, require 0-based correct_option_id, and may include a 200-character explanation revealed after answering. open_period is 5–600 seconds; close_date is Unix seconds/ms 5–600 seconds ahead; use one, not both. A changed selection replaces the previous vote and emits poll_answer; unchanged submissions are idempotent. Closed/timed-out polls return 410.

Checklists have a 1–200-character title and 1–30 items. Item text is 1–120; optional stable ids use the same 1–64 safe-id rule. update_mode: "client" is the default and does not notify the bot. update_mode: "developer" (also developer_updates: true / notify_bot: true) emits checklist_update only when a value actually changes. It includes nested actor, message, item, and state, plus flat chat_id, message_id, item_id, and done.

Rich blocks

sendRichMessage accepts 1–30 blocks and a maximum serialized payload of 64 KiB. In addition to heading, paragraph, list, and table, it supports:

  • collapsible: title 1–120, text 1–4000, optional initially_expanded; max 10.
  • media: photo/video/audio/document HTTPS URL (max 2048), caption max 1000, alt text max 300, optional declared size 1–20 MiB; max 10.
  • actions: safe inline buttons. Collapsible/media blocks may also embed actions; max 20 embedded actions total and 1–8 per block.

Commerce/payment/invoice/paid-media/Stars/gift/subscription blocks or fields return 400.


Webhook POST (Buzzio → you)

When a webhook is set, Buzzio POSTs one Update (same JSON as getUpdates items):

POST https://your-server/webhook
Content-Type: application/json
X-Buzzio-Timestamp: …
X-Buzzio-Bot-Id: …
X-Buzzio-Signature: sha256=…

Verify the signature before trusting the body. Return HTTP 2xx quickly, then call sendMessage asynchronously if needed.

Probe payloads from the console may include "probe": true — ignore for real chats.


Terminal walkthrough

# 1. Token from Forge /newbot (vanishes after 5 minutes)

# 2. Who am I?
curl.exe -sS https://developers.buzzio.dev/botbzbot_TOKEN/getMe

# 3. Wait for messages (leave running)
curl.exe -sS "https://developers.buzzio.dev/botbzbot_TOKEN/getUpdates?timeout=20"

# 4. After an Update arrives:
curl.exe -sS -X POST https://developers.buzzio.dev/botbzbot_TOKEN/sendMessage `
  -H "Content-Type: application/json" `
  -d "{\"chat_id\":\"botdm_…\",\"text\":\"Hi, I am Weather Bot.\"}"

Loop in a script: offset = last update_id + 1 so you do not see the same Update twice.

Test without a public server: start the poll loop first, then click Test on the website. Buzzio queues /start; your script sendMessages the welcome; Test passes; you can Submit.

Always-on later: setWebhook with your HTTPS URL, stop polling.


What stays on the website / Forge

Still website / Forge only Why
Create bot, username Identity = Buzzio ID on the phone
Show token 5 min / reset Forge /@yourbot api reset
Submit for review ToS + review ping
Pay / renew No card on the Bot API
Staff ban Founder desk

setWebhook on the API is allowed. Console save-webhook is the same field.


Limits

Rule Value
User → bot ~30 / minute / chat
sendMessage ~60 / minute / bot
Text 4000 chars
Media HTTPS URL you host; Buzzio never fetches
getUpdates timeout 0–25 s
Polling queue ~24 h, max ~1000
sendChoice 2–10 options; 1 min–7 day expiry
Poll 2–10 options; timed close 5–600 s
Checklist 1–30 items
Rich message 30 blocks / 64 KiB; 10 media; 10 collapsibles; 20 actions
Callback tap 30 s lifetime; 20/min/user/chat
Live send Approved + plan active (test chats botdm_test_* allowed while testing)
chat_id Only botdm_test_* or botdm_<thisBotId>_<ghostId> for service bots
Sealed / person ids 400

Shadow-ban / suspend: webhook paused; sendMessage 403; getUpdates empty or 403.

Abuse and quotas are keyed by owner Buzzio ID and by bot. Ban the person → their bots go offline.


Telegram mapping

Telegram Buzzio
api.telegram.org/bot<token>/METHOD developers.buzzio.dev/bot<token>/METHOD
{ "ok": true, "result": … } Same
getUpdates xor webhook Same
Integer chat ids Strings (botdm_…, ohg:…, community:…)
sendPhoto by URL Same idea; URL only, never multipart
Groups Worker token after Accept + grant
Incoming file_id 7-day hold, not a public CDN
Per-method pages Bot API methods

Intentionally not here

Item Why
bot-api.buzzio.dev hostname Nice alias; not required
Official client libraries After Wave I
Developer-hosted file CDN Cost lock: outgoing media stays URL-only
Payments, checkout, invoices, pay buttons, paid media, Stars, gifts, paid reactions, subscriptions Permanently not offered; method names return 404 and equivalent fields/controls return validation errors
Wave I (stories, inline, games, session) Names documented; calls return 404

Worker room grants: Worker bots. Full method tables: Bot API methods.