Telegram Channel Scraper - Messages, Profiles & Analytics
Pricing
from $1.00 / 1,000 telegram messages
Telegram Channel Scraper - Messages, Profiles & Analytics
Scrape public Telegram channels without an API, account, or browser. Extract messages, views, reactions, media, links, dates, authors, and channel profiles as clean JSON for monitoring, research, archiving, and analytics.
Pricing
from $1.00 / 1,000 telegram messages
Rating
0.0
(0)
Developer
Daniel Valev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
19 hours ago
Last modified
Categories
Share
Scrape public Telegram channels into clean, structured data—without a Telegram API ID, bot token, phone number, account, credentials, or browser. Enter channel usernames or t.me URLs and get messages, views, reactions, media, link previews, authors, dates, and channel profiles ready for monitoring, research, archiving, and analytics.
Disclaimer: This is an unofficial tool and is not affiliated with, endorsed by, or sponsored by Telegram.
Public web previews only. The Actor reads t.me/s/<username> over HTTP and never logs in to Telegram. That keeps runs lightweight and avoids browser overhead while preserving the data visible on public channel pages.
How to scrape Telegram without an API key
Many Telegram data tools require an api_id, api_hash, account session, or bot token. This Actor uses Telegram's public web preview—the same t.me/s/<username> page anyone can open without authentication. Provide a username such as durov or telegram; pagination, polite pacing, retries, normalization, and structured extraction are handled automatically.
It is best suited to public channel content. It does not bypass access controls or expose private groups, member lists, phone numbers, or login-protected history.
Telegram web scraper vs. Telegram API client
| Capability | This Actor | Authenticated Telegram API client |
|---|---|---|
| API credentials and phone login | Not required | Usually required |
| Public channel messages and profiles | Yes | Yes |
| Private channels or groups | No | Only when the account has access |
| Individual member lists | No | Permission and API limitations apply |
| Browser infrastructure | Not required | Not required |
| Setup time | Username and message limit | App credentials, account, and session management |
Try it in 30 seconds
- Add channels — usernames such as
durov,@telegram, or fullt.meURLs. - Choose a limit — up to 5000 messages per channel, or enable profile-only mode.
- Start — export the dataset as JSON, CSV, Excel, XML, or RSS.
{ "channels": ["durov", "https://t.me/telegram"], "maxMessages": 40 }
A message comes back like this:
{"type": "message","messageId": 510,"channelUsername": "durov","date": "2026-05-12T17:28:39.000Z","text": "With 400 validators across 6 continents…","views": 3490000,"mediaType": "photo","reactions": [{ "emoji": "⭐", "countParsed": 8220, "isPaid": true }],"url": "https://t.me/durov/510"}
Why this Telegram scraper
- No Telegram API or account. No API ID, API hash, bot token, session, phone verification, or login.
- Messages and profiles in one run. Collect content plus channel title, description, subscribers, media counters, avatar, and verification status.
- Analytics-ready numbers. Abbreviations such as
3.49Mviews and8.22Kreactions are also returned as integers. - Rich message context. Extract signatures, edited/forwarded state, forward sources, reply IDs, media, link previews, custom emoji reactions, and paid stars.
- HTTP-only and polite. Maximum concurrency of 2, per-domain delay, browser-like Chrome headers, retries, sessions, and proxy rotation—without downloading page assets in a browser.
- Reliable pagination. Overlapping pages are deduplicated by message ID, with migration progress persisted for platform restarts.
- Recoverable errors. Missing, private, rate-limited, or failed channels produce structured error items without breaking successful channels.
Who it is for
- News and media teams monitoring public announcement channels.
- Researchers and analysts studying publication volume, views, links, and reactions.
- Brand and community teams tracking public channel content and engagement.
- Developers needing a lightweight Telegram API alternative for public data.
- Archivists and OSINT workflows collecting reproducible public-channel snapshots responsibly.
Pricing
This Actor uses transparent Apify Pay-Per-Event pricing. Platform usage is included, so users pay only for the events below.
| Event | Charged when | Price |
|---|---|---|
apify-actor-start | Automatically when a run begins | $0.00005 |
channel-info | Per successfully saved public channel profile | $0.002 |
message | Per successfully saved public Telegram message | $0.001 |
Error items are free. If the run reaches the user's maximum-cost limit, the Actor stops successfully and preserves results already paid for.
Example costs:
| Example | Calculation | Total |
|---|---|---|
| 1 channel, 20 messages | $0.00005 + $0.002 + 20 × $0.001 | $0.02205 |
| 1 channel, 100 messages | $0.00005 + $0.002 + 100 × $0.001 | $0.10205 |
| 5 channels, 50 messages each | $0.00005 + 5 × $0.002 + 250 × $0.001 | $0.26005 |
apify-actor-start is Apify's synthetic start event and is charged automatically by the platform. The Actor charges only the custom channel-info and message events in code. The automatic apify-default-dataset-item event is intentionally disabled so results and errors are never double-charged.
Input
Configure the Actor from Apify Console or pass the same object through the API.
| Field | Type | Default | Description |
|---|---|---|---|
channels | string[] | required | Usernames, @usernames, t.me/<name>, or t.me/s/<name> URLs. Entries are normalized, lowercased, and deduplicated. |
maxMessages | integer | 100 | Maximum deduplicated messages per channel, from 1 to 5000. |
includeChannelInfo | boolean | true | Save one channelInfo item for each successful channel. |
profileOnly | boolean | false | Save exactly the channel profile and skip messages. Overrides includeChannelInfo: false. |
proxyConfiguration | object | Apify proxy enabled | Standard Apify proxy configuration. Disable it for direct local requests. |
Example input
{"channels": ["@durov", "https://t.me/s/telegram"],"maxMessages": 100,"includeChannelInfo": true,"profileOnly": false,"proxyConfiguration": { "useApifyProxy": true }}
Output
The default dataset can contain three item types: message, channelInfo, and error. Missing optional source data is never fabricated; it is returned as null, [], or false as appropriate.
Message fields
| Field | Type | Description |
|---|---|---|
messageId | integer | Message ID, unique within its channel. |
channelUsername / channelTitle | string | Normalized username and displayed title. |
url | string | Canonical https://t.me/<channel>/<id> permalink. |
date | string|null | ISO 8601 publication timestamp. |
text / textHtml | string|null | Plain-text and source-HTML message bodies. |
views / viewsRaw | integer|null / string|null | Normalized and displayed view counts. |
author | string|null | Message signature, when present. |
isEdited / isForwarded | boolean | Telegram message-state flags. |
forwardedFrom | object|null | Forward source name and URL. |
replyToMessageId | integer|null | Referenced message ID for replies. |
mediaType | string|null | photo, video, roundVideo, document, or sticker. |
photoUrl, videoUrl, videoThumbUrl | string|null | Telegram CDN media URLs. |
videoDuration | string|null | Displayed video duration. |
linkPreview | object|null | URL, site, title, description, and preview image. |
reactions | array | Emoji/custom emoji ID, raw and numeric count, paid-star flag. |
scrapedAt | string | ISO timestamp when the message was parsed. |
Channel profile fields
channelInfo items contain channelUsername, title, description, raw and numeric subscriber counts, photo/video/link counters, avatarUrl, and verified.
Error items
One failed channel does not stop other channels. Recoverable errors contain:
{"type": "error","channelUsername": "private_or_missing_channel","error": "NO_PUBLIC_PREVIEW","message": "Telegram channel @private_or_missing_channel has no public web preview.","scrapedAt": "2026-07-19T12:00:00.000Z"}
Possible codes are CHANNEL_NOT_FOUND, NO_PUBLIC_PREVIEW, RATE_LIMITED, and FETCH_FAILED.
Run via API
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('YOUR_USERNAME/telegram-channel-scraper').call({channels: ['durov', 'telegram'],maxMessages: 40,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("YOUR_USERNAME/telegram-channel-scraper").call(run_input={"channels": ["durov", "telegram"],"maxMessages": 40,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
cURL
curl -X POST \'https://api.apify.com/v2/acts/YOUR_USERNAME~telegram-channel-scraper/runs?token=YOUR_TOKEN' \-H 'Content-Type: application/json' \-d '{"channels":["durov","telegram"],"maxMessages":40}'
Recipes
Monitor recent posts from several channels
{"channels": ["channel_one", "channel_two", "channel_three"],"maxMessages": 20}
Build a channel directory without collecting messages
{"channels": ["durov", "telegram"],"profileOnly": true}
Collect a deeper archive
{"channels": ["public_channel"],"maxMessages": 1000,"proxyConfiguration": { "useApifyProxy": true }}
Scheduling and integrations
- Schedule recurring snapshots from Apify Console → Schedules.
- Export datasets as JSON, CSV, Excel, XML, or RSS.
- Send results to Google Sheets, Slack, Zapier, Make, webhooks, databases, or your own API.
- Use
messageIdpluschannelUsernameas a stable downstream deduplication key.
How to export Telegram channel history to CSV
- Enter one or more public channel usernames.
- Set
maxMessagesto the required depth, up to 5000 per channel. - Start the Actor and open its Dataset tab.
- Choose Export and select CSV or Excel.
- For nested reactions and link previews, prefer JSON because tabular formats flatten nested objects and arrays.
Each message becomes one dataset record with stable channel/message identifiers, publication date, text, views, author, media type, reactions, forward/reply context, and permalink. For a growing archive, schedule recurring runs and deduplicate downstream using channelUsername + messageId.
Use with AI agents through MCP
After publishing, the Actor can be exposed as a tool through the hosted Apify MCP server. Replace YOUR_USERNAME with the actual Apify account name:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=YOUR_USERNAME/telegram-channel-scraper"}}}
Example agent requests:
- “Scrape the latest 100 messages from this public Telegram channel.”
- “Get profile metadata and recent posts from @durov.”
- “Return only subscriber count, description, avatar, and verification status.”
The structured input/output schemas help MCP clients understand how to call the Actor and interpret its dataset results.
Telegram channels vs. groups
A Telegram channel is primarily a broadcast feed where administrators publish posts to subscribers. A Telegram group is a conversation space where members can post messages. This Actor supports only public entities that Telegram exposes through a working t.me/s/<username> preview. It does not claim group or member-list support when that content is absent from the public preview.
Tips for best results
- Start with 20–40 messages while testing a new channel, then raise the limit.
- Batch multiple channels in one run instead of creating many tiny runs.
- Keep the default proxy enabled for scheduled or high-volume work.
- Store media separately if you need durable files; Telegram CDN URLs can expire.
- Use
profileOnlyfor discovery and directories—it avoids message requests and message charges.
FAQ
What does this Telegram channel scraper extract? Public channel profiles and messages, including plain text and HTML, dates, integer views, authors, forwards, replies, media URLs, link previews, reactions, custom emoji IDs, and paid stars.
Does it require Telegram API credentials or a Telegram account? No. It reads only public Telegram web preview pages over HTTP, with no API ID, bot token, phone number, login, or browser.
Can it scrape private channels or groups? No. Private channels, invite-only content, groups without public previews, and login-protected history are not accessible through t.me/s.
How many messages can it collect? Up to 5000 deduplicated messages per channel per run, subject to what Telegram exposes in the public preview.
Can I scrape only channel subscriber and profile data? Yes. Set profileOnly: true to receive one profile item per successful channel and no message items.
Why are some values null? Telegram does not show every field on every message. The Actor preserves missing source data as null rather than guessing.
Are media URLs permanent? No. Telegram CDN URLs may expire. Download files into your own storage if long-term access is required.
How does it handle duplicates and platform migrations? It deduplicates by message ID and persists per-channel progress so an Apify migration can resume without restarting the crawl from the newest page.
Why is a reaction emoji sometimes null? Telegram custom emoji may have no Unicode equivalent in the preview. In that case, use emojiId; paid stars are marked by isPaid: true.
Why did a channel return NO_PUBLIC_PREVIEW? Open https://t.me/s/CHANNEL_NAME in a browser. If it redirects to a join page or shows no public messages, Telegram does not expose scrapeable preview history for that channel.
Legality and responsible use
The Actor requests publicly accessible t.me/s/ pages without authentication. It does not access private channels, bypass permissions, request user credentials, or extract private member lists. Public availability does not remove your obligations: review Telegram's terms and comply with applicable privacy, copyright, data-protection, and sector-specific rules for your use case.
Do not use the Actor to collect or process personal data unlawfully, harass individuals, evade access controls, or build prohibited surveillance systems.
Limitations
- Public Telegram channels with a working
t.me/s/<username>preview only. - Telegram can change its HTML or rate-limit requests; retries, sessions, pacing, and proxy support reduce—but cannot eliminate—this risk.
- Public previews may not expose all historical messages or original-quality media.
- The maximum is 5000 messages per channel per run.
Support and releases
If Telegram changes its HTML or a supported public channel parses incorrectly, open an issue from the Actor's Apify page and include the public channel URL, run ID, expected result, and observed error—never include API tokens or proxy credentials.
See CHANGELOG.md for release history. Breaking output changes will be documented before deployment.
Development
See DEVELOPMENT.md for fixtures, PPE testing, smoke tests, and deployment. Quick quality gate:
npm cimake check