Telegram API
Telegram is a bring-your-own-bot integration: each connected profile is one bot (created via @BotFather) that publishes to any channel where it’s an administrator. The same bot also powers two-way direct messages. See the Telegram BYO bot guide for setup.
Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.
Profiles and profile groups
Section titled “Profiles and profile groups”Every post targets one or more profiles. A profile is one connected account — for Telegram, a single bot that publishes to the channels where it’s an administrator. Reference one in a request by its id (the prof_abc123 in the examples below) or by the platform name "telegram", which selects the group’s Telegram profile (a group holds at most one profile per platform). List what’s connected with GET /api/profiles.
Profiles live in profile groups — containers that organize the accounts for one brand, client, or project. List groups with GET /api/profile_groups, and connect a new bot with the Initialize Connection endpoint (Telegram is bring-your-own-bot — see Connect Telegram).
Example: get profiles and profile groups
List the profiles you can post to — GET /api/profiles:
curl -X GET "https://api.postproxy.dev/api/profiles" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "prof_abc123", "name": "My Channel Bot", "platform": "telegram", "status": "active", "profile_group_id": "grp_xyz789", "expires_at": null, "post_count": 25, "avatar_url": "https://cdn.postproxy.dev/uploads/avatar_prof_abc123.jpg" } ]}List your profile groups — GET /api/profile_groups:
curl -X GET "https://api.postproxy.dev/api/profile_groups" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "grp_xyz789", "name": "Main Brand", "profiles_count": 5 }, { "id": "grp_def456", "name": "Client Project", "profiles_count": 3 } ]}At a glance
Section titled “At a glance”| Platform ID | telegram |
| Formats | post (channel post) |
| Character limit | 4,096 |
| Media | Optional |
| Placements | Channels — selected with chat_id (required) |
| Comments | No |
| Direct messages | Yes — text, media, edits, keyboards |
| Post chains | No |
Publishing
Section titled “Publishing”Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
chat_id | string | Yes | Destination channel/group — fetch from placements |
parse_mode | string | No | HTML or MarkdownV2. Omit for plain text |
disable_link_preview | boolean | No | Don’t render link previews |
disable_notification | boolean | No | Send silently (no notification sound) |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Image | 10 MB | jpg, png, webp, gif | 10 | — |
| Video | 50 MB | mp4, mov | 10 | — |
| Document | 50 MB | pdf, doc, docx, zip, mp3, wav | 1 | — |
- Text-only posts are allowed; media is optional.
- Images and video can be mixed in one media group.
# HTML-formatted channel post with an image, link preview offcurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "<b>New release</b> — read the changelog: https://example.com/changelog" }, "profiles": ["prof_abc123"], "media": ["https://example.com/image.jpg"], "platforms": { "telegram": { "chat_id": "-1001234567890", "parse_mode": "HTML", "disable_link_preview": true } } }'Placements
Section titled “Placements”Each placement is a channel the bot has been added to as administrator. List them with the placements endpoint — each placement’s id is the chat_id you pass when creating a post. chat_id is always required.
# List channels (placements) the bot can post tocurl "https://api.postproxy.dev/api/profiles/prof_abc123/placements" \ -H "Authorization: Bearer YOUR_API_KEY"The list is empty until the bot is added as a channel admin — Telegram pushes a my_chat_member event for each one, which Postproxy records. Poll the endpoint after connecting until the expected channels appear.
Comments
Section titled “Comments”Not supported through the API.
Direct messages
Section titled “Direct messages”Telegram DMs use the Bot API and offer richer features than the Meta networks in some areas. Supported through the Direct Messages API.
| Capability | Supported |
|---|---|
| Send / receive text | Yes |
| Attachments | Yes — photo, video, document, GIF, audio, voice, sticker |
| Edit outbound message | Yes |
| Reply threading | Yes — reply_to_external_id |
| Inline / reply keyboards | Yes — reply_markup |
| Reactions | No |
| Private reply to a comment | No |
| Delivery / read receipts | No |
| Inbound delivery | Webhook |
- Bot must be DM’d first. A bot can only message a user after that user has messaged it at least once (typically via
/start); otherwise the send returns422. - No messaging window — once a user has DM’d the bot, it can reply at any time.
- Callback queries from inline-button taps arrive as inbound messages (
platform_data.kind == "callback_query"); subscribe tomessage.receivedto react.
# Create or find a chat by the user's Telegram IDcurl -X POST "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "participant_external_id": "8000000000" }'# Send a text message with an inline keyboardcurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Pick an option:", "reply_markup": { "inline_keyboard": [[ { "text": "Plans", "callback_data": "plans" }, { "text": "Docs", "url": "https://postproxy.dev" } ]] } }'# Send a single media attachmentcurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "media": ["https://example.com/invoice.pdf"] }'# Edit a previously sent message (Telegram only)curl -X PATCH "https://api.postproxy.dev/api/messages/msg_abc123" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Updated: the sale ends tonight!" }'Postproxy records periodic stat snapshots you can pull as a timeseries; field names pass through from Telegram unchanged.
Profile stats
Section titled “Profile stats”Channel-level metrics, refreshed roughly every 23 hours and scoped per channel — pass the channel’s placement_id. See the Profile stats endpoint (GET /api/profiles/:id/stats).
Fields: followers_count, channel_title, channel_username
# Fetch the stats timeseries for one channel (placement_id is the chat_id)curl "https://api.postproxy.dev/api/profiles/prof_abc123/stats?placement_id=-1001234567890" \ -H "Authorization: Bearer YOUR_API_KEY"Post stats
Section titled “Post stats”Telegram does not report per-post stats.
Webhooks
Section titled “Webhooks”Subscribe with the Webhooks API:
curl -X POST "https://api.postproxy.dev/api/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/postproxy", "events": ["platform_post.published", "message.received", "message.edited"] }'Events relevant to Telegram:
| Event | When |
|---|---|
post.processed | A post is ready to publish |
platform_post.published | A post was published to the platform |
platform_post.failed | A post failed to publish (retries exhausted) |
platform_post.failed_waiting_for_retry | A publish attempt failed; will retry |
platform_post.insights | New analytics snapshot |
message.received / .sent | Inbound / outbound DM |
message.edited | A message was edited (inbound, or outbound via the API) |
message.failed_waiting_for_retry | An outbound DM failed; will retry |
message.failed | An outbound DM failed permanently |
profile.connected / .disconnected | Connection state changed |
profile.stats | New profile stats snapshot — fires once per channel placement |
media.failed | A media attachment failed to process |
Telegram does not expose delivery/read receipts, deletion events, or reactions.
- Create the bot with @BotFather and add it as an administrator to each channel — see the Telegram BYO bot guide.
chat_idis required on every post; one bot can publish to many channels.- Use
parse_mode(HTML/MarkdownV2) for rich formatting.