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_idStringOptionalUnique identifier of the business connection on behalf of which the message will be sent
chat_idIntegerStringRequiredUnique identifier for the target chat or username of the target channel (in the format
@channelusername)message_thread_idIntegerOptionalUnique 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_idIntegerOptionalIdentifier 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_notificationBooleanOptionalSends messages silently. Users will receive a notification with no sound.
protect_contentBooleanOptionalProtects the contents of the sent messages from forwarding and saving
allow_paid_broadcastBooleanOptionalPass 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_idStringOptionalUnique identifier of the message effect to be added to the message; for private chats only
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
| Code | Error | Cause |
|---|---|---|
| 400 | Bad Request: chat not found | chat_id is invalid or the bot has no access to that chat |
| 400 | Bad Request: wrong file identifier/HTTP URL specified | A file_id in the media array is malformed or the URL is inaccessible |
| 400 | Bad Request: MEDIA_EMPTY | media array has fewer than 2 items — albums require at least 2 |
| 400 | Bad Request: MEDIA_GROUP_INVALID | Mixed incompatible types — documents/audio can only be grouped with the same type |
| 403 | Forbidden: bot was blocked by the user | User blocked the bot — catch and mark as inactive |
| 403 | Forbidden: bot is not a member of the channel chat | Bot not in the target channel — add the bot as a member first |
| 429 | Too Many Requests: retry after N | Rate 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. UnlikesendPhotoorsendMessage,sendMediaGroupdoes not accept areply_markupparameter. Attach a keyboard via a separatesendMessagecall if needed. - Returns one
MessageContextper item. The method returnsPromise<MessageContext[]>— one element per media item sent. Use the array to access each message'sfile_idfor caching. - Use
MediaInput.*()helpers. Always useMediaInput.photo(),MediaInput.video(), etc. to buildInputMediaobjects — they set thetypefield automatically and accept optionalcaption,parse_mode/entitiesper item. - Cache
file_idafter first upload. Savefile_idvalues from the returned messages to avoid re-uploading on subsequent sends. The media-cache plugin can automate this.
See Also
- sendPhoto — Send a single photo
- sendVideo — Send a single video
- sendDocument — Send a single document
- sendPaidMedia — Send a paid photo/video album requiring Stars
- InputMediaPhoto — The InputMedia type for photos
- InputMediaVideo — The InputMedia type for videos
- Files & MediaUpload — How to upload files in GramIO
- auto-retry plugin — Handle rate limits automatically
- media-cache plugin — Cache
file_idvalues automatically