Telegram Channel Scraper
Pricing
from $0.30 / 1,000 telegram messages
Telegram Channel Scraper
Scrape public Telegram channels into structured posts, views, reactions, media, polls, forwards, discussion comments, capped participant samples, channel analytics, and discovery. Use no-login widget mode or publisher-pool MTProto. Run snapshots or monitor new posts with change events.
Pricing
from $0.30 / 1,000 telegram messages
Rating
0.0
(0)
Developer
Viremo Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Categories
Share
Telegram Channel Scraper — exports and change monitoring
Export public Telegram posts with text, views, reactions and available media URLs. Schedule repeat scans, identify new posts and text edits, and use stable message IDs to upsert your dataset. Widget mode needs no Telegram credentials; optional MTProto mode uses the publisher's account pool.
Start with five posts
The Store form prefills a removable durov example and five posts. Replace the
channel with your own public username, or paste this into the JSON input editor:
{"channels": ["durov"],"maxPosts": 5,"messagePreview": true,"maxChargeUsd": 0.01}
Check the dataset for one channel row and up to five message rows. At the
listed fixed event prices, five written messages plus startup are $0.00155.
This is an arithmetic example, not a minimum charge or a guaranteed result count.
The API still defaults to 50 posts when you omit maxPosts; the five-post
prefill applies only to a new Store form.
Step-by-step guides with downloadable inputs: export JSON/CSV and scheduled monitoring.
Monitor without rebilling the same observed posts
For a scheduled digest, use a dedicated baseline key for each watch:
{"mode": "monitor","monitorOutput": "changes","channels": ["durov"],"maxPosts": 50,"baselineKey": "durov-digest","messagePreview": true}
The first successful scan creates the baseline and returns the initial message
window. With monitorOutput: "changes", later scans return only newly observed
and text-edited message rows; unchanged messages are omitted. Channel rows and
requested member/story rows remain. Leave monitorOutput at its default
"snapshot" to receive the full observed message window again. Switching this
output projection does not reset the baseline or change event prices.
Message charges apply only to IDs absent from the previous baseline. Edited
messages are returned without a new message charge. Changed channels also
produce one change_event:
addedMessageIds: newly observed post IDs.updatedMessageIds: IDs in both windows whose extracted text changed.changedChannelFields: changed title, description, badges or linked discussion.eventId: identifier for this event occurrence, safe to append across runs.kind:message_addedorchannel_meta_changed.
A run containing additions and edits uses one channel summary event with both lists. View/reaction movements, subscriber counts and expiring avatar URLs are not change events. Missing posts are not treated as deletions and do not create a paid change event on their own: a bounded scan cannot distinguish deletion from history outside the window. Changing the target/filter configuration resets the baseline; a shorter window can make older posts billable if they later re-enter it.
Three practical workflows
Research export: supply up to 30 public channels, set maxPosts, and export
JSON, JSONL or CSV from the Dataset tab.
Keyword digest: add searchKeywords and a date window such as
sinceDate: "7 days"AI/search ingestion: enable messagePreview for a short summary, retain
canonicalId for upserts and compare textHash to detect changes in returned
text. The Actor does not send content to an LLM or classify sentiment.
What data is returned?
| Record type | Useful fields | Availability |
|---|---|---|
channel | username, title, description, subscribers, badges, observed-window analytics | Public source dependent |
message | messageId, URL, UTC date, text, textHash, views, reactions, links, media flags | Widget or MTProto |
change_event | eventId, kind, addedMessageIds, updatedMessageIds, changedChannelFields | Monitor runs with a baseline |
member | Public discussion participant metadata | MTProto opt-in, permission-limited sample |
story | Active story metadata | MTProto opt-in, may be unavailable |
Channel/message canonicalId is stable across runs. Change-event canonicalId
equals its run-scoped eventId. Join post IDs with the channel, not by bare ID.
textHash is SHA-256 of exact returned UTF-8 text, not of media or counters; it
is null when includeText: false. Timestamps are normalized to UTC.
Dataset views include records, messageFields and changeFields. These are
column projections, not row-type filters; use recordType when processing JSON.
The Output tab lists fields and the key-value store exposes RUN_SUMMARY with
coverage, warnings and confirmed custom-event billing counts.
Widget or MTProto?
| Capability | Widget | MTProto |
|---|---|---|
| Text, timestamps, post URLs | Yes | Yes |
| Views | Rounded public counter | API integer when available |
| Reactions | Public counts and exposed custom-emoji IDs | API counts |
| Photo/video URLs | When rendered; tokens may expire | Metadata; files are not downloaded |
| Channel avatar and media totals | When in the public header | May be null |
| Raw text HTML | Opt-in source HTML | Not supplied; entities are returned instead |
| Forward counts, entities, edit timestamps | Not supplied | When available |
| Discussion comments | Not supplied | Requires accessible public discussion threads |
| Similar-channel suggestions / topic discovery | Not supplied | Opt-in, Telegram-dependent |
| Poll results | Public question/options/percentages | Aggregate votes when supplied |
Comments, participants, polls, stories and service events depend on source
content and permissions. They are not guaranteed to exist on every channel.
Discussion comments were verified on a live run: a public
thread returned 4 comments with authors and timestamps. A run that requested
comments but found no accessible thread reports MTPROTO_NO_DISCUSSION instead of
silently returning nothing, and an optional fetch failure produces a warning while
keeping core results.
Numeric sender IDs can be absent when a post is published as the channel rather than a user. Author labels do not identify the private administrator behind a post. Voter identities, private chats, joins, invites, admin statistics and admin logs are not collected. Publisher sessions never go into the input or dataset.
Limits and incomplete results
maxPosts: 1–500 newest matching posts per channel; widget paging has a 25-page safety cap.- Existing four-character public names are supported, including post URLs and mentions.
sinceDate/untilDate:YYYY-MM-DDor relative lookbacks.searchKeywords,minViews,mediaOnly,textOnly: result filters.includePosts: false: profile-only, with no history charge.- Source timeouts, response-size limits and rate limits are respected.
coverage.complete describes the requested window, not all Telegram history.
A limit or source failure can produce coverage.partial. Inspect warnings[]
and dataQualityFlags: missing dates/views or unreadable cards are exposed;
posts with no valid date are excluded from a requested date-window filter.
text_not_extracted distinguishes disabled text extraction from an empty media
caption. Valid partial output is kept.
Private/invite-only targets are unsupported. CHANNEL_IS_USER means the target
is a person or bot; CHANNEL_IS_GROUP means it is not a broadcast channel;
CHANNEL_PREVIEW_DISABLED suggests trying MTProto. If every target fails, the
platform run fails rather than fabricating empty success.
Pricing and spending limits
- Run start: $0.00005 (platform synthetic event).
- Message: $0.00030 per billable unique message row.
- Monitor channel change summary: $0.001 per event.
Channel/member/story rows are free. Service rows requested through
includeServiceEvents are currently message rows and use the message rate.
Apify's current Pricing tab is authoritative.
maxChargeUsd caps custom message/change-event charges; it excludes the
synthetic start fee. MAX_CHARGE_USD_REACHED means this Actor-level cap was hit;
CHARGE_LIMIT_REACHED means the platform spending limit was hit. Kept rows stay
available. RUN_SUMMARY.billing reports confirmed custom charges and excludes
startup; use the platform run cost for the full invoice amount.
The minimum selectable platform spending limit is not a minimum billed price. Free-plan credits are supplied by Apify, not an additional trial from this Actor.
Re-running a monitor schedule over an unchanged channel is verified to bill $0.00 in custom events while retaining the full observed window in default snapshot output, so a run still incurs the $0.00005 startup event. When new posts appear, their message events and the $0.001 changed-channel summary are charged.
API, schedules and MCP
Use Actor ID vqebdVk5mXTYFRAIm or viremo-labs/telegram-channel-scraper with
the Apify client/API. The API tab has runnable examples; the same JSON can be
used in a Task and Schedule. In MCP, start with a bounded snapshot before asking
for a deeper export. This is batch collection, not continuous real-time streaming.
Support, responsible use and changelog
Open an issue through this Actor's Apify page with the run ID and warning code. Never include API tokens, hashes or session strings. Use public content for authorized research/workflows and respect Telegram and applicable source terms. Media files are not downloaded and no external AI service receives the data.
The Changelog tab records contract updates. Contract 1.2.0 adds changes-only
monitor output and structured channel-metadata changes. Posts leaving a window
no longer create a paid event by themselves. Message/channel identities remain unchanged.