Telegram Channel Scraper API - Messages, Reactions & Search avatar

Telegram Channel Scraper API - Messages, Reactions & Search

Pricing

from $2.00 / 1,000 messages

Go to Apify Store
Telegram Channel Scraper API - Messages, Reactions & Search

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

Blackcube

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

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 scrapersThis Actor
Phone numberrequirednone
api_id / api_hashrequirednone
Session string to paste and keep aliverequirednone
Your Telegram account at riskyesnothing to ban
Works the first time you press Runafter setupimmediately

What you get

FieldWhat it is
textThe post itself, emoji intact, formatting flattened to plain text
channel, messageId, urlWhere it came from and a permalink straight to it
channelIdTelegram's own numeric channel id — survives a channel rename, which the @handle does not
datetimeExact ISO timestamp, straight from Telegram. Not "2 days ago"
viewsView count as an integer
viewsLabelWhat Telegram actually rendered, verbatim: "1.06K", "14.7M"
author, authorUrlThe posting identity and a link to it
reactionsEvery emoji reaction with its count, including paid Star reactions
reactionsTotalAll reaction counts summed, so posts sort by engagement in one field
forwardedFrom, forwardedFromUrlThe channel a post was forwarded from — the forward graph nobody else surfaces
replyToThe post it answers: message id, author and the quoted excerpt
mediaPhotos, videos, voice notes, documents, stickers, polls and link previews, with CDN URLs
hashtags, mentions, linksPulled out of the text, deduplicated, ready to filter on
isServicePinned-message and channel-event notices, so you can keep or drop them

Turn on enrichMessages and every post also carries:

FieldWhat it is
sentimentpositive, negative or neutral
sentimentScoreNormalised -1 to 1, so posts sort by strength of feeling
keywordsContent words, stopwords stripped out
tickers$BTC, #TAO style tokens — the dominant content type on Telegram
addressesWallet and contract-shaped strings found in the post
hasQuestionThe post asks something
languageDominant writing system (latin, cyrillic, arabic, …), or null when too short to tell
wordCountWords in the post

Four kinds of row, and only two of them cost anything

RowtypeCosts
One public channel postmessage$2.00 per 1,000 (+$4.00 per 1,000 if enriched)
A channel's profile card, with its subscriber countchannel$8.00 per 1,000
What each channel produced, and whether your cap stopped itcoveragefree
Anything that could not be served, with the reasonerrorfree

Pricing

Your Apify planmessage / 1,000channel profile / 1,000enrichment / 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", not 1062. Rather than pass a rounded number off as exact, every row carries both the expanded integer in views and Telegram's verbatim string in viewsLabel, 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 error row 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.

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 ApifyClient
client = 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.