Telegram Channel Scraper (public channels)
Extract posts from public Telegram channels as clean JSON: text, date, views, reactions, hashtags, links, photos and videos.
Extract posts from public Telegram channels as clean JSON: text, date, views, reactions, hashtags, links, photos and videos. Keyword search and date window, many channels per run, no login, no Telegram API keys. Pay per result, built for monitoring and AI pipelines.
$3.00 / 1,000 · Recently published - building its public record.
Run it on Apify → Free to try - runs bill per result on your own account.
What you give it
Every field is optional unless marked; sensible defaults do the rest.
| Field | Type | What it does | Default |
|---|---|---|---|
channels |
string | One or more public Telegram channels, separated by commas or spaces. Use the username ("telegram", "@telegram") or the link ("https://t.me/telegram"). Only channels with a public web preview can be read: open t.me/s/<name> in a browser to check. Private channels and invite links (t.me/+...) cannot be read. |
telegram |
searchQuery |
string | Optional. Only return posts that contain this text, using Telegram's own in-channel search. Leave empty to read the latest posts. | - |
postedAfter |
string | Only include posts published on or after this date. Channels are read newest-first, so the run stops walking a channel once it reaches older posts. Format: YYYY-MM-DD (for example 2026-09-08) or a full ISO timestamp such as 2026-09-08T14:30:00Z. Slash dates like 08/09/2026 are refused on purpose: they are read as September in Europe and August in the United States, and this actor will not guess which you meant. |
- |
postedBefore |
string | Only include posts published on or before this date. Format: YYYY-MM-DD (for example 2026-09-08) or a full ISO timestamp such as 2026-09-08T14:30:00Z. Slash dates like 08/09/2026 are refused on purpose: they are read as September in Europe and August in the United States, and this actor will not guess which you meant. |
- |
maxItems |
integer | Stop after this many posts in total. Free-plan runs are capped at 5 items. The form starts at 25 for a cheap first run - that is the form's prefill, not a cap on your plan; clear it to use the default of 500. | 500 |
reportFailures |
boolean | When a run fails, send the developer the actor name and build, an error category, the error message (truncated) and a one-way hash of your input - so a bug can be fixed without anyone asking you to reproduce it. Your input itself, your results and your identity are never sent, and successful runs send nothing at all. Switch this off and the actor behaves exactly the same. | True |
What you get back
One JSON object per result, with exactly these fields - no seller identities, no contact data, ever.
| Field | Type | Meaning |
|---|---|---|
channel |
string | The channel's public username - the byline of the post. |
channelTitle |
['string', 'null'] | The channel's public display title. |
channelSubscribers |
['integer', 'null'] | Subscribers shown on the channel page. Telegram rounds large counts (for example 9.23M), so this is as exact as the page shows it. |
postId |
integer | The post's number inside its channel - a stable identifier together with `channel`. |
url |
string | Direct link to the post on t.me. |
date |
['string', 'null'] | When the post was published (ISO timestamp). |
text |
string | Post text as published, with line breaks. Empty for posts that are only media, or whose media the public preview cannot show (polls, voice messages, stickers). |
hashtags |
array | Hashtags used in the post text. |
links |
array | External links in the post text (Telegram-internal search links are excluded). |
views |
['integer', 'null'] | Views at scrape time. Telegram rounds large counts, so this is as exact as the page shows it. |
reactions |
array | Reactions at scrape time. `emoji` is null for paid (star) and custom-emoji reactions, which the public page does not render as text. |
photoUrls |
array | Photo URLs attached to the post (all photos of an album). |
videoUrls |
array | Video URLs attached to the post, where the preview exposes them. |
documentTitle |
['string', 'null'] | File name of an attached document, when the post carries one. |
linkPreview |
['object', 'null'] | The link card Telegram shows under the post, when there is one. |
isForwarded |
boolean | True when the post was forwarded from another channel. The original source's name is not collected. |
isReply |
boolean | True when the post replies to another message. The replied-to author and text are not collected. |
isEdited |
boolean | True when the post was edited after publishing. |
Health
Recently published - building its public record. Live record, failures included: status page.
Full documentation, examples and the AI-assistant prompt live on the store page.
Questions
Is scraping Telegram channels legal?
This is not legal advice. The actor reads only the public web preview at t.me/s/<channel> that any logged-out visitor can open, with no login, no Telegram API and no private chats. Post signatures, forwarded-from and reply-to names, avatars and channel bios are never read, so none of it reaches the dataset. Whether your own use of the posts is allowed under Telegram's terms and your jurisdiction's rules is yours to assess.
Which Telegram channels can it read?
Public channels whose web preview is switched on, which is the default. If t.me/s/<name> shows posts in your browser, the actor can read that channel. Private channels, groups, chats and invite links are not readable, and some large channels have the preview turned off by their owner. Those names are reported as having no public web preview, and the rest of the run is delivered.
Can I search a channel for a keyword?
Yes. Set searchQuery and only matching posts come back, each with views and reactions. Telegram's in-channel search returns a short result set rather than every match ever made, so combine it with a date window such as postedAfter for a daily watch.
How much do 10,000 Telegram posts cost?
$30.00, billed per delivered post at $3.00 per 1,000. That price covers the run's platform usage, and a run that fails or returns nothing bills nothing per result. A run delivers about three posts a second, so 10,000 posts take roughly an hour.
Does it collect who posted or forwarded a message?
No. You get the channel's title and username as the byline, plus the post itself. Signatures, forwarded-from names, reply-to names and text, and avatars are never read, and a test on every build fails if one ever appears in the output.