Telegram Channel Scraper — Posts API, Views & Media | $0.50/1k avatar

Telegram Channel Scraper — Posts API, Views & Media | $0.50/1k

Pricing

from $0.50 / 1,000 results

Go to Apify Store
Telegram Channel Scraper — Posts API, Views & Media | $0.50/1k

Telegram Channel Scraper — Posts API, Views & Media | $0.50/1k

Scrape public Telegram channels without login: posts with text, views, photos, videos, files, link previews, reactions and forwards, plus exact subscriber counts. Date range and keyword search. Export JSON, CSV or Excel.

Pricing

from $0.50 / 1,000 results

Rating

0.0

(0)

Developer

Raffy

Raffy

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

What does Telegram Channel Scraper do?

Telegram Channel Scraper reads public Telegram channels and returns their posts (text, views, photos, videos, files, link previews, polls, reactions, forwards, replies, hashtags and links) plus one channel profile row per channel (title, description, exact subscriber count, photo, verified badge). It works as a simple Telegram channel API: give it channel usernames or t.me links and get clean JSON, CSV or Excel back in seconds. No Telegram account, no phone number, no API key, no browser.

Typical use cases:

  • 📰 News and media monitoring: follow news, crypto, finance or politics channels in any language and pipe every new post into a spreadsheet, a database or an AI summariser.
  • 📊 Channel analytics and benchmarking: compare subscribers, views, reactions and posting frequency across channels, or track them over time with a schedule.
  • 🔎 Research and archiving: pull a channel's history for a date range, or search inside channels for a keyword across their whole history.
  • 🤖 AI agents and RAG: give an agent a list of channels and get structured, self-describing rows it can reason over.

It reads only what Telegram shows logged-out on its public web preview (t.me/s/<channel>). It does not log in, join groups, or collect member lists, user profiles or phone numbers.

Why use this Telegram scraper?

  • Fast. Pure HTTP, about 20 posts per request: 1,000 posts from one channel took 37 seconds and 20 channels × 60 posts took 9 seconds on Apify (real runs, 2026-09-28).
  • Cheap. $0.50 per 1,000 results, Apify platform usage included.
  • Deep history and date ranges. Pages back as far as you ask. With Posted before it jumps straight to that date by binary search instead of reading every newer page, so "December 2023 on a channel with 400,000 posts" takes about 15 requests.
  • Keyword search inside channels. Uses Telegram's own in-channel search, so a keyword finds matching posts across the channel's whole history, not just the newest pages.
  • Exact subscriber counts. The channel row reads the channel's profile card, which shows the exact number (10,608,845), not the rounded header figure (10.6M).
  • Honest results. Every row carries a status (ok, not_found, error). A group, a personal account, a bot or a private invite link comes back as one free not_found row that says why. You are billed only for ok rows.
  • Works from Apify's datacenter. In our test runs on Apify (2026-09-28) every one of 428 Telegram page requests succeeded on the first attempt, across 23 public channels in Russian, Arabic, Ukrainian and English, with no proxy.

What data can Telegram Channel Scraper extract?

Two row types share one dataset; type tells them apart.

Post rows (type = post)

FieldTypeDescription
channelstringChannel username without @ (the channel's primary username)
channelTitlestringChannel display name
postIdintegerPost number in the channel; newer posts have higher numbers
urlstringLink to the post, https://t.me/<channel>/<postId>
postedAtstringPublication time, ISO 8601 UTC
textstringPost text or caption as plain text (line breaks and emoji kept)
textHtmlstringOptional (includeTextHtml): the text with bold, italic, code, quote, spoiler and link formatting
viewsintegerView count as Telegram shows it ("18.9M" becomes 18900000)
reactionsarray{ emoji, count } per reaction; custom emoji carry customEmojiId, paid Star reactions paid: true
reactionsCountintegerSum of all reactions
photosarrayPhoto URLs (albums give several)
videosarray{ thumbnailUrl, duration, durationSeconds, videoUrl } (videoUrl only for small videos Telegram serves in the preview)
documentsarrayAttached files and audio: { name, details, kind }
linkPreviewobjectThe link card: { url, siteName, title, description, imageUrl }
pollobject{ question, type, options: [{ text, percent }] }
hashtagsarrayHashtags in the text
mentionsarray@usernames linked in the text (usually other channels)
linksarrayWeb links in the text
isForwardedbooleanThe post was forwarded from somewhere else
forwardedFromobject{ channel, title, postUrl } when the source is a public channel post
replyToPostIdintegerThe earlier post in the same channel this post replies to
isEditedbooleanTelegram marks the post as edited
searchKeywordstringWhich of your keywords found the post

Channel rows (type = channel, one per channel when Add one channel profile row is on)

FieldTypeDescription
channel, channelTitle, urlstringUsername, display name and https://t.me/<channel>
subscribersintegerExact subscriber count
descriptionstringChannel description (bio)
photoUrlstringProfile photo
verifiedbooleanTelegram's verified badge
photosCount, videosCount, filesCount, linksCountintegerMedia the channel has posted, as Telegram counts them

Every row also has status, error and scrapedAt.

Result status (tri-state output)

statusMeaningBilled?
okA post or a channel profile was extracted.Yes
not_foundThe name is not a public channel (a group, a person, a bot, a private invite link, a name nobody owns, or a channel whose preview is switched off), or no post matched your date range or keyword. error says which.No
errorTelegram could not be read after retries (network error, rate limit or a layout change). error says why.No

How to use the Telegram Channel Scraper

  1. Open the Actor in Apify Console and click Try for free.
  2. Put channels into Telegram channels, one per line: durov, @bbcrussian or https://t.me/s/tass_agency all work.
  3. Choose Posts per channel (20 is one page). Optionally set Posted on or after / Posted before and Keywords.
  4. Click Start. The default input (2 channels, 20 posts each) finishes in about 10 seconds.
  5. Open the Output tab (views: Overview, Media and links, Channel profiles) or Export as JSON, CSV, Excel, XML or HTML.

To automate it, use the API tab (Node.js, Python, curl) or add a Schedule: a daily run with Posted on or after = 1 day gives you each day's new posts.

How much does it cost to scrape Telegram channels?

This Actor uses pay-per-event pricing. Apify platform usage is included in these prices.

EventPrice
Actor start$0.005 per run
Result (status: ok row: a post or a channel profile)$0.0005 per result ($0.50 per 1,000)

Example: 1,000 posts in one run cost $0.505 ($0.50 for the rows plus $0.005 for the start). The default input (2 channels × 20 posts + 2 channel rows = 42 results) costs about $0.026. Rows with status not_found or error are never billed. Cap spending with Posts per channel, Maximum results and the run's Max total charge option; the Actor stops gracefully when your run's maximum charge is reached.

Input

See the Input tab for the full schema. The main options:

FieldTypeDefaultDescription
startUrlsarray of strings["durov", "telegram"]Channels: usernames, @names or t.me links
maxPostsPerChannelinteger20Newest posts per channel (after filters)
postedAfterstring-Only posts on or after: YYYY-MM-DD, ISO time, or 7 days
postedBeforestring-Only posts before this moment (the Actor jumps there directly)
keywordsarray of strings-Search inside each channel with Telegram's own search
includeChannelInfobooleantrueAdd one channel profile row per channel
includeTextHtmlbooleanfalseAdd textHtml with basic formatting
maxItemsinteger1000Safety cap on rows for the whole run
proxyConfigurationobjectoffNot needed; datacenter proxy only if you hit HTTP 429

API callers may also send the channel list as channels.

Example input (news channels, one week, two keywords):

{
"startUrls": ["bbcrussian", "@tass_agency", "https://t.me/s/ajanews"],
"maxPostsPerChannel": 200,
"postedAfter": "7 days",
"keywords": ["Путин", "Iran"],
"includeChannelInfo": true
}

Output

You can download the dataset as JSON, HTML, CSV or Excel. Real rows from a run on Apify (2026-09-28), long URLs shortened with …:

[
{
"url": "https://t.me/durov",
"status": "ok",
"scrapedAt": "2026-09-27T23:43:28.543Z",
"type": "channel",
"channel": "durov",
"channelTitle": "Pavel Durov",
"description": "Founder of Telegram.",
"subscribers": 10608845,
"photoUrl": "https://cdn4.telesco.pe/file/OpC7B9qam6vvIGLzp…Wb0c5RZJMNAvo0zVC0LWKJJ68TA.jpg",
"verified": true,
"photosCount": 102,
"videosCount": 46,
"linksCount": 200
},
{
"url": "https://t.me/durov/548",
"status": "ok",
"scrapedAt": "2026-09-27T23:43:27.034Z",
"type": "post",
"channel": "durov",
"channelTitle": "Pavel Durov",
"postId": 548,
"postedAt": "2026-09-11T16:04:02Z",
"text": "🤝 Telegram has become the sponsor of Codeforces — the largest competitive programming platform in the world.\n\n ⚡CodeForces organizes over 100 coding contests every year and has 4 million contestants signed up.\n\n…",
"views": 1690000,
"isForwarded": false,
"photos": [],
"videos": [],
"documents": [],
"linkPreview": {
"url": "https://codeforces.com/blog/entry/156620",
"siteName": "Codeforces",
"title": "Telegram Returns as Title Sponsor of Codeforces!",
"description": "Hi, Codeforces!",
"imageUrl": "https://cdn4.telesco.pe/file/pMiBhAOwyapnw…rnP1Q.jpg"
},
"hashtags": [],
"mentions": [],
"links": ["https://codeforces.com/blog/entry/156620"],
"reactions": [
{ "emoji": "⭐", "paid": true, "count": 13600 },
{ "customEmojiId": "5399847211989246390", "count": 28700 },
{ "customEmojiId": "5936157098181135162", "count": 8260 },
{ "customEmojiId": "5373223594484587136", "count": 7760 }
],
"reactionsCount": 58320,
"isEdited": false
},
{
"url": "https://t.me/rt_russian",
"status": "not_found",
"error": "@rt_russian is a channel, but Telegram shows no public web preview for it (the owner switched it off, or it is restricted in the region the request came from). Only public channels whose preview opens at t.me/s/rt_russian are supported.",
"scrapedAt": "2026-09-27T23:43:28.187Z",
"type": "channel",
"channel": "rt_russian"
}
]

A missing field means Telegram did not show it for that post; it is never guessed.

Tips

  • Put many channels in one run instead of one run per channel; you pay the start fee once and channels are read in parallel.
  • For monitoring, schedule a run with Posted on or after = 1 day (or 6 hours) and a generous Posts per channel; paging stops as soon as it reaches older posts.
  • Media URLs point at Telegram's CDN and are signed; download files you need soon after the run.
  • If you read hundreds of channels at once and see HTTP 429 error rows, enable Apify Proxy (datacenter) in Proxy configuration.

Limitations

  • Public channels only. Telegram's web preview shows public channels; public groups, personal accounts, bots and private invite links return a free not_found row. Comments under posts and member lists are not shown there and are not collected.
  • Some channels switch the preview off or are restricted in some regions; those return not_found with that reason.
  • A username Telegram does not use for anything public can redirect to telegram.org. That drops the name from the answer, so the not_found row says what happened but cannot name the input; the other rows of the run show which input it was.
  • View counts and some media counters are rounded the way Telegram displays them (for example 18.9M). The channel's subscriber count is exact.
  • Stickers, voice messages, round videos and paid media show only what the preview shows (often a "view in Telegram" placeholder), so such posts may carry just their caption.
  • Service messages (channel created, title changed, pinned message) are skipped. Whether a post is currently pinned is not visible in the preview.
  • Keywords use Telegram's own search, which matches words (with its own stemming), so it can return posts where the word appears in a different form.
  • Results reflect the preview at the time of the run; if Telegram changes its layout, rows come back as error and the Actor is updated (report it in the Issues tab).

FAQ

Do I need a Telegram account, phone number or API key?

No. The Actor reads the public web preview at t.me/s/<channel>, the same page anyone can open in a browser without logging in.

Can it scrape Telegram groups, members or users?

No. Only public channels' broadcast posts. A group, a user or a bot returns one free not_found row saying so. The Actor never collects member lists, user profiles or phone numbers, and it does not output post author signatures; a forward is named only when its source is a public channel.

How far back can it go?

As far as the channel's history goes. Posts per channel sets how many; Posted before jumps straight to a date, and Posted on or after stops paging once posts get older than that date.

How do I track new posts every day?

Create a Schedule with Posted on or after = 1 day. Each run returns only posts from the last day, so you pay only for new posts.

Why is a channel not_found?

The error column explains it: the name is a group, a person or a bot, it is not taken, it is a private invite link, or the channel's owner switched the web preview off (or it is restricted in the region the request came from).

Can I use this Actor from an AI agent or MCP client?

Yes. It runs with no input at all (two sample channels), inputs are plain strings, and every row is self-describing (type, status, error).

How fast is it?

About 20 posts per request. On Apify, 1,000 posts from one channel took 37 seconds, three channels × 1,000 posts took 82 seconds, and 20 channels × 60 posts took 9 seconds.

This Actor extracts only what Telegram publishes on its public, logged-out channel preview. It does not log in, join chats or get around access controls, and it does not extract private user data such as member lists, user profiles, phone numbers or post author signatures. However, public posts can still contain personal data, for example names mentioned in a news story. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with Telegram's terms of service and applicable law when using the extracted data.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Telegram or its owners. Telegram is a trademark of its respective owner.