Skip to content

editMessageReplyMarkup

Use this method to edit only the reply markup of messages. On success, if the edited message is not an inline message, the edited Message is returned, otherwise True is returned. Note that business messages that were not sent by the bot and do not contain an inline keyboard can only be edited within 48 hours from the time they were sent.

Parameters

business_connection_idStringOptional
Unique identifier of the business connection on behalf of which the message to be edited was sent
chat_idIntegerStringOptional
Required if inline\message\id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername)
message_idIntegerOptional
Required if inline\message\id is not specified. Identifier of the message to edit
inline_message_idStringOptional
Required if chat\id and message\id are not specified. Identifier of the inline message
A JSON-serialized object for an inline keyboard.

Returns

On success, Message | True is returned.

GramIO Usage

ts
// Replace the keyboard on a message after a button press
bot
.
on
("callback_query", async (
ctx
) => {
const
updatedKeyboard
= new
InlineKeyboard
()
.
text
("Option A ✓", "opt_a_done")
.
row
()
.
text
("Back", "go_back");
await
ctx
.
editReplyMarkup
(
updatedKeyboard
);
await
ctx
.
answer
();
});
ts
// Build a multi-step wizard — swap keyboards between steps
bot
.
on
("callback_query", async (
ctx
) => {
if (
ctx
.
queryPayload
=== "step_1") {
const
step2Keyboard
= new
InlineKeyboard
()
.
text
("Continue →", "step_2")
.
text
("Cancel", "cancel");
await
ctx
.
editReplyMarkup
(
step2Keyboard
);
} await
ctx
.
answer
();
});
ts
// Direct API call — remove the inline keyboard from a message
await 
bot
.
api
.
editMessageReplyMarkup
({
chat_id
: 123456789,
message_id
: 42,
// omit reply_markup to remove the existing keyboard });

Errors

CodeErrorCause
400Bad Request: message is not modifiedNew keyboard is identical to the current one — check before calling
400Bad Request: message can't be editedMessage too old, sent by another bot, or the message has no inline keyboard to edit
400Bad Request: chat not foundInvalid or inaccessible chat_id
400Bad Request: message not foundmessage_id doesn't exist in the chat
403Forbidden: bot was blocked by the userUser blocked the bot — catch and mark user as inactive
403Forbidden: not enough rightsBot lacks edit permissions in a channel
429Too Many Requests: retry after NFlood control — check retry_after, use auto-retry plugin

TIP

Use GramIO's auto-retry plugin to handle 429 errors automatically.

Tips & Gotchas

  • Only InlineKeyboardMarkup is supported — you cannot switch to ReplyKeyboardMarkup or ForceReply using this method. Inline keyboards are the only type that can be attached to non-private bot messages.
  • Omit reply_markup to remove the keyboard. Sending the request without the reply_markup parameter removes the existing inline keyboard from the message.
  • This is the lightest edit method — it changes only the keyboard, leaving the message text, caption, and media untouched. Prefer this over editMessageText when only the button state needs to change.
  • Business messages have a 48-hour edit window. Messages sent via a business connection by another user without an inline keyboard can only be edited within 48 hours of sending.
  • Inline messages return true, not Message. When editing via inline_message_id, the method returns true on success instead of the updated Message object.
  • Ideal for wizard-style UIs. Swapping keyboards between steps is a common pattern for multi-step bots — this method handles it with minimal overhead.

See Also