Skip to content

Telegram API

Schedule and automate Telegram channel and group posts with Zernio API - Text, images, videos, media albums, silent messages, and bot management

Quick Reference

PropertyValue
Text limit4,096 characters (text messages)
Caption limit1,024 characters (media captions)
Images per album10
Videos per album10
Mixed mediaYes (images + videos in same album)
Image formatsJPEG, PNG, GIF, WebP
Image max size10 MB (auto-compressed)
Video formatsMP4, MOV
Video max size50 MB (auto-compressed)
SchedulingYes
Inbox (DMs)Yes (full featured)
Inbox (Comments)No
AnalyticsNo (Telegram limitation)

Before You Start

Telegram requires @ZernioScheduleBot to be an administrator in your channel or group with post permissions. This is the number one setup failure. Also: posts in groups show as sent by "ZernioScheduleBot", not by you. In channels, posts show as the channel name.

Additional requirements:

  • Bot-based integration (not OAuth). Uses @ZernioScheduleBot
  • The bot must be added as an admin with post permissions before you can publish
  • Channels: posts appear as the channel name and logo (correct behavior)
  • Groups: posts appear as "ZernioScheduleBot" (cannot be changed)

Quick Start

Post to a Telegram channel or group:

typescript
const { post } = await zernio.posts.createPost({
  content: 'Hello from Zernio API! Check out our latest update.',
  platforms: [
    { platform: 'telegram', accountId: 'YOUR_ACCOUNT_ID' }
  ],
  publishNow: true
});
console.log('Posted to Telegram!', post._id);
python
result = client.posts.create_post(
    content="Hello from Zernio API! Check out our latest update.",
    platforms=[
        {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    publish_now=True
)
post = result.post
print(f"Posted to Telegram! {post['_id']}")
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hello from Zernio API! Check out our latest update.",
    "platforms": [
      {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Content Types

Text Message

Send a formatted text message with HTML, Markdown, or MarkdownV2:

typescript
const { post } = await zernio.posts.createPost({
  content: '<b>Important Update!</b>\n\nCheck out our <a href="https://example.com">new feature</a>.',
  platforms: [{
    platform: 'telegram',
    accountId: 'YOUR_ACCOUNT_ID',
    platformSpecificData: {
      parseMode: 'HTML'
    }
  }],
  publishNow: true
});
python
result = client.posts.create_post(
    content='<b>Important Update!</b>\n\nCheck out our <a href="https://example.com">new feature</a>.',
    platforms=[{
        "platform": "telegram",
        "accountId": "YOUR_ACCOUNT_ID",
        "platformSpecificData": {
            "parseMode": "HTML"
        }
    }],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "<b>Important Update!</b>\n\nCheck out our <a href=\"https://example.com\">new feature</a>.",
    "platforms": [{
      "platform": "telegram",
      "accountId": "YOUR_ACCOUNT_ID",
      "platformSpecificData": {
        "parseMode": "HTML"
      }
    }],
    "publishNow": true
  }'

Photo Message

Send a single image with an optional caption:

typescript
const { post } = await zernio.posts.createPost({
  content: 'Check out this photo!',
  mediaItems: [
    { type: 'image', url: 'https://example.com/image.jpg' }
  ],
  platforms: [
    { platform: 'telegram', accountId: 'YOUR_ACCOUNT_ID' }
  ],
  publishNow: true
});
python
result = client.posts.create_post(
    content="Check out this photo!",
    media_items=[
        {"type": "image", "url": "https://example.com/image.jpg"}
    ],
    platforms=[
        {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Check out this photo!",
    "mediaItems": [
      {"type": "image", "url": "https://example.com/image.jpg"}
    ],
    "platforms": [
      {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Video Message

Send a single video with an optional caption:

typescript
const { post } = await zernio.posts.createPost({
  content: 'Watch our latest video!',
  mediaItems: [
    { type: 'video', url: 'https://example.com/video.mp4' }
  ],
  platforms: [
    { platform: 'telegram', accountId: 'YOUR_ACCOUNT_ID' }
  ],
  publishNow: true
});
python
result = client.posts.create_post(
    content="Watch our latest video!",
    media_items=[
        {"type": "video", "url": "https://example.com/video.mp4"}
    ],
    platforms=[
        {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Watch our latest video!",
    "mediaItems": [
      {"type": "video", "url": "https://example.com/video.mp4"}
    ],
    "platforms": [
      {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Document Message

Send any file type as a document:

typescript
const { post } = await zernio.posts.createPost({
  content: 'Here is the report.',
  mediaItems: [
    { type: 'document', url: 'https://example.com/report.pdf' }
  ],
  platforms: [
    { platform: 'telegram', accountId: 'YOUR_ACCOUNT_ID' }
  ],
  publishNow: true
});
python
result = client.posts.create_post(
    content="Here is the report.",
    media_items=[
        {"type": "document", "url": "https://example.com/report.pdf"}
    ],
    platforms=[
        {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Here is the report.",
    "mediaItems": [
      {"type": "document", "url": "https://example.com/report.pdf"}
    ],
    "platforms": [
      {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Media Album

Send up to 10 items in a single album. Images and videos can be mixed:

typescript
const { post } = await zernio.posts.createPost({
  content: 'Our latest product gallery!',
  mediaItems: [
    { type: 'image', url: 'https://example.com/image1.jpg' },
    { type: 'image', url: 'https://example.com/image2.jpg' },
    { type: 'video', url: 'https://example.com/video.mp4' },
    { type: 'image', url: 'https://example.com/image3.jpg' }
  ],
  platforms: [
    { platform: 'telegram', accountId: 'YOUR_ACCOUNT_ID' }
  ],
  publishNow: true
});
python
result = client.posts.create_post(
    content="Our latest product gallery!",
    media_items=[
        {"type": "image", "url": "https://example.com/image1.jpg"},
        {"type": "image", "url": "https://example.com/image2.jpg"},
        {"type": "video", "url": "https://example.com/video.mp4"},
        {"type": "image", "url": "https://example.com/image3.jpg"}
    ],
    platforms=[
        {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Our latest product gallery!",
    "mediaItems": [
      {"type": "image", "url": "https://example.com/image1.jpg"},
      {"type": "image", "url": "https://example.com/image2.jpg"},
      {"type": "video", "url": "https://example.com/video.mp4"},
      {"type": "image", "url": "https://example.com/image3.jpg"}
    ],
    "platforms": [
      {"platform": "telegram", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Media Requirements

Images

PropertyRequirement
Max per album10
FormatsJPEG, PNG, GIF, WebP
Max file size10 MB (auto-compressed)
Max resolution10,000 x 10,000 px

Videos

PropertyRequirement
Max per album10
FormatsMP4, MOV
Max file size50 MB (auto-compressed)
Max durationNo limit
CodecH.264 recommended

Platform-Specific Fields

All fields go inside platformSpecificData for the Telegram platform entry:

FieldTypeDefaultDescription
parseModestring"HTML"Text formatting mode: "HTML", "Markdown", or "MarkdownV2"
disableWebPagePreviewbooleanfalsePrevents link preview generation for URLs in the message
disableNotificationbooleanfalseSends the message silently (recipients get no notification sound)
protectContentbooleanfalsePrevents the message from being forwarded or saved by recipients
typescript
const { post } = await zernio.posts.createPost({
  content: '<b>Important Update!</b>\n\nCheck out our <a href="https://example.com">new feature</a>.',
  platforms: [{
    platform: 'telegram',
    accountId: 'YOUR_ACCOUNT_ID',
    platformSpecificData: {
      parseMode: 'HTML',
      disableWebPagePreview: false,
      disableNotification: true,
      protectContent: true
    }
  }],
  publishNow: true
});
python
result = client.posts.create_post(
    content='<b>Important Update!</b>\n\nCheck out our <a href="https://example.com">new feature</a>.',
    platforms=[{
        "platform": "telegram",
        "accountId": "YOUR_ACCOUNT_ID",
        "platformSpecificData": {
            "parseMode": "HTML",
            "disableWebPagePreview": False,
            "disableNotification": True,
            "protectContent": True
        }
    }],
    publish_now=True
)
bash
curl -X POST https://zernio.com/api/v1/posts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "<b>Important Update!</b>\n\nCheck out our <a href=\"https://example.com\">new feature</a>.",
    "platforms": [{
      "platform": "telegram",
      "accountId": "YOUR_ACCOUNT_ID",
      "platformSpecificData": {
        "parseMode": "HTML",
        "disableWebPagePreview": false,
        "disableNotification": true,
        "protectContent": true
      }
    }],
    "publishNow": true
  }'

Connection

Zernio provides a managed bot (@ZernioScheduleBot) for Telegram integration. No need to create your own bot -- just add Zernio's bot to your channel or group.

This is the easiest way to connect a Telegram channel or group.

Step 1: Generate an Access Code

typescript
const { code, botUsername, instructions } = await zernio.connect.getConnectUrl({
  platform: 'telegram',
  profileId: 'YOUR_PROFILE_ID'
});
console.log(`Your access code: ${code}`);
console.log(`Bot to message: @${botUsername}`);
python
result = client.connect.get_connect_url(
    platform="telegram",
    profile_id="YOUR_PROFILE_ID"
)
print(f"Your access code: {result.code}")
print(f"Bot to message: @{result.bot_username}")
bash
curl -X GET "https://zernio.com/api/v1/connect/telegram?profileId=YOUR_PROFILE_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "code": "ZERNIO-ABC123",
  "expiresAt": "2025-01-15T12:30:00.000Z",
  "expiresIn": 900,
  "botUsername": "ZernioScheduleBot",
  "instructions": [
    "1. Add @ZernioScheduleBot as an administrator in your channel/group",
    "2. Open a private chat with @ZernioScheduleBot",
    "3. Send: ZERNIO-ABC123 @yourchannel (replace @yourchannel with your channel username)",
    "4. Wait for confirmation - the connection will appear in your dashboard",
    "Tip: If your channel has no public username, forward a message from it along with the code"
  ]
}

Step 2: Add the Bot to Your Channel/Group

For Channels:

  1. Go to your channel settings
  2. Add @ZernioScheduleBot as an Administrator
  3. Grant permission to Post Messages

For Groups:

  1. Add @ZernioScheduleBot to the group
  2. Make the bot an Administrator (required for posting)

Step 3: Send the Access Code

  1. Open a private chat with @ZernioScheduleBot
  2. Send your access code with your channel: ZERNIO-ABC123 @yourchannel
  3. For private channels without a username, forward any message from the channel to the bot along with the code

Step 4: Poll for Connection Status

bash
curl -X PATCH "https://zernio.com/api/v1/connect/telegram?code=ZERNIO-ABC123" \
  -H "Authorization: Bearer YOUR_API_KEY"

The published Node and Python SDKs auto-generate signatures for these Telegram connect-status endpoints that don't match the actual request shape (the endpoint takes code as a query param). Until the next regen catches up, hit the endpoint directly via fetch / requests.

Status Response (Pending):

json
{
  "status": "pending",
  "expiresAt": "2025-01-15T12:30:00.000Z",
  "expiresIn": 542
}

Status Response (Connected):

json
{
  "status": "connected",
  "chatId": "-1001234567890",
  "chatTitle": "My Channel",
  "chatType": "channel",
  "account": {
    "_id": "64e1f0a9e2b5af0012ab34cd",
    "platform": "telegram",
    "username": "mychannel",
    "displayName": "My Channel"
  }
}

Option 2: Direct Connection (Power Users)

If you already know your chat ID and the Zernio bot is already an administrator in your channel/group:

The published Node and Python SDKs auto-generate signatures for these Telegram connect endpoints that don't match the actual request shape. Until the next regen catches up, hit the endpoint directly.

bash
curl -X POST https://zernio.com/api/v1/connect/telegram \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "YOUR_PROFILE_ID",
    "chatId": "-1001234567890"
  }'

Response:

json
{
  "message": "Telegram channel connected successfully",
  "account": {
    "_id": "64e1f0a9e2b5af0012ab34cd",
    "platform": "telegram",
    "username": "mychannel",
    "displayName": "My Channel",
    "isActive": true,
    "chatType": "channel"
  }
}

Finding Your Chat ID

For Public Channels:

  • Use the channel username with @ prefix: @mychannel

For Private Channels:

  • Forward a message from the channel to @userinfobot
  • The bot will reply with the numeric chat ID (starts with -100)

For Groups:

  • Add @userinfobot to your group temporarily
  • It will display the group's chat ID (negative number)
  • Remove the bot after getting the ID

Text Formatting

HTML Mode (Default)

html
<b>bold</b>
<i>italic</i>
<u>underline</u>
<s>strikethrough</s>
<code>inline code</code>
<pre>code block</pre>
<a href="https://example.com">link</a>

Markdown Mode

markdown
*bold*
_italic_
[link](https://example.com)
`inline code`

MarkdownV2 Mode

markdown
*bold*
_italic_
__underline__
~strikethrough~
||spoiler||
`inline code`

> Note: MarkdownV2 requires escaping special characters: _, *, [, ], (, ), ~, `, &gt;, #, +, -, =, |, {, }, ., !

Channel vs Group Posts

DestinationAuthor Display
ChannelChannel name and logo
GroupBot name (ZernioScheduleBot)

When posting to a channel, the post appears as if sent by the channel itself. When posting to a group, the post shows as sent by the Zernio bot.

Analytics

Telegram does not provide analytics through its Bot API. View counts for channel posts are only visible within the Telegram app. For messaging metrics, use Telegram's native channel statistics (available for channels with 500+ subscribers).

What You Can't Do

  • Create polls or quizzes via Zernio
  • Schedule messages natively through Telegram (use Zernio scheduling instead)
  • Manage channel administrators
  • See message analytics (Telegram platform limitation)
  • Pin messages
  • Create channel invite links

Common Errors

ErrorCauseFix
"Bot is not a member of the channel"@ZernioScheduleBot is not added to the channel/group or is not an adminAdd the bot as an administrator and grant post permissions
"Message is too long"Text exceeds 4,096 characters or caption exceeds 1,024 charactersShorten the content or split into multiple messages
"Wrong file identifier/HTTP URL specified"Media URL is inaccessible, uses HTTP, or redirectsUse a direct HTTPS URL that is publicly accessible with no redirects
"Can't parse entities"Invalid HTML/Markdown syntax or unescaped special charactersCheck tag closure in HTML mode; escape special characters in MarkdownV2
Media not displayingUnsupported format or file exceeds size limitVerify format is supported and size is within limits (10 MB images, 50 MB videos)
"Access code expired"Code was not used within 15 minutesGenerate a new access code with GET /v1/connect/telegram

Inbox

> Included — Inbox (DMs, comments, reviews) is bundled with every paid account on the Usage plan.

Telegram supports DMs with full attachment support.

Direct Messages

FeatureSupported
List conversationsYes
Fetch messagesYes
Send text messagesYes
Send attachmentsYes (images, videos, documents)
Edit messagesYes (text and inline keyboard)
Inline keyboardsYes (buttons with callback data or URLs)
Reply keyboardsYes (one-time custom keyboards)
Reply to messageYes (via replyTo message ID)
Archive/unarchiveYes

Attachment Support

TypeSupportedMax Size
ImagesYes10 MB
VideosYes50 MB
DocumentsYes50 MB

Bot Commands

Manage the bot command menu shown in Telegram chats. Commands appear in the "/" menu when users interact with the bot.

See Account Settings for the GET/PUT/DELETE /v1/accounts/{accountId}/telegram-commands endpoints.

Webhooks

EventWhen it fires
message.receivedNew incoming message to the bot
message.sentOutgoing message is sent
message.editedThe user edits a previously-sent message (also fires for edited_channel_post in channels where the bot is admin)

Messages are stored locally via webhooks. See the Webhooks page for payload details.

Note: Telegram's Bot API does not expose deletion or read receipt events for regular bot chats. Delivery and read tracking is available only through the separate Telegram Business integration, which Zernio does not currently use.

Notes

  • Bot-based - Uses bot tokens, not OAuth
  • Messages are stored locally when received via webhooks
  • Incoming callback data from inline keyboard taps is available in message metadata.callbackData

See Messages API Reference for endpoint details.

  • Connect Telegram Account - Access code connection flow
  • Create Post - Post creation and scheduling
  • Upload Media - Image and video uploads
  • Messages - Inbox conversations and DMs
  • Account Settings - Bot commands configuration