Skip to content

sendMessage

Use this method to send text messages. On success, the sent Message 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 message will be sent; required if the message is sent to a direct messages chat
textStringRequired✏️ FormattableminLen 1maxLen 4096
Text of the message to be sent, 1-4096 characters after entities parsing
parse_modeStringOptional
Mode for parsing entities in the message text. See formatting options for more details.
entitiesMessageEntity[]Optional
A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse\_mode
link_preview_optionsLinkPreviewOptionsOptional
Link preview generation options for the message
disable_notificationBooleanOptional
Sends the message silently. Users will receive a notification with no sound.
protect_contentBooleanOptional
Protects the contents of the sent message 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
suggested_post_parametersSuggestedPostParametersOptional
A JSON-serialized object containing the parameters of the suggested post to send; for direct messages chats only. If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
reply_parametersReplyParametersOptional
Description of the message to reply to
Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user

Returns

On success, the Message object is returned.

GramIO Usage

ts
// The simplest way — via context shorthand
bot
.
command
("start", (
ctx
) =>
ctx
.
send
("Hello! 👋"));
// reply() automatically sets reply_parameters to the current message
bot
.
on
("message", (
ctx
) =>
ctx
.
reply
("Got your message!"));
ts
// Direct API call
await 
bot
.
api
.
sendMessage
({
chat_id
: 123456789,
text
: "Hello from the API!",
});

Formatting with format

GramIO's format tagged template builds entities (not parse_mode) — type-safe, no escaping needed:

ts
bot
.
command
("info", (
ctx
) =>
ctx
.
send
(
format
`Hello, ${
bold
(
ctx
.
from
?.
firstName
?? "there")}!
Version: ${
code
("1.0.0")}
Docs: ${
link
("gramio.dev", "https://gramio.dev")}`,
), );

With inline keyboard

ts
bot
.
command
("menu", (
ctx
) =>
ctx
.
send
("Choose an option:", {
reply_markup
: new
InlineKeyboard
()
.
text
("Option A", "option_a")
.
text
("Option B", "option_b"),
}), );

Silent message

ts
bot
.
on
("message", (
ctx
) =>
ctx
.
send
("This arrives without a notification sound", {
disable_notification
: true,
}), );

Errors

CodeErrorCause
400Bad Request: chat not foundInvalid or inaccessible chat_id
400Bad Request: not enough rights to send text messagesBot lacks send permission in the chat
400Bad Request: TEXT_TOO_LONGtext exceeds 4096 characters
400Bad Request: can't parse entitiesMalformed entities array or bad parse_mode markup
400Bad Request: BUTTON_DATA_INVALIDCallback data in reply_markup is too long or malformed
403Forbidden: bot was blocked by the userUser has blocked the bot
429Too Many Requests: retry after NRate limit hit — check retry_after in the response

TIP

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

Tips & Gotchas

  • Text limit is 4096 characters. Use the Split plugin to split text while preserving formatting entities.
  • parse_mode and entities are mutually exclusive. GramIO's format helper produces entities, don't add parse_mode alongside it.
  • chat_id accepts @username strings for public groups/channels. Private chats require a numeric ID.
  • Forum topics: include message_thread_id matching the topic ID when sending to a supergroup forum.
  • Cross-chat replies: reply_parameters supports replying to messages in other chats.

See Also