Telegram Channel Scraper: Posts, Comments & Media avatar

Telegram Channel Scraper: Posts, Comments & Media

Pricing

from $0.07 / 1,000 posts

Go to Apify Store
Telegram Channel Scraper: Posts, Comments & Media

Telegram Channel Scraper: Posts, Comments & Media

Scrape public Telegram channels without login: posts, views, reactions, media, links, comments, channel details. Search inside a channel and get only new posts for n8n or Make. Export to JSON, CSV or Excel.

Pricing

from $0.07 / 1,000 posts

Rating

0.0

(0)

Developer

Nice Dev

Nice Dev

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

3

Monthly active users

37 minutes ago

Last modified

Share

🔎 What is Telegram Channel Scraper?

Telegram Channel Scraper extracts posts from public Telegram channels (t.me): text, date, views, reactions, photos, videos, links, forwards, polls, plus the comments of each post and the details of the channel when you ask for them. It works as a Telegram API alternative for public channels: no account, no API key, no phone number. Run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type the channel names (durov, telegram), click Start, and download the posts in JSON, CSV or Excel. Add a keyword to search inside each channel, or tick Only new posts to get, at each scheduled run, only the posts published since the last one. Speed: about 1,000 posts of one channel in 4 minutes with the included proxy (several channels are read side by side), and about 5 times faster without a proxy.

📋 What data can you extract from Telegram?

One item per post, comment or channel, 56 fields:

CategoryWhat you get
📝 Posttext (plain, HTML and Markdown), publication date, edited mark, link, post number
👀 Reachviews, every reaction with its emoji and count, reactions paid with Stars
🖼️ Mediaphoto links, videos (thumbnail and duration), documents, audio files, polls, link cards, albums as one row
🔗 Links and mentionsevery link, hashtag, @mention, e-mail address and inline button of a post
↪️ Forwards and replieswhere a post was forwarded from, which message it replies to
📣 Channeltitle, username, numeric id, subscribers, verified badge, SCAM / FAKE label
💬 Commentsauthor, text, date, reactions and reply-to of each public comment, with the commented post
🧾 Channel detailsexact subscriber count, description, photo, counts of photos, videos, files and links, last post date
🔍 Searchthe keyword that found a post

Every field, with an example, is listed in the Output section below. Comments, channel details, e-mail addresses and saved media files are options: they are empty (or absent) unless you tick them.

✅ Why use Telegram Channel Scraper?

  • 🔍 Search inside the channels: the keyword is searched by Telegram in each channel, older posts included, not only the latest ones.
  • 🔔 Monitoring built in: tick Only new posts, schedule the Actor, and each run reads each channel only from the last post it delivered. Posts already delivered are not read again and not charged.
  • 💬 Comments without an account: the public comments of each post, one row per comment, up to 1,000 per post (author, text, date, reactions, the comment it answers).
  • 🧾 A row for every channel it cannot read: a closed, hidden, unknown or group channel gives a row that says why, never an empty run with no explanation.
  • 🗂️ Many channels in one run: up to 1 000 channels, with a cap per channel so that a big one cannot use up the whole budget.
  • 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy and JSON/CSV/Excel export via the Apify platform.

🚀 How to scrape Telegram channels

  1. Create a free Apify account.
  2. Open Telegram Channel Scraper and list the Channels (durov, @telegram, t.me/telegram, or a full link).
  3. Optional: a Search inside the channels keyword, a date range, the options you want (comments, channel details…).
  4. Set Max posts (100 by default, 0 = no limit), then click Start.
  5. Download the dataset in JSON, CSV, Excel or via API.

💰 How much does it cost to scrape Telegram?

This Actor uses pay per event pricing: you pay for each post saved, plus a small fee per run start. The options are charged only when you tick them: each comment, each channel detail row, each page of comments read, each e-mail address found and each media file saved. The exact prices are in the Pricing tab of the Actor. A run that saves nothing costs only the run start, plus the small fee for each post a filter drops if you use filters (see Pricing).

⚙️ Input

Channels, a cap, and nothing else:

{
"channels": ["durov", "telegram"],
"maxItems": 100
}

Search a keyword inside a channel, from a date:

{
"channels": ["durov"],
"query": "privacy",
"postedAfter": "2026-01-01",
"maxItems": 50
}

Monitoring: only the posts published since the last run, one memory per schedule:

{
"channels": ["durov", "telegram"],
"onlyNew": true,
"stateKey": "crypto-news",
"maxItems": 0
}

With links, comments and channel details:

{
"startUrls": [{ "url": "https://t.me/s/durov?q=privacy" }, { "url": "https://t.me/durov/427" }],
"includeChannelInfo": true,
"includeComments": true,
"maxCommentsPerPost": 20,
"maxItems": 20
}
FieldNotes
channelsPublic channels, in any form: durov, @durov, t.me/durov, https://t.me/s/durov. A link of a channel page keeps its keyword and its page (https://t.me/s/durov?q=privacy), as in startUrls. Max 1 000 channels. A public group gives its details only.
startUrlsChannel pages, searches inside a channel (https://t.me/s/durov?q=privacy), single posts (https://t.me/durov/427), or a channel read from a post number (https://t.me/s/durov?before=1000). Max 1 000 URLs.
query, searchQueriesKeyword searched inside each channel, as the channel's own search box does (privacy); searchQueries adds more keywords: channels × keywords = one search each (max 500 searches per run).
maxItems, maxItemsPerQueryPosts saved for the whole run (100 by default, 0 = unlimited) and for each channel and keyword (0 = no cap). Comments and channel rows are not counted.
includeChannelInfo, channelInfoOnlyOne row per channel with its exact subscribers, description and counts; the second one returns only these rows, no post. Paid options, off by default.
includeComments, maxCommentsPerPostThe most recent public comments of each post whose discussion is open, one row per comment (the newest ones, written in the order they were posted), up to 1,000 per post (Telegram shows 100 per page, more are loaded 50 at a time). Paid option, off by default.
includeEmails, downloadMediaE-mail addresses written in the posts and comments; photos and video thumbnails saved in the run's key-value store, their links in mediaFiles (they work as long as the run's storage is kept: the data retention of your plan). Paid options, off by default.
postedAfter, postedBeforePublication date range: 2026-09-01, or a period before now (7 days, 2 weeks, 30 days; via the API also 24 hours or a full ISO date-time). A channel is read from the newest post back and stops at the first one too old.
minViews, maxViews, minReactionsKeep the posts seen at least / at most so many times, or with at least so many reactions (0 = no bound).
mediaOnly, withTextOnly, withLinksOnly, includeForwarded, includeServiceMessagesKeep only the posts with any media (photo, video, file, audio, poll, sticker, location, or a post Telegram shows only in the app; use Only these media types to keep only some), with text, with a link; drop the forwarded posts; add the service messages (channel created, post pinned…).
mediaTypesKeep only the posts holding one of these media kinds (photo, video, document, audio, poll, sticker, location).
includeKeywords, excludeKeywordsKeep only the posts containing one of these words, or drop those that do (sale); case and accents ignored.
onlyNew, stateKey, resetStateMonitoring: each channel is read from the last post a previous run delivered under this memory key (crypto-news); resetState forgets the memory.
AdvancedproxyConfiguration (Apify proxy by default, included in the price; the residential proxy is not available; for a proxy country, US works), maxConcurrency, maxRequestsPerMinute, minRequestIntervalMs, maxRequestRetries, debugLog.

📦 Output

A post (shortened: the full row has 56 fields, the ones that do not apply are null or empty):

{
"type": "post",
"id": "durov/427",
"url": "https://t.me/durov/427",
"channel": "durov",
"channelTitle": "Pavel Durov",
"channelUrl": "https://t.me/durov",
"channelId": 1006503122,
"channelSubscribers": 10600000,
"channelVerified": true,
"channelLabels": [],
"postId": 427,
"publishedAt": "2026-09-30T14:02:11.000Z",
"edited": false,
"text": "Telegram now has 1 billion monthly users.",
"views": 18900000,
"reactions": [{ "emoji": "👍", "emojiId": null, "count": 15400, "paid": false }],
"reactionsCount": 52300,
"photos": ["https://cdn4.telesco.pe/file/abc.jpg"],
"mediaTypes": ["photo"],
"mediaCount": 1,
"links": ["https://telegram.org/blog"],
"hashtags": [],
"mentions": [],
"searchQuery": null,
"scrapedAt": "2026-10-07T12:00:00.000Z"
}

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. A comment row and a channel row have the same columns; type tells them apart.

All 56 fields

FieldsWhat you get
type, id, urlpost, comment or channel; a unique row id (durov/427); the public link
channel, channelTitle, channelUrl, channelIdusername, title, link, numeric id of the channel
channelSubscribers, channelVerified, channelLabelssubscribers (rounded by Telegram on a post, exact on a channel row, empty on a post pasted by its link), verified badge, SCAM / FAKE label
postId, publishedAt, edited, serviceActionpost number, ISO date, edited mark, what a service message says
text, textHtml, textMarkdownthe text, with its links and formatting
views, reactions, reactionsCount, paidStarsviews, each reaction with its count, their total, reactions paid with Stars
author, authorUrl, authorPhotosignature of a signed post, or the comment author and profile
forwardedFrom, replyToorigin of a forwarded post, the message a post or comment replies to
photos, videos, documents, audiomedia of the post
poll, linkPreview, buttonspoll question and results (no results on a post pasted by its link: its page shows none), link card, inline buttons
mediaTypes, mediaCount, albumPostIds, mediaFileskinds of media, how many, post numbers of an album, links of the files saved by Download media
links, hashtags, mentions, emailsevery link, hashtag, @mention and e-mail address of the text
commentsCount, relatedPostUrlcomments of a post (0 = discussion closed); for a comment, the post it belongs to
channelDescription, channelPhoto, isGroup, membersOnlinechannel and group rows: description, photo, group or channel, members online
photosCount, videosCount, filesCount, linksCountchannel rows: counts of what the channel published
webPreview, lastPostId, lastPostAtchannel rows: open, closed, not_found or group; the newest post and its date
searchQuery, scrapedAtthe keyword that found the post; ISO timestamp of the extraction

💡 Tips

How to get more results

Set maxItems to 0 and maxItemsPerQuery to the number of posts you want from each channel. A channel is read from its newest post back, page after page, with no limit on its history.

How to reduce costs

The price is per post, so the levers are maxItems, maxItemsPerQuery, the date range (postedAfter stops the reading of a channel at the first post too old), the filters, and onlyNew for recurring runs (you never pay twice for the same post). Leave the options you do not need unticked.

Search inside a channel

Fill query (and searchQueries for several keywords): Telegram searches each channel and the Actor reads only the matching posts, however old. Each post carries the keyword that found it in searchQuery.

Several searches in one run

Fill channels and searchQueries: the Actor runs one search per channel × keyword (3 keywords × 4 channels = 12 searches, up to 500 per run). A post found by several keywords is saved — and charged — once. Set maxItemsPerQuery to give every channel its own cap: without it the first channels can use up the whole maxItems.

Monitoring: only the new posts

Tick Only new posts (onlyNew) and schedule the Actor. The first run returns the posts allowed by the caps and dates; each later run reads each channel only from the last post it delivered, so a delivered post is never read, saved or charged twice. The memory lives in a named key-value store of your account (telegram-channel-scraper-seen, up to 150,000 posts per key) and is only updated with posts that really reached the dataset: a post you paste by its link, or a page you paste with ?before= / ?after=, does not move where its channel stopped, and a run that was stopped before its end (its maximum cost, a site that changed) leaves the memory under the first post it did not deliver, so the next run delivers it. A post that minViews or minReactions dropped while it was among the newest (its counters can still grow) is checked again by the next run, with the filter fee, until it passes or a newer post is delivered. Give each schedule its own stateKey.

Comments

Tick Comments to get the public comments of each post whose discussion is open. A channel without comments is detected after a few posts and no more comment pages are asked for it.

🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run. It returns one item per Telegram post. Actor id: nice_dev/telegram-channel-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/telegram-channel-scraper.

Smallest input, for a cheap first call:

{
"channels": ["durov"],
"maxItems": 10
}

Key output fields: channel, postId, publishedAt, text, views, reactionsCount, url.

Cost: see the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.

❓ FAQ

The Actor only reads what Telegram shows publicly to any anonymous visitor on the web: the posts of public channels. It logs in to nothing. Posts and comments can contain personal data, which is protected by GDPR: do not store it without a legitimate reason. You are responsible for using the data in compliance with Telegram's Terms of Service and applicable law. This Actor is not affiliated with Telegram.

Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). Some channels are hidden on the web in some countries: pick another proxy country for them — US works; a country where Apify Proxy has no IP fails the run, with a message that says so. About 5 times faster without a proxy (untick Apify Proxy), but then a request Telegram turns away is asked again from the same address only, after a pause. A request Telegram turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

Why does a channel give a row and no post?

A channel row with webPreview set to closed means the channel hides its posts on the web (some channels only show them in the app), not_found that the name belongs to nobody, group that it is a public group (its messages are not published on the web, only its details). These rows are free unless you ticked Channel details.

Is the data safe to open in Excel or to show on a web page?

Texts are the channels' own words, copied as they are. A text can begin with -, +, = or @: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. On a web page, escape the text: textHtml is Telegram's own markup and the Actor does not sanitize it.

Known limitations

  • Only public channels whose web preview is open give posts; public groups give their details only.
  • Views, reactions and subscribers of a post are rounded by Telegram (10.6M); the exact subscriber count is on the channel row.
  • Photo and video links of Telegram expire: tick Download media to save the files in the run's key-value store, where their links work as long as the run's storage is kept (the data retention of your plan): copy the files elsewhere to keep them for good.
  • onlyNew remembers post numbers, not their content: a post that was edited is not returned again.
  • Two runs sharing the same stateKey at the same time may both return the same new post.
  • Comments: the most recent ones of each post, up to Max comments per post (1,000 at most).

A run that reaches its timeout stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with onlyNew, remembered, and the run ends Succeeded with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

A run the platform stops without warning (out of memory)

  • Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the posts already saved are skipped: none is delivered or charged twice, and maxItems still counts them.
  • With onlyNew, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the posts it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the posts of its last 2 seconds once more.

Something doesn't work?

The last line of the log counts the posts saved, those filtered out and the requests that failed after every retry. Those requests are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the reason.

If Telegram changes its pages, you are told instead of paying for blank rows. If the first 20 posts read all lack their date, channel title or view count, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first posts are charged. A post that postedAfter / postedBefore drops because it has no date at all counts among those 20. A run of fewer posts (a scheduled onlyNew run that finds a few new ones, a small Max posts) is checked at its end, from 2 posts (the view count from 5): its posts are already saved, and the run fails with the missing field instead of ending green.

🛟 Support

Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which URLs failed and why.