{% note tip "" %}
If you are developing integrations for Bitrix24 using AI tools (Codex, Claude Code, Cursor), connect to the MCP server so that the assistant can utilize the official REST documentation.
{% endnote %}
KEYBOARD adds interactive buttons to a message: link navigation, command execution, text substitution in the input field, and other actions.
The keyboard is passed in the KEYBOARD parameter when sending or updating a message: im.message.add, im.message.update.
KEYBOARD.BUTTONS— array of buttonsTEXT— button text- one action:
LINKorACTION+ACTION_VALUEorCOMMAND
{% include Footnote on Examples %}
{% list tabs %}
-
cURL (Webhook)
curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"DIALOG_ID":"chat2725","MESSAGE":"Select an action","KEYBOARD":{"BUTTONS":[{"TEXT":"Open website","LINK":"https://www.example.com/"},{"TYPE":"NEWLINE"},{"TEXT":"Insert command","ACTION":"PUT","ACTION_VALUE":"/help"}]}}' \ https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/im.message.add
-
cURL (OAuth)
curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"DIALOG_ID":"chat2725","MESSAGE":"Select an action","KEYBOARD":{"BUTTONS":[{"TEXT":"Open website","LINK":"https://www.example.com/"},{"TYPE":"NEWLINE"},{"TEXT":"Insert command","ACTION":"PUT","ACTION_VALUE":"/help"}]},"auth":"**put_access_token_here**"}' \ https://**put_your_bitrix24_address**/rest/im.message.add
-
JS (TS)
// This snippet is an ES module: top-level await requires type="module" or a bundler. // $b24 is an already-initialized SDK instance (see the SDK "Get started" guide). import { Text } from '@bitrix24/b24jssdk' import type { B24Frame } from '@bitrix24/b24jssdk' declare const $b24: B24Frame try { const response = await $b24.actions.v2.call.make<number>({ method: 'im.message.add', params: { DIALOG_ID: 'chat2725', MESSAGE: 'Choose an action', KEYBOARD: { BUTTONS: [ { TEXT: 'Open site', LINK: 'https://www.example.com/' }, { TYPE: 'NEWLINE' }, { TEXT: 'Insert command', ACTION: 'PUT', ACTION_VALUE: '/help' }, ], }, }, requestId: Text.getUuidRfc4122() }) // The payload is available only on a successful response if (!response.isSuccess) { console.error(response.getErrorMessages().join('; ')) } else { const result = response.getData()!.result console.info('Created message ID:', result) } } catch (error) { // Thrown on transport or SDK failures (AjaxError, SdkError, etc.) console.error(error) }
-
JS (UMD)
<!-- Load the SDK (UMD build); it is exposed as the global B24Js --> <script src="https://unpkg.com/@bitrix24/b24jssdk@1/dist/umd/index.min.js"></script> <script> async function sendMessageWithKeyboard() { try { // Initialize the SDK inside a Bitrix24 frame const $b24 = await B24Js.initializeB24Frame() const response = await $b24.actions.v2.call.make({ method: 'im.message.add', params: { DIALOG_ID: 'chat2725', MESSAGE: 'Choose an action', KEYBOARD: { BUTTONS: [ { TEXT: 'Open site', LINK: 'https://www.example.com/' }, { TYPE: 'NEWLINE' }, { TEXT: 'Insert command', ACTION: 'PUT', ACTION_VALUE: '/help' }, ], }, }, requestId: B24Js.Text.getUuidRfc4122() }) // The payload is available only on a successful response if (!response.isSuccess) { console.error(response.getErrorMessages().join('; ')) return } const result = response.getData().result console.info('Created message ID:', result) } catch (error) { // Thrown on transport or SDK failures (AjaxError, SdkError, etc.) console.error(error) } } document.addEventListener('DOMContentLoaded', sendMessageWithKeyboard) </script>
-
PHP
try { $response = $b24Service ->core ->call( 'im.message.add', [ 'DIALOG_ID' => 'chat2725', 'MESSAGE' => 'Select an action', 'KEYBOARD' => [ 'BUTTONS' => [ ['TEXT' => 'Open website', 'LINK' => 'https://www.example.com/'], ['TYPE' => 'NEWLINE'], ['TEXT' => 'Insert command', 'ACTION' => 'PUT', 'ACTION_VALUE' => '/help'], ], ], ] ); $result = $response ->getResponseData() ->getResult(); echo 'Created message ID: ' . $result; } catch (Throwable $e) { error_log($e->getMessage()); echo 'Error: ' . $e->getMessage(); }
-
BX24.js
BX24.callMethod( 'im.message.add', { DIALOG_ID: 'chat2725', MESSAGE: 'Select an action', KEYBOARD: { BUTTONS: [ { TEXT: 'Open website', LINK: 'https://www.example.com/' }, { TYPE: 'NEWLINE' }, { TEXT: 'Insert command', ACTION: 'PUT', ACTION_VALUE: '/help' }, ], }, }, function(result) { if (result.error()) { console.error(result.error().ex); } else { console.log(result.data()); } } );
-
PHP CRest
require_once('crest.php'); $result = CRest::call( 'im.message.add', [ 'DIALOG_ID' => 'chat2725', 'MESSAGE' => 'Select an action', 'KEYBOARD' => [ 'BUTTONS' => [ ['TEXT' => 'Open website', 'LINK' => 'https://www.example.com/'], ['TYPE' => 'NEWLINE'], ['TEXT' => 'Insert command', 'ACTION' => 'PUT', 'ACTION_VALUE' => '/help'], ], ], ] ); print_r($result);
-
Go
// client and ctx are already created — see the Go SDK section res, err := client.Core().Call(ctx, "im.message.add", b24.Params{ "DIALOG_ID": "chat2725", "MESSAGE": "Select an action", "KEYBOARD": b24.Params{ "BUTTONS": []b24.Params{ { "TEXT": "Open website", "LINK": "https://www.example.com/", }, { "TYPE": "NEWLINE", }, { "TEXT": "Insert command", "ACTION": "PUT", "ACTION_VALUE": "/help", }, }, }, }) if err != nil { return fmt.Errorf("im.message.add: %w", err) } // The response arrives as json.RawMessage — unmarshal it // into a struct matching the response shape shown below on this page. fmt.Printf("%s\n", res.Result)
{% endlist %}
{% note warning "" %}
The current documentation on keyboards can be found in the Chatbots 2.0 section:
{% endnote %}