Skip to content

editMessageCaption

Use this method to edit captions 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
captionStringOptional✏️ FormattableminLen 0maxLen 1024
New caption of the message, 0-1024 characters after entities parsing
parse_modeStringOptional
Mode for parsing entities in the message caption. See formatting options for more details.
caption_entitiesMessageEntity[]Optional
A JSON-serialized list of special entities that appear in the caption, which can be specified instead of parse\_mode
show_caption_above_mediaBooleanOptional
Pass True, if the caption must be shown above the message media. Supported only for animation, photo and video messages.
A JSON-serialized object for an inline keyboard.

Returns

On success, Message | True is returned.

GramIO Usage

ts
// Update a photo/video caption when a user presses a button
bot
.
on
("callback_query", async (
ctx
) => {
await
ctx
.
editCaption
("Caption updated!");
await
ctx
.
answer
();
});
ts
// Edit caption with rich formatting — entities are built automatically
bot
.
on
("callback_query", async (
ctx
) => {
await
ctx
.
editCaption
(
format
`${
bold
("Updated:")} new caption text`,
); await
ctx
.
answer
();
});
ts
// Remove a caption by passing an empty string
bot
.
on
("callback_query", async (
ctx
) => {
await
ctx
.
editCaption
("");
await
ctx
.
answer
();
});
ts
// Direct API call — edit caption and show it above the media
await 
bot
.
api
.
editMessageCaption
({
chat_id
: "@mychannel",
message_id
: 123,
caption
: "Updated caption for this photo",
show_caption_above_media
: true,
});

Errors

CodeErrorCause
400Bad Request: message is not modifiedNew caption is identical to current — check before calling to avoid unnecessary requests
400Bad Request: message can't be editedMessage too old, sent by another bot, or is not a media message with a caption
400Bad Request: CAPTION_TOO_LONGcaption exceeds 1024 characters
400Bad Request: can't parse entitiesMalformed HTML/Markdown markup — use GramIO's format helper to build caption_entities safely
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

  • Caption limit is 1024 characters — half the 4096-character limit for text messages. Plan your content layout accordingly.
  • Caption can be cleared by passing "" — unlike editMessageText, the caption is optional and can be set to zero characters to remove it entirely.
  • parse_mode and caption_entities are mutually exclusive. GramIO's format helper always produces caption_entities, so never pass parse_mode alongside a formatted string.
  • show_caption_above_media only works for animation, photo, and video — it has no effect on documents or audio messages.
  • 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.

See Also