Telegram Channel Posts Scraper
Pricing
from $0.35 / 1,000 posts
Telegram Channel Posts Scraper
Posts from public Telegram channels, with rounded counters labelled as approximate and every missing field explained.
Pricing
from $0.35 / 1,000 posts
Rating
0.0
(0)
Developer
Marknetic
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Telegram Channel Scraper — Public Posts, Views & Reactions
Extract posts from public Telegram channels: text, date, views, reactions, photos, videos, documents, forwards, author signatures and link previews, as structured JSON, CSV or Excel.
No Telegram account, phone number, API key or bot token. It reads the same public web preview anyone can open at t.me/s/<channel>.
Built for media monitoring, brand and news tracking, research archives, and keeping an eye on many channels on a schedule.
Three guarantees
1. You pay per post returned. Nothing else.
No charge to start a run. No charge for a channel that does not exist, is private, or cannot be read. If a run returns nothing, it costs you nothing, and the run summary says so in plain words.
That matters most for scheduled monitoring, where a run every hour may return only a handful of new posts: you pay for those posts, not for the run.
2. Every field matches the page, or it is null with a reason.
Telegram's web preview shows view and reaction counts rounded ("1.68M"). This actor gives you that figure exactly as shown, plus a number parsed from it in a field whose name ends in _approx. A rounded count is never passed off as an exact one.
When a value is missing, every row still has every key, and a _provenance block records where each value came from, or why it is null:
absent: the post has no such thing (no caption, no signature).undisclosed: Telegram shows the post but withholds its content from the web ("Please open Telegram to view this post").unparseable: the value is on the page but could not be read.
3. Nothing is dropped silently.
Every channel you ask for is accounted for. One that cannot be read appears in the run summary with the reason: not a public channel, a reserved name, a preview that is unavailable from where the request was made, or a page that could not be fetched. One bad channel does not stop the others.
What you get
One row per post:
| Field | Example |
|---|---|
channel | durov |
post_id | 536 |
url | https://t.me/durov/536 |
published_at | 2026-07-30T16:55:01+00:00 |
edited | false |
text | the post text, line breaks kept |
views_display / views_approx | "6.25M" / 6250000 |
reactions | emoji (or custom-emoji id), paid flag, count as shown and approximate |
photo_urls | direct image URLs |
video_count | videos in the post |
document_titles | titles of attached files and audio |
forwarded, forwarded_from_name, forwarded_from_url | the forward source, when Telegram shows it |
author_signature | the signature on signed posts |
link_preview_url | the link behind a preview card |
preview_withheld | true when Telegram shows "Please open Telegram to view this post" instead of the content |
source_url | the page the post was read from |
_provenance | where each field came from, or why it is null |
Real sample output
From a run on the Apify platform, with the photo URL and reaction list shortened:
{"channel": "durov","post_id": 536,"url": "https://t.me/durov/536","published_at": "2026-07-30T16:55:01+00:00","edited": false,"text": "🇦🇫😈","views_display": "6.25M","views_approx": 6250000,"reactions": [{ "emoji": null, "emoji_id": null, "paid": true, "count_display": "49.2K", "count_approx": 49200 },{ "emoji": null, "emoji_id": "5373223594484587136", "paid": false, "count_display": "274K", "count_approx": 274000 }],"photo_urls": ["https://cdn4.telesco.pe/file/sA6LMASu6MckEQiLzrDe9dwVzq7EgV2…"],"video_count": 0,"document_titles": [],"forwarded": false,"forwarded_from_name": null,"forwarded_from_url": null,"author_signature": "Pavel Durov","link_preview_url": null,"preview_withheld": false,"source_url": "https://t.me/s/durov","_provenance": {"views_display": { "source": "dom", "key": ".tgme_widget_message_views", "reason": null, "conflict": null },"author_signature": { "source": "dom", "key": ".tgme_widget_message_from_author", "reason": null, "conflict": null },"link_preview_url": { "source": null, "key": null, "reason": "absent", "conflict": null }}}
The _provenance block above is an excerpt; every row carries an entry for every field.
A post Telegram will not show on the web
Some posts appear in the channel, with a date and a view count, but the web preview replaces their content with "Please open Telegram to view this post". You still get the row, and it says what happened:
{"channel": "bbcrussian","post_id": 100853,"url": "https://t.me/bbcrussian/100853","published_at": "2026-10-28T14:10:51+00:00","text": null,"views_display": "44.8K","views_approx": 44800,"preview_withheld": true,"_provenance": {"text": { "source": null, "key": null, "reason": "undisclosed", "conflict": null }}}
The text is null with reason undisclosed, not absent: the post is not empty, Telegram is withholding it from the web. A row with no text and a row whose text was withheld are different facts, and you can tell them apart.
Speed and reliability
Measured on the Apify platform at 1 GB of memory, not estimated:
| 6,000 posts from two channels | 60 seconds, 338 MB peak memory |
| 800 posts from four channels | 15 seconds, 211 MB peak memory |
| Pages blocked or rate-limited | none in any run |
One request returns about 20 posts with every field, and older pages are fetched in parallel. No browser is launched, which is why runs are fast and light.
Before the first release, 1,200 consecutive page requests through Apify's datacenter proxy all succeeded, with no slowdown from the first request to the last. Stated conservatively, that supports at least a 99.7% page success rate, with 95% confidence. It is a measurement, not a promise about every future run.
The newest 200 posts of a channel returned by this actor were checked one for one against a page-by-page walk of the same channel: none missing, none duplicated.
Input
| Field | Description |
|---|---|
| Channels | Usernames or links: durov, @durov, https://t.me/durov and https://t.me/s/durov all work. Duplicates are removed. |
| Maximum posts per channel | The newest N posts of each channel. Defaults to 200. |
| Oldest date | Optional. Only posts published on or after this date; fetching stops once it is passed. |
| Search query | Optional. Return only posts matching a word or phrase inside each channel, using Telegram's own channel search. |
| Concurrency | Pages fetched at once, 1–30. Defaults to 10. |
{"channels": ["durov", "https://t.me/s/telegram"],"maxPostsPerChannel": 200,"oldestDate": "2026-10-01"}
Monitoring on a schedule: set Oldest date to a recent date, or keep Maximum posts per channel small, and run it every hour or day. There is no start fee, so a run that finds 5 new posts costs 5 posts.
What cannot be scraped, and how you are told
| The channel is… | You get |
|---|---|
private, or an invite link (t.me/+…, joinchat) | refused before the run fetches anything, with the reason |
| not a channel (a person's account, or no such name) | not_found in the run summary |
| a reserved name Telegram redirects to its home page | not_found in the run summary |
| showing no web preview from the region the request came from | not_found, worded "may be restricted in this region". Requests leave from the US. |
| empty | a note in the log; not counted as a failure |
None of these is charged.
Pricing
$0.50 per 1,000 posts, charged as posts are delivered. Nothing on start, nothing for failures. Your Apify plan's discount applies automatically.
At the default of 200 posts per channel, a channel costs about $0.10. The maximum cost you set for a run is respected exactly: the run checks it before fetching anything and stops at it, rather than returning posts it cannot charge for.
Typical uses
- Media and news monitoring: follow outlets' channels and archive every post with its date and reach.
- Brand and topic tracking: search channels for a name or keyword on a schedule.
- Research datasets: a channel's history as one table, with rounded counts clearly labelled.
- Reach comparison: views and reactions across channels over time.
Limits worth knowing
- Public channels only. Groups, private channels and anything behind a login are out of scope; no account is used.
- Counts are as precise as Telegram makes them. The web shows views and reactions rounded; exact figures are only available inside the Telegram apps.
- Comments are not included, and media files are not downloaded. Photos come as URLs; Telegram's media links may stop working after a while, so download what you need promptly.
- Telegram's channel search decides what a search query matches.
- Requests leave from the US. A channel that Telegram restricts in the US cannot be read and is reported as such.
Responsible use
This actor reads only what Telegram publishes on its public web preview, at a modest request rate. Posts can contain personal data, and you are responsible for using the results lawfully, including under data-protection law such as the GDPR, and in line with Telegram's terms.