Telegram Channel Scraper: posts, views, media, no API key
Pricing
from $0.005 / actor start
Telegram Channel Scraper: posts, views, media, no API key
Scrape public Telegram channels without a login or API key: post text, views, reactions, media links, polls, replies, forward sources and channel subscriber counts.
Pricing
from $0.005 / actor start
Rating
0.0
(0)
Developer
Michal Pšenčík
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Telegram Channel Scraper (posts, views, media, no API key)
What does Telegram Channel Scraper do?
This Actor scrapes public Telegram channels through Telegram's own web preview at
t.me/s/<channel>. For every post it returns the text, the exact posting time in UTC, the view
count, reactions, links to any photos, videos and voice notes, the poll results, the post it replies
to, the channel it was forwarded from, and a link to the post itself. Each channel also produces one
record with its title, description and subscriber count.
No Telegram account, no phone number, no API key, no api_id. The Actor reads the same public
page a browser would, so there is nothing to authorise and nothing to keep logged in.
Give it a list of channel usernames, optionally a keyword filter and a start date, and run it. Because it runs on the Apify platform you get a REST API for the results, scheduled runs, proxy rotation, run monitoring, and integrations with Google Sheets, Zapier, Make, Slack and the rest.
Try it from the Input tab: leave everything at its default and hit Start to get the latest posts
from @telegram and @durov.
Why use Telegram Channel Scraper?
- Monitoring and alerting. Run it on a schedule with a keyword filter to watch a set of channels for a brand, a ticker, a place name or a competitor, and push the hits into Slack or a webhook.
- OSINT and news desks. Views, reactions and forward provenance are the reach signals on Telegram, and all three come back with every post.
- Research datasets. Page backwards through a channel's history with
sinceand build a corpus you can rerun over time.messageIdis stable, so reruns upsert cleanly. - Market and crypto signals. Channel calls, their timing and their view counts, straight into a spreadsheet or a database.
- No MTProto client to maintain. Telegram's own API needs an
api_id, a session file and a phone number, and rate-limits per account. This Actor needs none of that.
How to use Telegram Channel Scraper
- Click Try for free (or open the Actor in Apify Console).
- On the Input tab, put the channels you want in Channels. A username, an
@usernameor at.melink all work. - Set Maximum messages per channel. The default is 40, which is two pages of the preview.
- Optionally add a Keyword filter, or a date under Only messages posted since, to narrow the run.
- Click Start and watch the log. Forty messages from two channels takes about two seconds.
- Open the Output tab (or Storage → Dataset) and export as JSON, CSV, Excel or HTML, or pull it through the Apify API.
To keep the data fresh, use Schedules in Apify Console to run the Actor every few minutes for a monitoring feed, or once a morning for a daily digest.
Input
All fields are optional; the defaults return the latest 40 posts from @telegram and @durov.
| Field | Type | Default | Description |
|---|---|---|---|
channels | array | ["telegram", "durov"] | Channels to scrape. A username, an @username or any t.me link. |
maxItems | integer | 40 | Stop after pushing this many messages per channel. 0 means no limit. |
keywords | array | [] | Only return messages whose text contains one of these words or phrases, matched case-insensitively. |
since | string | empty | Skip messages older than this date and stop paging back at it. YYYY-MM-DD or a full ISO 8601 timestamp. |
maxScannedMessages | integer | 500 | How far back to read per channel before giving up on finding more keyword matches. 0 means no limit. |
proxyConfiguration | object | Apify proxy disabled | Optional. The preview serves these pages without an anti-bot challenge, so datacenter proxies are plenty if you want one. |
Example input:
{"channels": ["telegram", "durov", "https://t.me/nexta_live"],"keywords": ["gift", "sticker"],"since": "2026-06-01","maxItems": 100}
Output
Each post is one dataset item with "type": "message". Each channel adds one item with
"type": "channel" before its messages. Download the dataset as JSON, HTML, CSV or Excel.
The channel record:
{"type": "channel","channel": "durov","title": "Pavel Durov","description": "Founder of Telegram.","url": "https://t.me/durov","imageUrl": "https://cdn4.telesco.pe/file/HYnMQg4YKLOXAKQEfmxf0NzfSxGdMvCScrzLMtLj6Mx…","subscribers": 10900000,"subscribersText": "10.9M","photosCount": 102,"videosCount": 46,"filesCount": null,"linksCount": 198,"scrapedAt": "2026-09-03T17:02:12.041Z"}
A post with a video and a link preview:
{"type": "message","channel": "telegram","messageId": 460,"postId": "telegram/460","url": "https://t.me/telegram/460","date": "2026-08-26T19:12:34.000Z","text": "For all the info from today's update and a look back at 13 years of Telegram features — check out our blog:\nhttps://telegram.org/blog/welcome-messages-buttons-TG-13\n\nAugust Features\n1 • 2 • 3 • 4 • 5 • More","views": 843000,"viewsText": "843K","forwardedFrom": null,"replyTo": null,"media": [],"linkPreview": {"url": "https://telegram.org/blog/welcome-messages-buttons-TG-13","siteName": "Telegram","title": "Welcome Messages, Buttons in Messages and Signed Gifts","description": "Introducing Welcome Messages to greet new members of groups or channels, Buttons in Messages to make any text interactive, Inline Documents in Messages and much more.","imageUrl": "https://cdn4.telesco.pe/file/dhX3eCd_S2LrqYN1CQrGUhmYQarf3dPyUfR0Z_uOtu6…"},"outlinks": ["https://telegram.org/blog/welcome-messages-buttons-TG-13", "https://t.me/telegram/455"],"reactions": [],"poll": null,"authorSignature": null,"edited": false,"scrapedAt": "2026-09-03T17:02:11.938Z"}
A poll comes back with its options and the share of the vote each one holds:
{"type": "message","channel": "polls","messageId": 122,"url": "https://t.me/polls/122","date": "2026-09-03T08:00:15.000Z","text": "","views": 8,"poll": {"question": "What's the most realistic path for China-West relations over the next decade?","type": "Anonymous Poll","voters": 1,"options": [{ "text": "Managed rivalry with guardrails", "percent": 0 },{ "text": "Full economic decoupling", "percent": 0 },{ "text": "Gradual cooperation on shared crises", "percent": 100 },{ "text": "Escalating conflict with no resolution", "percent": 0 }]}}
A reply carries the post it answers, a forward carries its source, and files come back as a name and a size:
{"replyTo": {"messageId": 123066,"url": "https://t.me/nexta_live/123066","author": "NEXTA Live","text": "Россияне атаковали университет в центре Киева — в это время у студентов шли занятия…"},"forwardedFrom": { "name": "LUXTA", "channel": "luxta_tv", "url": "https://t.me/luxta_tv/8235" },"media": [{ "type": "document", "url": null, "fileName": "Конкретная математика.zip", "fileSize": "15.4 MB" }],"reactions": [{ "emoji": "🤬", "emojiId": null, "count": 1280 },{ "emoji": "😢", "emojiId": null, "count": 173 }]}
CDN links in the examples above are shortened with … for readability; the real values are full URLs.
Data fields
| Field | Type | Description |
|---|---|---|
type | string | message or channel. Filter on this if you only want one of them. |
channel | string | Channel username, without the @. |
messageId | number | Telegram's post number inside the channel. Stable, so use channel + messageId as your key. |
postId | string | <channel>/<messageId>, the single-field version of the same key. |
url | string | Link to the post on t.me. |
date | string | null | When it was posted, ISO 8601 in UTC. |
text | string | Post text with line breaks preserved and emoji intact. Empty for media-only posts. |
views | number | null | View count, expanded from the preview's 843K shorthand. |
viewsText | string | null | The shorthand as the preview renders it. |
forwardedFrom | object | null | { name, channel, url } for a forwarded post. channel and url are null for a private source. |
replyTo | object | null | { messageId, url, author, text } of the post being replied to. |
media | array | One entry per attachment: { type, url, thumbnailUrl, duration, fileName, fileSize }. |
linkPreview | object | null | The preview card: { url, siteName, title, description, imageUrl }. |
outlinks | array | Every http(s) link inside the post text, deduplicated. |
reactions | array | { emoji, emojiId, count } per reaction. Custom emoji have an id and no character. |
poll | object | null | { question, type, voters, options[] }, each option with its text and percent. |
authorSignature | string | null | The signature on the post, when the channel signs posts. |
edited | boolean | Whether the post carries Telegram's "edited" mark. |
scrapedAt | string | When this run read the page, ISO 8601 in UTC. |
Media type is one of photo, video, roundvideo, voice, document or sticker. Photos, videos
and voice notes come back with a direct CDN URL. Documents do not: Telegram's preview publishes the file
name and size but no download link, so url is null for them.
How much does it cost to scrape Telegram channels?
This Actor uses pay per event pricing: $0.002 per result plus $0.005 per run start. Platform usage is included, so those two numbers are the whole bill. A result is one message, or the one channel record each channel produces.
The default input returns 82 results, which costs about $0.17. A hundred messages from a single channel costs $0.21. A keyword-filtered monitoring run is much cheaper, because you are only charged for the messages that match: scanning 500 messages for two keywords and finding four of them costs $0.02. The Apify free plan comes with $5 of monthly platform credit, which is enough to try the Actor and run it daily for a while.
To cap spending on a single run, set a maximum cost in the run options, or use maxItems.
Tips and advanced options
- Cut the bill on monitoring runs. Set
keywordsand a smallmaxItems. You are only charged for messages that are pushed, so a quiet interval costs one actor start. maxItemsis per channel, not per run. Ten channels atmaxItems: 50is up to 500 messages. This is deliberate: a shared budget would let the first channel eat all of it.- Deduplicate across runs.
postIdis stable. A post scraped twice will have the same id and a higher view count the second time, which is exactly what you want for tracking reach over time. - Reading a long history.
sinceis the cheap way to bound it. WithoutsinceormaxItems, the Actor pages back through the whole channel, twenty posts at a time. - Keyword runs need a scan budget. A keyword that never appears would otherwise walk the entire
history, so
maxScannedMessages(500 by default) stops the search. Raise it to dig deeper. - Proxies are optional. Telegram does not challenge these pages. Turn on Apify Proxy datacenter groups only if you are running very frequently from one address.
FAQ, disclaimers and support
Does this Actor need a Telegram account or API key?
No. It reads the public web preview at t.me/s/<channel>, which needs no login, no phone number and no
api_id.
Which channels can it read? Any public channel that has a web preview. Private and invite-only channels, groups, user accounts and bots have no preview: t.me redirects those to a plain landing page, and the Actor logs a warning and skips them rather than failing the run.
Does it return forward counts?
No, and no scraper of this page can. Telegram's public preview publishes views and reactions but not the
number of times a post was forwarded. What the Actor does return is forwardedFrom, the channel a post
was forwarded from.
Does it return comments or discussion-group replies?
No. replyTo is the in-channel reply chain. Comments live in the linked discussion group, which the
channel preview does not render.
Why is text sometimes empty?
A post can be media only, a poll only, or a forward with no caption. The text field is empty rather than
null in those cases, and the content is in media or poll.
Why did I get fewer messages than I asked for?
Check maxItems, keywords and since, and remember the channel may simply be shorter than your limit.
The Actor also stops at the first post of a channel.
Is scraping Telegram legal? This Actor reads only publicly available pages, the same ones anyone can open without an account. Scraping publicly accessible information is generally legal in the EU and the US, but you are responsible for how you use the output, including Telegram's Terms of Service, the privacy of the people posting, and any rights that apply where you operate. Talk to a lawyer if you plan to redistribute the data commercially.
Found a bug, or need something else? Open an issue on the Issues tab of this Actor and it will be picked up. If you need a custom version, Telegram-wide search, or an extraction that is not covered here, mention it in the issue.