Platforms
Coming soon. Connect a Telegram channel or group with an access code, publish text, photos, videos, documents and albums, edit messages, and run bot DMs and commands.
Telegram accounts cannot be connected yet. GET /v1/connect/telegram and the Telegram access-code endpoints answer 403 with code: "feature_not_available". The rest of this page describes how Telegram will work once it opens, so you can plan for it. Watch the changelog for the launch.
Telegram publishing goes through a bot that is an administrator of your channel or group. There is no OAuth: you connect with a short access code, then publish with POST /v1/posts using the platform id telegram. The same bot handles direct messages in the Inbox and the "/" command menu.
#What you will be able to do
| Feature | Supported | Where |
|---|---|---|
| Text messages with HTML or Markdown formatting | Yes | Post types |
| Photo, video and document messages | Yes | Post types |
| Albums, images and videos mixed | Up to 10 items | Post types |
| Silent and protected messages | Yes | Platform fields |
| Scheduling | Yes | Scheduling |
| Edit a published message | Text or caption | Editing |
| DMs with the bot | Yes, with attachments and keyboards | Inbox |
| Bot command menu | Up to 100 commands | Bot commands |
| Comments, analytics | No | Not exposed by Telegram's Bot API |
#Connect
Not available yet: these steps return 403 feature_not_available until Telegram opens.
The bot must be an administrator of the channel or group, with permission to post messages, before you connect. A bot that is a plain member, or an admin without the post permission, is the most common setup failure: every post then fails with "Bot is not a member of the channel".
#With an access code
#Generate a code
Call Generate Telegram code with the profile that should own the account. The code is valid for 15 minutes.
curl "https://api.pozy.ai/v1/connect/telegram?profileId=66a1f0c2a4b9d3e8f1a2b3c4" \
-H "Authorization: Bearer $POZY_API_KEY"const res = await fetch("https://api.pozy.ai/v1/connect/telegram?profileId=66a1f0c2a4b9d3e8f1a2b3c4", {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.code, data.botUsername, data.instructions);import os, requests
resp = requests.get(
"https://api.pozy.ai/v1/connect/telegram",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
params={"profileId": "66a1f0c2a4b9d3e8f1a2b3c4"},
)
data = resp.json()
print(data["code"], data["botUsername"], data["instructions"])The response has code, expiresAt, expiresIn, botUsername and instructions. Show the user the bot's username and the instructions exactly as returned.
#The user sets up the bot
In Telegram, the user:
- Adds the bot (
botUsername) to the channel as an administrator with the Post Messages permission, or to the group as an administrator. - Opens a private chat with the bot.
- Sends the code followed by the channel username, for example
<code> @acmenews. For a private channel with no username, they forward any message from the channel to the bot together with the code.
#Poll until connected
Call Check Telegram status with the code every few seconds. status is pending until the bot receives the code, then connected with the new account, or expired after 15 minutes.
curl -X PATCH "https://api.pozy.ai/v1/connect/telegram?code=$CODE" \
-H "Authorization: Bearer $POZY_API_KEY"account._id in the connected response is the accountId for every call that follows. If the code expires, generate a new one.
#Directly with a chat id
If the bot is already an administrator and you know the chat id, skip the code and call Connect Telegram directly:
curl -X POST https://api.pozy.ai/v1/connect/telegram \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "chatId": "@acmenews", "profileId": "66a1f0c2a4b9d3e8f1a2b3c4" }'chatId is @username for a public channel. For a private channel or a group it is the numeric id; private channel ids start with -100, group ids are negative. One way to find a numeric id is to forward a message from the channel to an id-lookup bot in Telegram.
In a channel, posts appear under the channel's name and logo. In a group, they appear as sent by the bot.
#Post types
The media decides the message type:
mediaItems |
Result | Text used as |
|---|---|---|
| None | Text message | Message body, up to 4,096 characters |
| 1 image, video or document | Photo, video or document message | Caption, up to 1,024 characters |
| 2 to 10 items | Album (images and videos can mix) | Caption on the first item |
curl -X POST https://api.pozy.ai/v1/posts \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "<b>Release 2.4</b> is out.\nRead the notes: <a href=\"https://example.com/changelog\">changelog</a>",
"platforms": [{
"platform": "telegram",
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"platformSpecificData": { "parseMode": "HTML", "disableNotification": true }
}],
"publishNow": true
}'const res = await fetch("https://api.pozy.ai/v1/posts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.POZY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
content: '<b>Release 2.4</b> is out.\nRead the notes: <a href="https://example.com/changelog">changelog</a>',
platforms: [{
platform: "telegram",
accountId: "66b2e19d8c3f5a7e9d0b1c2d",
platformSpecificData: { parseMode: "HTML", disableNotification: true },
}],
publishNow: true,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.post.platforms[0].status);resp = requests.post(
"https://api.pozy.ai/v1/posts",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
json={
"content": '<b>Release 2.4</b> is out.\nRead the notes: <a href="https://example.com/changelog">changelog</a>',
"platforms": [{
"platform": "telegram",
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"platformSpecificData": {"parseMode": "HTML", "disableNotification": True},
}],
"publishNow": True,
},
)
print(resp.json()["post"]["platforms"][0]["status"])#Formatting
parseMode sets how Telegram reads content. HTML is the default.
parseMode |
Syntax |
|---|---|
HTML |
<b>, <i>, <u>, <s>, <code>, <pre>, <a href="..."> |
Markdown |
*bold*, _italic_, [link](https://...), backtick code |
MarkdownV2 |
Adds __underline__, ~strikethrough~ and ||spoiler||, but every _ * [ ] ( ) ~ > # + - = | { } . ! and backtick must be escaped with a backslash |
#Platform fields
| Field | Type | Notes |
|---|---|---|
parseMode |
HTML, Markdown or MarkdownV2 |
Default HTML |
disableWebPagePreview |
boolean | No link preview |
disableNotification |
boolean | Deliver silently |
protectContent |
boolean | Recipients cannot forward or save the message |
Edit the text or caption of a published message with Edit published post. The media cannot be changed.
#Media requirements
| Images | Requirement |
|---|---|
| Per album | Up to 10 |
| Formats | JPEG, PNG, GIF, WebP |
| Max size | 10 MB. Larger images are compressed |
| Max resolution | Width plus height up to 10,000 px. Larger images are downscaled |
| Videos | Requirement |
|---|---|
| Per album | Up to 10 |
| Formats | MP4, MOV (H.264 recommended) |
| Max size | 50 MB. Larger videos are compressed, up to a source size of 200 MB. Above that the file goes through untouched and Telegram refuses it |
| Duration | No limit |
URLs must be direct HTTPS links with no redirects. Telegram rejects HTTP and redirecting links with "Wrong file identifier/HTTP URL specified". Media gives you URLs that qualify.
#Limits
| Limit | Value |
|---|---|
| Text message | 4,096 characters |
| Caption | 1,024 characters |
| Album | 10 items |
| Bot commands | 100, names up to 32 characters (a-z, 0-9, _, no slash), descriptions up to 256 |
#Analytics
Telegram's Bot API exposes no view or engagement counts, so Telegram has no analytics in Pozy.
#Inbox
People who message the bot show up in the Inbox.
| Feature | Supported |
|---|---|
| List and read conversations | Yes |
| Send text | Yes |
| Send images, videos, documents | Yes. Images up to 10 MB, videos and documents up to 50 MB |
| Edit sent messages | Text and inline keyboard |
| Inline keyboards | Buttons with callback data or URLs |
| Reply keyboards | One-time custom keyboards |
| Reply to a specific message | replyTo with the message id |
| Archive and unarchive | Yes |
| Read receipts, deletions | No. The Bot API does not report them |
When someone taps an inline keyboard button, the callback data arrives on the incoming message in metadata.callbackData. Reactions arrive as reaction.received when the bot is an admin of the chat; reactions in private chats are not delivered.
#Bot commands
Bot commands are the entries in the "/" menu people see when they chat with the bot. Manage them with Get, Set and Delete TG bot commands.
curl -X PUT https://api.pozy.ai/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/telegram-commands \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "commands": [{ "command": "help", "description": "How to reach support" }, { "command": "status", "description": "Check your order status" }] }'See Conversation starters for menus and starters on other channels.
#Errors you may see
| Error | Cause | Fix |
|---|---|---|
| "Bot is not a member of the channel" | The bot is not an admin, or lacks the post permission | Make it an administrator with Post Messages, then retry |
expired on the status check |
The code was not used within 15 minutes | Generate a new code |
| "Wrong file identifier/HTTP URL specified" | Media URL is HTTP, redirects or is not public | Use a direct HTTPS URL or upload through Media |
| Message too long | Text over 4,096 or caption over 1,024 characters | Shorten it, or send the text as its own message |
| Formatting error | Unescaped characters in MarkdownV2, or broken HTML |
Escape the characters, or switch to HTML |
Errors covers the error format.
#Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/connect/telegram |
Generate Telegram code (not available yet) |
PATCH /v1/connect/telegram |
Check Telegram status (not available yet) |
POST /v1/connect/telegram |
Connect Telegram directly (not available yet) |
GET /v1/accounts/{accountId}/telegram-commands |
Get TG bot commands |
PUT /v1/accounts/{accountId}/telegram-commands |
Set TG bot commands |
DELETE /v1/accounts/{accountId}/telegram-commands |
Delete TG bot commands |
POST /v1/posts |
Create post |
POST /v1/posts/{postId}/edit |
Edit published post |
GET /v1/inbox/conversations |
List conversations |
POST /v1/inbox/conversations/{conversationId}/messages |
Send message |
#Webhook events
| Event | When it fires |
|---|---|
post.published |
Post published. |
post.failed |
Post failed. |
message.received |
Message received. |
message.sent |
Message sent. |
message.edited |
Message edited. |
reaction.received |
Reaction received. |