Telegram Channel Scraper API - Messages, Reactions & Search
Pricing
from $2.00 / 1,000 messages
Telegram Channel Scraper API - Messages, Reactions & Search
Scrape public Telegram channels without a Telegram account. Complete post history back to the first message, keyword search across many channels at once, view counts, emoji reactions, forward attribution and reply threads. No phone number, no session string. Pay per post, failures are free.
Pricing
from $2.00 / 1,000 messages
Rating
0.0
(0)
Developer
Blackcube
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 hours ago
Last modified
Categories
Share
More from this account: YouTube Transcript Suite · Website Contact & Email Suite · Career Site & ATS Jobs Suite · Google News Suite · Keyword Research Suite · Shopify Store Intelligence Suite · eBay Data Suite · Amazon Reviews Suite · Reddit · Meta Ad Library · Vinted · Trustpilot Review Intelligence Suite · App Store & Google Play Reviews Suite · Business Reviews Suite · Amazon Product Data Suite
Scrape public Telegram channels without a Telegram account. Complete post history back to the first message, keyword search across many channels at once, view counts, emoji reactions, forward attribution and reply threads. No phone number, no session string. Pay per post, failures are free.
No run-start fee, and failures are free. Private channels, dead handles, the coverage report and every error row cost nothing. A channel that was read but had nothing new since your last run is billed once as a channel checked ($0.004) — half the price of a channel profile, and a fiftieth of what a busy channel costs.
No Telegram account. That is the whole point.
The best-known Telegram scrapers on this Store drive a logged-in Telegram session. To use
them you hand over a phone number, an api_id, an api_hash and a session string — and
then Telegram's anti-abuse systems treat that session as a scraper. The largest one in the
category has 307 open issues and none closed, with titles like "My account got blocked"
and "It wants a session password".
This Actor has no session to block. It reads what Telegram publishes to the open web.
| Session-based scrapers | This Actor | |
|---|---|---|
| Phone number | required | none |
api_id / api_hash | required | none |
| Session string to paste and keep alive | required | none |
| Your Telegram account at risk | yes | nothing to ban |
| Works the first time you press Run | after setup | immediately |
What you get
| Field | What it is |
|---|---|
text | The post itself, emoji intact, formatting flattened to plain text |
channel, messageId, url | Where it came from and a permalink straight to it |
channelId | Telegram's own numeric channel id — survives a channel rename, which the @handle does not |
datetime | Exact ISO timestamp, straight from Telegram. Not "2 days ago" |
views | View count as an integer |
viewsLabel | What Telegram actually rendered, verbatim: "1.06K", "14.7M" |
author, authorUrl | The posting identity and a link to it |
reactions | Every emoji reaction with its count, including paid Star reactions |
reactionsTotal | All reaction counts summed, so posts sort by engagement in one field |
forwardedFrom, forwardedFromUrl | The channel a post was forwarded from — the forward graph nobody else surfaces |
replyTo | The post it answers: message id, author and the quoted excerpt |
media | Photos, videos, voice notes, documents, stickers, polls and link previews, with CDN URLs |
hashtags, mentions, links | Pulled out of the text, deduplicated, ready to filter on |
isService | Pinned-message and channel-event notices, so you can keep or drop them |
Turn on enrichMessages and every post also carries:
| Field | What it is |
|---|---|
sentiment | positive, negative or neutral |
sentimentScore | Normalised -1 to 1, so posts sort by strength of feeling |
keywords | Content words, stopwords stripped out |
tickers | $BTC, #TAO style tokens — the dominant content type on Telegram |
addresses | Wallet and contract-shaped strings found in the post |
hasQuestion | The post asks something |
language | Dominant writing system (latin, cyrillic, arabic, …), or null when too short to tell |
wordCount | Words in the post |
Four kinds of row, and only two of them cost anything
| Row | type | Costs |
|---|---|---|
| One public channel post | message | $2.00 per 1,000 (+$4.00 per 1,000 if enriched) |
| A channel's profile card, with its subscriber count | channel | $8.00 per 1,000 |
| What each channel produced, and whether your cap stopped it | coverage | free |
| Anything that could not be served, with the reason | error | free |
Pricing
| Your Apify plan | message / 1,000 | channel profile / 1,000 | enrichment / 1,000 |
|---|---|---|---|
| Free | $4.00 | $16.00 | $8.00 |
| Bronze | $3.33 | $13.40 | $6.70 |
| Silver | $2.53 | $10.20 | $5.10 |
| Gold | $2.00 | $8.00 | $4.00 |
| Platinum | $2.00 | $7.40 | $3.70 |
| Diamond | $2.00 | $7.00 | $3.50 |
You are charged per post delivered, once. A post reached through two different inputs is
billed a single time, and on a scheduled re-run with onlyNewSinceLastRun the posts you
already have are neither delivered nor charged again.
searchQuery, dateFrom and dateTo narrow the run before billing, so they reduce the
bill rather than filtering something you already paid for.
What this listing's own defaults cost
Press Run without changing anything and the most this listing can charge on the Gold tier is $2.00 — up to 1,000 posts at $2.00 per 1,000 = $2.00.
A channel that returns nothing is billed one channel checked ($0.004) rather than a post, so the real bill is usually far lower. Lower
maxItems or set maxCostUsd to cap it outright.
Set maxCostUsd for a hard ceiling in dollars, or maxItems for one in rows.
Try it
{"channels": ["@durov","@telegram"],"maxMessagesPerChannel": 200,"maxItems": 1000}
Worked recipes
A channel's complete history, back to post one
Set the per-channel cap high and it walks all the way to the very first message ever published, then stops on its own.
{ "channels": ["@durov"], "maxMessagesPerChannel": 100000, "maxItems": 50000 }
Many channels in one run
Paste a list in any form — @name, name, or a t.me link. They are read in parallel
and land in one dataset, each row tagged with its channel.
{ "channels": ["@durov", "telegram", "https://t.me/TelegramTips"], "maxMessagesPerChannel": 500 }
One keyword, watched across every channel you care about
Telegram's own in-channel search does the matching, so you are billed for the hits, not for the history you filtered out.
{ "channels": ["@durov", "@telegram", "@TelegramTips"], "searchQuery": "airdrop", "maxItems": 500 }
Watch daily and pay only for new posts
Put it on a schedule with onlyNewSinceLastRun. It remembers the last post it saw per
channel, so tomorrow's run delivers — and bills — only what is genuinely new.
{ "channels": ["@bloomberg", "@BBCWorld"], "onlyNewSinceLastRun": true, "stateLabel": "news-watch" }
Just one date range
The walk stops as soon as it reaches older posts, so a narrow window is cheap rather than a full history you then throw away.
{ "channels": ["@telegram"], "dateFrom": "2026-01-01", "dateTo": "2026-03-31", "maxMessagesPerChannel": 5000 }
Subscriber counts for a list of channels
One row per channel — title, description, avatar, exact subscriber count and whether the handle is a channel, a group or a bot. Bulk vetting in a single run.
{ "channels": ["@durov", "@telegram", "@Bitcoin", "@TelegramTips"], "mode": "channels" }
Find what actually performs
Every post with its view count and its full reaction breakdown, plus the channel's subscriber count on the same dataset, so reach is a division rather than a guess.
{ "channels": ["@durov"], "mode": "both", "maxMessagesPerChannel": 300 }
Crypto channels as a structured feed
Tickers, wallet and contract addresses, sentiment and reactions extracted from every post — for backtesting and comparing channels, not for following calls.
{ "channels": ["@cryptosignals", "@whale_alert"], "enrichMessages": true, "maxItems": 2000 }
Score the lot
Sentiment, keywords, tickers and question intent on every post, so ten thousand rows sort into piles worth reading first.
{ "channels": ["@Bitcoin"], "enrichMessages": true, "maxMessagesPerChannel": 2000 }
Straight to a spreadsheet
Run it, then use the dataset's own Export button for CSV, JSON, Excel or XML. The columns are flat and documented.
{ "channels": ["@telegram"], "maxMessagesPerChannel": 5000, "includeHtml": false }
Cap the spend, not just the rows
A hard ceiling in dollars. The run stops the moment it would exceed it, and still writes its coverage report.
{ "channels": ["@durov", "@telegram"], "maxMessagesPerChannel": 100000, "maxCostUsd": 5 }
Honest limits
These are measured, and stated because a listing that hides them wastes your first run.
- View counts above 1,000 are rounded by Telegram itself. Telegram publishes
"1.06K", not1062. Rather than pass a rounded number off as exact, every row carries both the expanded integer inviewsand Telegram's verbatim string inviewsLabel, so you always know which you are filtering on. Below 1,000 the count is exact. - Member and subscriber lists are not available, and nothing here pretends otherwise. Telegram does not publish who is in a channel. The channel's total subscriber count is returned; the individual people are not, by any public route. Actors that claim to extract member lists are driving a logged-in account to do it.
- Private channels, invite-only groups, user profiles and bots have no public page. They
come back as a free
errorrow naming the reason, not as a failed run. - Some reactions are custom emoji with no glyph in the published page. Those are reported
as
custom:<id>with their exact count, rather than a guessed emoji. Standard emoji and paid Star reactions come back as themselves. - No phone numbers, and no way to message anyone. This reads published posts. It does not add members, send messages or resolve contacts, and it never will.
Legal and privacy
Not affiliated with, endorsed by, or sponsored by Telegram. "Telegram" is a trademark of Telegram Messenger Inc. and is used here only to describe what this Actor reads.
It collects publicly published channel content only — nothing behind a login, nothing private, no member lists. Where posts contain personal data you are the controller for whatever you collect under GDPR: you are responsible for having a lawful basis, honouring deletion requests, and not using what you collect to contact people who have not agreed to hear from you.
Use it from n8n, MCP, the API or a schedule
Built to be called by a workflow, not only from the Store form. The Actor is vonsensey/telegram-channel-scraper-api; every snippet below sends {}, which runs the defaults shown on the form — replace it with your own input.
n8n
Install the Apify community node (@apify/n8n-nodes-apify under Settings → Community Nodes, or search "Apify" on n8n Cloud). Add Apify → Run Actor with Actor vonsensey/telegram-channel-scraper-api and your input JSON, then Apify → Get Dataset Items on the run's defaultDatasetId and pipe the rows anywhere. For scheduled runs, the On new Apify Event trigger fires when a run of this Actor finishes.
MCP (Claude, Cursor, VS Code, any MCP client)
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=vonsensey/telegram-channel-scraper-api","headers": {"Authorization": "Bearer <YOUR_APIFY_TOKEN>"}}}}
Your agent then calls vonsensey/telegram-channel-scraper-api as a tool with the same input the form takes and reads the dataset back.
REST API (one call, rows in the response)
curl -X POST "https://api.apify.com/v2/acts/vonsensey~telegram-channel-scraper-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" -d '{}'
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("vonsensey/telegram-channel-scraper-api").call(run_input={})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row)
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('vonsensey/telegram-channel-scraper-api').call({});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Make, Zapier, LangChain, CrewAI
The Apify app in Make and Zapier has a Run an Actor module: pick vonsensey/telegram-channel-scraper-api. In LangChain and CrewAI the Apify tool wrappers take the same Actor id. A daily schedule needs nothing but the Console: Schedules → Create → this Actor → cron, and the dataset fills on its own.
Use cases
- Archive a channel before it disappears. Walk a public channel all the way back to its first post and keep the lot — text, timestamps, views, reactions and media links — as a dataset you own.
- Watch a term across a whole watchlist. One keyword, many channels, on a schedule. Each run returns the new matches and nothing else, so a daily watch costs what the day produced.
- Compare channels on evidence. Subscriber counts, posting cadence, views per post and the full reaction breakdown, side by side, so reach is a division rather than a guess.
- Feed a model or a dashboard. Flat, documented rows with an exact ISO timestamp on every post — ready to embed, chart or load into a warehouse without a cleaning pass.
Run it on a schedule
A one-off pull answers a question; a schedule answers it every day without you. Open Schedules in the Apify Console, point a cron at this Actor, and the dataset keeps filling on its own — no server, no cron box, no babysitting. Everything here is built to be re-run: you are billed per post delivered, so a scheduled run that finds nothing new bills one channel checked ($0.004) per channel instead of a post — a fiftieth of what a busy channel costs, and nothing at all for a channel that could not be read.
FAQ
Do I need a Telegram account or API key to use this?
No. No phone number, no api_id, no api_hash and no session string. It reads what Telegram publishes to the open web, so there is nothing to log in with and nothing that can get your account limited — which is the single most common complaint against the session-based scrapers in this category.
Can I scrape Telegram group members or subscriber lists?
No, and nothing in this suite claims to. Telegram does not publish who is in a channel on any public route; only the total subscriber count is public, and that is returned. Actors that offer member lists are driving a logged-in account to get them.
Can I export Telegram messages to CSV, JSON or Excel?
Yes. Every run writes a dataset you can export in one click from the Console, or pull straight from the API in JSON, CSV, XLSX or JSONL. There is a dedicated Actor in this suite for exactly that.
What happens with a private channel or a handle that no longer exists?
It comes back as a free row naming the reason, rather than failing the run. You are never charged for a channel that returned nothing, and there is no run-start fee.
Something wrong, or a field you need that is missing? Open an issue on the Issues tab — it is read and it gets fixed. If this saved you time, a rating on the Store page helps the next person find it.