Skip to content

sendMediaGroup

Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio files can be only grouped in an album with messages of the same type. On success, an array of Message objects that were sent is returned.

Parameters

business_connection_idStringOptional
Unique identifier of the business connection on behalf of which the message will be sent
chat_idIntegerStringRequired
Unique identifier for the target chat or username of the target channel (in the format @channelusername)
message_thread_idIntegerOptional
Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only
direct_messages_topic_idIntegerOptional
Identifier of the direct messages topic to which the messages will be sent; required if the messages are sent to a direct messages chat
A JSON-serialized array describing messages to be sent, must include 2-10 items
disable_notificationBooleanOptional
Sends messages silently. Users will receive a notification with no sound.
protect_contentBooleanOptional
Protects the contents of the sent messages from forwarding and saving
allow_paid_broadcastBooleanOptional
Pass True to allow up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance
message_effect_idStringOptional
Unique identifier of the message effect to be added to the message; for private chats only
reply_parametersReplyParametersOptional
Description of the message to reply to

Returns

On success, an array of Message objects is returned.

GramIO Usage

ts
// Send 3 photos as an album
bot
.
command
("album", (
ctx
) =>
ctx
.
sendMediaGroup
([
MediaInput
.
photo
("file_id_1", {
caption
: "First photo" }),
MediaInput
.
photo
("file_id_2"),
MediaInput
.
photo
("file_id_3"),
]) );
ts
// Upload local files and send as a mixed photo+video album
bot
.
command
("upload", async (
ctx
) => {
const
messages
= await
ctx
.
sendMediaGroup
([
MediaInput
.
photo
(await
MediaUpload
.
path
("./photo1.jpg"), {
caption
: "Photo 1" }),
MediaInput
.
photo
(await
MediaUpload
.
path
("./photo2.jpg")),
MediaInput
.
video
(await
MediaUpload
.
path
("./clip.mp4")),
]);
console
.
log
(`Sent ${
messages
.
length
} messages`);
});
ts
// Reply with a media group (sets reply_parameters automatically)
bot
.
on
("message", (
ctx
) =>
ctx
.
replyWithMediaGroup
([
MediaInput
.
photo
("file_id_1"),
MediaInput
.
photo
("file_id_2"),
]) );
ts
// Direct API call — send a document album
await 
bot
.
api
.
sendMediaGroup
({
chat_id
: 123456789,
media
: [
MediaInput
.
document
("doc_file_id_1", {
caption
: "Report Q1" }),
MediaInput
.
document
("doc_file_id_2"),
], });

Errors

CodeErrorCause
400Bad Request: chat not foundchat_id is invalid or the bot has no access to that chat
400Bad Request: wrong file identifier/HTTP URL specifiedA file_id in the media array is malformed or the URL is inaccessible
400Bad Request: MEDIA_EMPTYmedia array has fewer than 2 items — albums require at least 2
400Bad Request: MEDIA_GROUP_INVALIDMixed incompatible types — documents/audio can only be grouped with the same type
403Forbidden: bot was blocked by the userUser blocked the bot — catch and mark as inactive
403Forbidden: bot is not a member of the channel chatBot not in the target channel — add the bot as a member first
429Too Many Requests: retry after NRate limit hit — check retry_after, use auto-retry plugin

TIP

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

Tips & Gotchas

  • 2–10 items required. Albums must contain between 2 and 10 media items. Sending 1 item will error; more than 10 is not allowed.
  • Mixed types are restricted. Photos and videos can be freely mixed. Documents can only be grouped with other documents; audio can only be grouped with other audio — cross-type mixing will error.
  • No group-level reply_markup. Unlike sendPhoto or sendMessage, sendMediaGroup does not accept a reply_markup parameter. Attach a keyboard via a separate sendMessage call if needed.
  • Returns one MessageContext per item. The method returns Promise<MessageContext[]> — one element per media item sent. Use the array to access each message's file_id for caching.
  • Use MediaInput.*() helpers. Always use MediaInput.photo(), MediaInput.video(), etc. to build InputMedia objects — they set the type field automatically and accept optional caption, parse_mode / entities per item.
  • Cache file_id after first upload. Save file_id values from the returned messages to avoid re-uploading on subsequent sends. The media-cache plugin can automate this.

See Also