Shiba Bank

How to send a Telegram message with curl

How to send a Telegram message through the API with one curl request: sendMessage, chat_id, text, parse_mode, buttons, how to find a chat_id and what the 400, 403 and 429 errors mean.

Updated 2026-10-02 · 5 min read

You send a message through the Telegram API with the Bot API method sendMessage: it needs your bot's token, the recipient's chat_id and the text. From a command line it is one request: curl "https://api.telegram.org/bot<TOKEN>/sendMessage" --data-urlencode "chat_id=123456789" --data-urlencode "text=Hello". The reply is a JSON object with "ok": true and the sent message in result. The token comes from @BotFather — how to get it and keep it safe.

In the examples below <TOKEN> is a placeholder. Put your own token there, but never show it to anyone. The examples are written for bash and zsh.

What sendMessage needs

The request address is https://api.telegram.org/bot<TOKEN>/sendMessage. The method's parameters:

  • chat_id — required. The identifier of the chat, or the username of a channel in the format @channelusername.
  • text — required. The message text, 1 to 4096 characters after entities are parsed.
  • parse_mode — optional. The markup mode: HTML, MarkdownV2 or Markdown.
  • reply_markup — optional. Buttons under the message or a custom keyboard.
  • reply_parameters — reply to a specific message.
  • disable_notification — send silently.
  • link_preview_options — control link previews.

The method accepts both GET and POST. For text with spaces or non-Latin letters --data-urlencode is handier: curl encodes the value for you.

How to find a chat_id

As a rule a bot can't start a conversation: the person has to message it first, or add it to a group. So the order is:

  1. Open your bot in Telegram and send it any message, such as /start.
  2. Ask for updates: curl "https://api.telegram.org/bot<TOKEN>/getUpdates".
  3. In the reply find message, then chat, then the field id — that is your chat_id. For a public channel you can use its @username instead of a number.

getUpdates works only while the bot has no webhook set — see getUpdates and webhooks. A chat identifier is an integer that may not fit in 32 bits, so keep it in a 64-bit type in your code.

Request examples

A plain message: curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage" --data-urlencode "chat_id=123456789" --data-urlencode "text=Your order is ready"

With HTML markup: curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage" --data-urlencode "chat_id=123456789" --data-urlencode "parse_mode=HTML" --data-urlencode "text=<b>Your order</b> is ready"

In HTML mode, the characters <, > and & in ordinary text must be written as &lt;, &gt; and &amp;. In MarkdownV2 the special characters are escaped with a backslash.

A message with a link button, sent as JSON: curl -s -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" -H "Content-Type: application/json" -d '{"chat_id": 123456789, "text": "Open the site", "reply_markup": {"inline_keyboard": [ [{"text": "Go", "url": "https://example.com"}] ]}}'

A JSON body works for every method except file uploads. A button under a message has text and either a url or callback_data (1 to 64 bytes): pressing the second kind sends the bot an event.

Errors

A failed request returns "ok": false with an error_code and a description. The usual ones:

  • 401 Unauthorized. This usually means the token is wrong or has been replaced. Check it with getMe — how.
  • 400 Bad Request: chat not found. The chat doesn't exist or the bot doesn't know it: the user has never written to the bot, or chat_id has a typo.
  • 403 Forbidden: bot was blocked by the user. The person blocked the bot, so nothing can be delivered to them.
  • 400 about markup. Telegram couldn't parse the text: an HTML tag isn't closed, or <, > and & aren't escaped.
  • 429 Too Many Requests. Requests are too frequent. The reply has a retry_after field — how many seconds to wait before trying again.

The limits in Telegram's documentation: avoid sending more than one message per second to a single chat, a bot can send no more than 20 messages per minute to the same group, and a broadcast is limited to about 30 messages per second.

Tip

Don't write the token into scripts that end up in a repository: keep it in an environment variable or in a settings file outside the repository.

What next

To make the bot answer messages rather than only send them, set up receiving: getUpdates and webhooks. If your program needs to send users Stars or Premium, the Shiba Bank bot has an API for that — see the documentation.

Frequently asked questions

How do I send a message in Telegram through the API?

Call sendMessage with the bot's token, a chat_id and a text: curl "https://api.telegram.org/bot<TOKEN>/sendMessage" --data-urlencode "chat_id=<ID>" --data-urlencode "text=Hello".

How do I find the chat_id for sendMessage?

Send the bot any message and call getUpdates: the number is in message.chat.id. For a public channel you can use the channel's @username.

What does "chat not found" mean in Telegram?

The bot doesn't know that chat: either chat_id is wrong, or the person has never written to the bot. As a rule a bot can't start the conversation.

What does "bot was blocked by the user" mean?

It's a 403 error: the user blocked the bot, so you can't write to them.

Can I send a message from my own account instead of a bot?

Not with a token: requests made with a bot token are made by the bot, and the messages go out in its name.

How do I send a message to a channel through a bot?

Add the bot to the channel as an administrator and put the public channel's @username in chat_id.

Everything inside Telegram

Open the bot
QR code of the link to Telegram

Open in Telegram

Point your phone's camera at the code

Open in Telegram Desktop

The Shiba Bank window opens in Telegram.A chat with the bot @barboskich_stars_bot opens.Telegram will ask you to pick a group and give the bot admin rights.