Skip to content

forwardMessages

Use this method to forward multiple messages of any kind. If some of the specified messages can't be found or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. Album grouping is kept for forwarded messages. On success, an array of MessageId of the sent messages is returned.

Parameters

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 forwarded; required if the messages are forwarded to a direct messages chat
from_chat_idIntegerStringRequired
Unique identifier for the chat where the original messages were sent (or channel username in the format @channelusername)
message_idsInteger[]Required
A JSON-serialized list of 1-100 identifiers of messages in the chat from\chat\id to forward. The identifiers must be specified in a strictly increasing order.
disable_notificationBooleanOptional
Sends the messages silently. Users will receive a notification with no sound.
protect_contentBooleanOptional
Protects the contents of the forwarded messages from forwarding and saving

Returns

On success, an array of MessageId objects is returned.

GramIO Usage

ts
// Forward a batch of messages from one chat to another
const 
forwarded
= await
bot
.
api
.
forwardMessages
({
chat_id
: -1009876543210, // destination
from_chat_id
: "@sourcechannel",
message_ids
: [101, 102, 103, 104, 105],
});
console
.
log
(`Forwarded ${
forwarded
.
length
} messages`);
ts
// Forward an album — grouping is automatically preserved
await 
bot
.
api
.
forwardMessages
({
chat_id
: -1001234567890,
from_chat_id
: -1009876543210,
message_ids
: [200, 201, 202], // album message IDs in order
});
ts
// Bulk-forward silently with protected content
await 
bot
.
api
.
forwardMessages
({
chat_id
: -1001234567890,
from_chat_id
: "@newsarchive",
message_ids
: [300, 301, 302, 303],
disable_notification
: true,
protect_content
: true,
});
ts
// Forward the last 10 messages from a channel to a forum topic
const 
latestIds
= [990, 991, 992, 993, 994, 995, 996, 997, 998, 999];
await
bot
.
api
.
forwardMessages
({
chat_id
: -1001234567890, // forum supergroup
message_thread_id
: 12, // topic ID
from_chat_id
: "@mychannel",
message_ids
:
latestIds
, // already in increasing order
});

Errors

CodeErrorCause
400Bad Request: chat not foundTarget chat_id is invalid or the bot is not a member — verify the bot was added to the destination
400Bad Request: MESSAGE_IDS_INVALIDmessage_ids are not in strictly increasing order — sort the array before passing it
400Bad Request: CHAT_FORWARD_RESTRICTThe source chat has disabled message forwarding — none of the messages can be forwarded from it
403Forbidden: bot is not a member of the channel chatBot is not in the target channel — add it 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

  • message_ids must be in strictly increasing order. Passing IDs out of order returns an error — always call .sort((a, b) => a - b) before passing a dynamically-built array.
  • Maximum 100 message IDs per call. For larger batches, chunk the array into groups of 100 and forward sequentially to avoid errors.
  • Unfound or unforwardable messages are silently skipped. The API doesn't throw an error if some IDs are invalid — it skips them and returns only the IDs of successfully forwarded messages. The returned array may be shorter than message_ids.
  • Album groupings are preserved. If the original messages form an album (multiple photos/videos sent together), the forwarded copies maintain the same grouping in the destination.
  • Returns MessageId[], not Message[]. The response only contains { message_id: number } objects — you don't get full message content back. Use forwardMessage (singular) if you need the full Message response.
  • Forward without attribution using copyMessages. Like forwardMessage, this method shows "Forwarded from" headers. Use copyMessages to copy content without attribution.
  • Use message_thread_id for forum supergroups. Without it, all messages land in the general/unthreaded area of the group.

See Also

  • forwardMessage — forward a single message (returns full Message object)
  • copyMessage — copy a single message without "Forwarded from" attribution
  • copyMessages — copy multiple messages without attribution
  • MessageId — the lightweight object returned in the response array
  • Message — the full message object (returned by single-message variants)
  • auto-retry plugin — automatic 429 retry handling