editMessageText
Use this method to edit text and game 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_idStringOptionalUnique identifier of the business connection on behalf of which the message to be edited was sent
chat_idIntegerStringOptionalRequired if inline\message\id is not specified. Unique identifier for the target chat or username of the target channel (in the format
@channelusername)message_idIntegerOptionalRequired if inline\message\id is not specified. Identifier of the message to edit
inline_message_idStringOptionalRequired if chat\id and message\id are not specified. Identifier of the inline message
New text of the message, 1-4096 characters after entities parsing
parse_modeStringOptionalMode for parsing entities in the message text. See formatting options for more details.
A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse\_mode
Link preview generation options for the message
A JSON-serialized object for an inline keyboard.
Returns
On success, Message | True is returned.
GramIO Usage
ts
// Edit message text when a user presses a button
bot.on("callback_query", async (ctx) => {
await ctx.editText("Updated message content!");
await ctx.answer();
});ts
// Edit with rich text formatting — entities are built automatically, no parse_mode needed
bot.on("callback_query", async (ctx) => {
await ctx.editText(
format`Hello, ${bold("world")}! Visit ${link("GramIO", "https://gramio.dev")}`,
);
await ctx.answer();
});ts
// Edit text and update the inline keyboard simultaneously
bot.on("callback_query", async (ctx) => {
const keyboard = new InlineKeyboard().text("Back", "go_back");
await ctx.editText("Step 2: choose an option.", {
reply_markup: keyboard,
});
await ctx.answer();
});ts
// Direct API call — edit a specific message by chat_id + message_id
await bot.api.editMessageText({
chat_id: 123456789,
message_id: 42,
text: "Message has been updated.",
link_preview_options: { is_disabled: true },
});Errors
| Code | Error | Cause |
|---|---|---|
| 400 | Bad Request: message is not modified | New text is identical to the current content — check before calling to avoid unnecessary requests |
| 400 | Bad Request: message can't be edited | Message is too old, was sent by a different bot, or is not a text or game message |
| 400 | Bad Request: TEXT_TOO_LONG | text exceeds 4096 characters — use the Split plugin for long content |
| 400 | Bad Request: can't parse entities | Malformed HTML/Markdown markup or mismatched tags — use GramIO's format helper to build entities safely |
| 400 | Bad Request: chat not found | Invalid or inaccessible chat_id |
| 400 | Bad Request: message not found | message_id doesn't exist in the chat |
| 403 | Forbidden: bot was blocked by the user | User blocked the bot — catch and mark user as inactive |
| 403 | Forbidden: not enough rights | Bot lacks edit permissions in a channel |
| 429 | Too Many Requests: retry after N | Flood control — check retry_after, use auto-retry plugin |
TIP
Use GramIO's auto-retry plugin to handle 429 errors automatically.
Tips & Gotchas
- Text length is 1–4096 characters. Empty strings are rejected — unlike captions, text cannot be cleared. For content that might exceed the limit, use the Split plugin.
parse_modeandentitiesare mutually exclusive. GramIO'sformathelper always producesentities, so never passparse_modealongside a formatted string — doing so causes an error.link_preview_optionsreplaces the deprecateddisable_web_page_preview. Use{ is_disabled: true }to suppress link previews, or{ url: "..." }to force a specific URL preview.- Business messages have a 48-hour edit window. Messages sent via a business connection by another user (not the bot) that lack an inline keyboard can only be edited within 48 hours of sending.
- Inline messages return
true, notMessage. When editing viainline_message_id, the method returnstrueon success instead of theMessageobject. Narrow the type before accessing message properties. ctx.editText()onCallbackQueryContextautomatically uses the correct identifier —chat_id + message_idfor regular messages,inline_message_idfor inline query results.
See Also
- editMessageCaption — edit the caption on photo/video messages
- editMessageReplyMarkup — change only the inline keyboard without touching the text
- editMessageMedia — replace the media file in a message
- Formatting guide — building rich text with
format,bold,italic, and more - Keyboards overview — building inline keyboards with
InlineKeyboard - Message — the type returned on success for non-inline messages
- auto-retry plugin — automatic
429retry handling - Split plugin — handle messages exceeding the 4096-character limit