Interactive elements

Message keyboard

keyboard belongs to a message. Rows may have different widths; the maximum is 9 rows and 10 buttons per row.

Button shape

command or action is required. text and emoji icon are optional, and long labels ellipsize. action.type defaults to send_command.

{
  "command": "/status",
  "text": "Status",
  "icon": "📦",
  "single_use": false,
  "expires_at": null
}

Actions

send_command posts a visible command, send_message posts specified text, callback emits an event without a user message, and open_url opens a confirmed HTTPS URL. Callback buttons show a loader while pending.

SDK practice

Commands create a visible user message; callbacks do not. Use callbacks for interface state and never place sensitive values in action.data.

Even with single_use enabled, make the server handler idempotent because duplicate network delivery can happen before the button is updated.

Usage examples

import { callbackButton, commandButton, urlButton } from '@keychat/bots';

await bot.sendMessage({ chat_id: chatId, content: {
  text: 'Choose an action',
  keyboard: { rows: [
    [commandButton('/status', { text: 'Status', icon: '📦' })],
    [callbackButton('details', 'Details', 'order-42'), urlButton('Help', 'https://example.com/help')]
  ] }
}});
© 2026. Key Chat.