QivunaDevelopers

Keyboards and callbacks

Attach an inline keyboard to a message. A callback button sends your bot a callback_query when pressed; a URL button opens a link after the app shows where it leads.

Sending a keyboard#

{"chat_id": -4503600130020245,
 "text": "Lunch?",
 "reply_markup": {"inline_keyboard": [
   [{"text": "Pizza", "callback_data": "v:pizza"}, {"text": "Sushi", "callback_data": "v:sushi"}],
   [{"text": "Menu", "url": "https://lunch.example.com/menu"}]]}}

reply_markup works on sendMessage, editMessageText, editMessageReplyMarkup and the three media methods. It may be an object or a JSON string.

Limits#

Rowsat most 10, none empty
Buttons per rowat most 8
Buttons in allat most 64
Button text1–40 characters, no control characters. Invisible formatting characters (direction marks, zero-width spaces, soft hyphens, …) are removed first, and a label that is blank after that is refused. Emoji sequences (ZWJ, variation selectors) are kept.
callback_data1–64 bytes
urlhttps://, a host, no user name or password, at most 512 characters
Fieldstext and exactly one of callback_data or url; anything else (login_url, switch_inline_query, …) is refused

A broken keyboard answers 422 invalid_markup with parameter: reply_markup. {"inline_keyboard": []} means no keyboard.

Before opening a URL button (or a text_link), the app shows its registrable domain, e.g. example.co.il. A domain is shown in Unicode only if each of its non-ASCII characters is an accented Latin letter (Latin-1 Supplement or Latin Extended-A, such as é or ü); anything else, including other scripts and look-alikes, is shown in its xn-- form, so pаypal.com with a Cyrillic “а” shows as xn--pypal-4ve.com.

Presses#

  1. A person presses a callback button. The app shows a spinner on it.
  2. Your bot receives a callback_query with the press's id, who pressed (from), your message (with its keyboard) and the button's data.
  3. You answer with answerCallbackQuery: nothing (the spinner stops), a short toast (text, up to 200 characters), or an alert (show_alert: true). You may also edit the message.
{"callback_query_id": "01JB2G0M3K6V1S8T4W2Q9R5X7Y", "text": "Voted for pizza"}

Changing a keyboard#

editMessageReplyMarkup replaces or removes the keyboard of your own message, at any age. editMessageText also replaces it — and removes it if you leave reply_markup out, as in Telegram.

Every keyboard write gives the message a fresh random revision. A press on a copy of the keyboard that an app has not refreshed yet is refused in the app, so your bot never gets a press for a button that no longer exists.

Keyboards in encrypted chats#

In an encrypted bot's chats the keyboard is part of the signed, encrypted message (QB1 kb), never reply_markup: reply_markup next to an envelope is refused, and editMessageReplyMarkup in an encrypted bot's private chat answers 403 e2ee_required. Limits are stricter there: at most 8 rows, 1–4 buttons a row, 32 buttons, labels 1–40 characters. A press arrives as an encrypted_message with kind: "callback" and a callback_query_id; you answer with answerCallbackQuery {callback_query_id, envelope}. The callback data then comes from the person's phone, not from Qivuna's copy of your keyboard: treat it as untrusted input. See Encrypted bots.