Telegram
#Overview
Post to a Telegram channel through a bot you own. A connection is one channel, not one bot, so a bot that is admin of three channels is three connections.
Telegram posts are free to send. The channel counts as one connected account, like LinkedIn or Bluesky. See pricing.
#How to connect
- Message @BotFather and send
/newbotto get a bot token. - Add the bot to your channel as an admin with permission to post messages.
- In yeetpost, click Add connection, then Telegram, and paste the token and the channel.
The channel is either its public @handle or, for a private channel, the numeric id
starting with -100. All three things are checked when you connect: that the token is
real, that the chat is a channel rather than a group, and that the bot is an admin that can
post. A connection that exists is one that can post.
Your first Telegram connection gets the slug telegram. A second one gets a slug built
from the channel, so @shipnotes becomes shipnotes_telegram. GET /connections
describes it as Ship notes (Telegram).
The connection is identified by the chat id, so renaming the channel does not break it. A bot token never expires. If you revoke it in BotFather, connect again with the new one.
#What works
| Thing | Value |
|---|---|
| Text limit | 4096 characters |
| Text limit with an image | 1024 characters, because the text becomes the photo's caption |
| Images | Up to 5 per post |
| Image formats | image/png and image/jpeg only |
| Alt text | No, Telegram has no field for it, so it is dropped |
| Threads | Yes, up to 24 replies under the head message |
| First comment | No, LinkedIn only |
| Scheduling | Yes |
| Permalink | https://t.me/<handle>/<message id>, or https://t.me/c/<internal id>/<message id> for a private channel |
| Per-post fee | None |
An image turns the text into a caption, and a caption holds a quarter of what a message does. Text over 1024 characters with an image attached is refused rather than split into a photo plus a follow-up message nobody wrote. Send the long text on its own.
Alt text is dropped, silently and per connection. An image's description still travels to every other connection on the same post.
A broken thread is taken back. If Telegram refuses the third reply, the messages this
request already published are deleted, newest first, head included, and the item comes back
failed with Telegram's own error. If one of those deletes is refused too, what is still
up is a shorter thread and the item comes back sent with threadCount at the replies
that survived.
An album is never taken back. Several images go out as one album, which is several
messages a Telegram client shows as one post. Deleting a piece of it would leave the rest
standing with a gap, so when the head carries more than one image only the replies are
deleted. The album stays and the item comes back sent.
A private channel's permalink only opens for members of that channel.
#Refusals
Every one of these is a per-item refusal: the other connections on the same post still go out. See the errors reference for the full vocabulary.
| Code | Status | When |
|---|---|---|
invalid_request | 400 | Text over 4096 characters, or over 1024 with an image attached |
media_unsupported | 400 | The image is not a png or a jpeg |
shape_unsupported | 400 | A firstComment was given. Telegram has no first comment |
unauthorized | 401 | The bot token was revoked. Connect again with the new one |
platform_rejected | 422 | Telegram refused the message, for example the bot lost its admin rights |
internal_server_error | 500 | Our fault. Quote the req_id when you report it |
The image check runs before anything is sent, so a gif aimed at Telegram never reaches the channel and never blocks the other connections on the post.
#Post from curl
curl -X POST https://api.yeetpost.com/api/v2/posts \
-H "x-api-key: $YEETPOST_API_KEY" \
-H "content-type: application/json" \
-d '{
"text": "release 2.4.0 is out",
"connectionSlugs": ["telegram"],
"thread": ["changelog: https://yeetpost.com/changelog"]
}'#Post from Node
const response = await fetch("https://api.yeetpost.com/api/v2/posts", {
method: "POST",
headers: {
"x-api-key": process.env.YEETPOST_API_KEY,
"content-type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
text: "release 2.4.0 is out",
connectionSlugs: ["telegram"],
mediaIds: [process.env.SCREENSHOT_MEDIA_ID],
}),
});
const data = await response.json();
console.log(data.results[0].status, data.results[0].url);Remember the caption rule when you attach an image: with mediaIds set, the text has to
fit in 1024 characters.
#FAQ
#Can I post to a group or to a person?
No. A connection has to be a channel. A group or a private chat is refused when you try to connect it, because the permalink shapes and the posting rules are not the same.
#Why does my gif come back media_unsupported?
Telegram takes png and jpeg photos only. The check runs before the post is sent, so the same post still goes out to every other connection on it.
#Why did my alt text disappear?
Telegram has no field for a photo description. yeetpost drops it for this connection and still sends it to X, Bluesky, Mastodon and LinkedIn on the same post.
#How do I find a private channel's id?
It is the numeric id starting with -100. Most Telegram clients show it in the channel
info, and forwarding a message from the channel to a bot such as @userinfobot returns it.
#Does the bot need any other permission?
Only "post messages". yeetpost checks for exactly that when you connect and refuses the connection if the bot is not an admin that can post.