Telegram Media Scraper — Photos & Video Links
Pricing
$1.20 / 1,000 media items
Telegram Media Scraper — Photos & Video Links
Every photo and video from any public Telegram channel, one row per file, with a direct link you can download. Albums are fully expanded — all ten images, not just the first. Videos arrive with a playable link, poster frame and duration. No Telegram account or login. Export to CSV, Excel or JSON.
Pricing
$1.20 / 1,000 media items
Rating
0.0
(0)
Developer
Hamza
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a month ago
Last modified
Categories
Share
Point it at any public Telegram channel and get every photo and video it has published, one row per file, each with a direct link you can download. Photo albums are fully expanded — a post carrying ten images gives you ten rows, not one. Videos arrive with a playable link, a poster frame and a duration in seconds. Nothing to install, no Telegram account, no login: paste channel names, press start, download the result as CSV, Excel or JSON.
What you can do with it
- Build an image library from a channel — every photo it has published, ready to download in bulk.
- Collect video clips with their details — playable link, poster frame, duration and the caption they were posted with.
- Feed a brand-safety or computer-vision pipeline — a clean list of image and video links, refreshed on a schedule.
- Archive visual coverage from news channels — pictures of an event as they were published, with the exact publication time.
- See what a competitor posts and how it lands — each attachment carries the views and reactions of the post it came from.
- Audit a channel's media mix — how much of it is photos, how much is video, how long the videos run.
What you get
One row per photo or video, not one row per post. Abridged real example — the second image of a six-image album:
{"channel": "bbcrussian","channelTitle": "BBC News | Русская служба","channelId": -1003921752,"subscriberCount": 389000,"subscriberCountIsExact": false,"mediaId": "bbcrussian/98011#2","postId": 98011,"mediaMessageId": 98012,"date": "2026-08-04T16:48:19.000Z","mediaType": "photo","mediaGroup": "photo","fileUrl": "https://…/file/tkZKiv0VTadzUYNPZY9vUqyEEi_c-ZxeOHjLIMKcxlz.jpg","fileExtension": "jpg","isDownloadable": true,"thumbnailUrl": null,"duration": null,"durationSeconds": null,"unavailableReason": null,"isAlbum": true,"positionInPost": 2,"itemsInPost": 6,"caption": "📸 Фото дня. Извержение вулкана Фуэго в Гватемале …","viewCount": 29000,"viewCountIsExact": false,"viewCountPublished": "29K","reactionCount": null,"reactionCountIsExact": null,"isForwarded": false,"hashtags": [],"scrapedAt": "2026-08-05T09:14:22.000Z"}
A video row looks the same, with fileUrl pointing at a playable file, thumbnailUrl at the poster frame and durationSeconds filled in.
Input reference
Every setting below appears in the actor's form, labelled exactly as shown.
| Setting | Type | Default | What it does |
|---|---|---|---|
| Telegram channels | list of strings | — | The public channels to collect from. A channel link or an @username, one per line, up to 1,000 in one run — anything past that is left out and named in the run log. Required. |
| Media to collect | multi-select | Photos, Videos | Which attachments to return. Photos and videos come with a direct file link. Files, audio and voice notes can be added, but Telegram publishes no downloadable link for them, so those rows carry their title and kind only. |
| Posts to look through per channel | integer | 200 | How many recent posts to look through in each channel, newest first. Posts with no attachments produce no rows, so a text-heavy channel returns fewer items than posts. Maximum 20,000. |
| Maximum media items | integer | 1000 | A ceiling on the rows the whole run may produce, across every channel. The run stops cleanly when it is reached and keeps everything already collected. Maximum 200,000. |
| Browse from | select | United States | The country to browse from on a second attempt, used only when Telegram declines the first one. Most runs never need it. A few channels are restricted in some countries, so on that second attempt it can change what a channel returns. |
| Parallel workers | integer | 16 | How many channels are worked through at the same time. Maximum 32. |
Output fields
| Field | Type | Description |
|---|---|---|
channel | string | The channel's @username, without the @. |
channelTitle | string | null | The channel's display name. |
channelId | number | null | Telegram's own numeric id for the channel. One channel can answer on more than one name, so this is the reliable way to group rows. |
channelUrl | string | Public link to the channel. |
subscriberCount | number | null | Subscribers at the moment of collection. |
subscriberCountIsExact | boolean | null | false when Telegram published the figure in rounded form. |
mediaId | string | A stable id for this exact attachment: channel, post and the attachment's place inside it. |
postId | number | The post the attachment belongs to. For an album this is the post's first number. |
postUrl | string | Public link to the post. |
mediaMessageId | number | null | The attachment's own number, when Telegram gives it one — every image and every video in an album has its own. null when it does not have one. |
mediaUrl | string | Public link to the individual attachment, or to its post when it has no link of its own. |
date | string | null | When the post was published, in UTC. |
mediaType | string | photo, video, round_video, sticker, audio, voice, file, or unavailable for media Telegram does not publish outside its own apps. |
mediaGroup | string | The family the row belongs to: photo, video or document. |
fileUrl | string | null | Direct link to the file. null when Telegram publishes none — see unavailableReason. |
fileExtension | string | null | The file's format, e.g. jpg, mp4, webp. |
isDownloadable | boolean | true when the row has a direct file link. |
thumbnailUrl | string | null | Poster frame for a video. |
duration | string | null | Video length as Telegram displays it, e.g. "0:42". |
durationSeconds | number | null | The same length in seconds. |
fileTitle | string | null | Title of a file, audio track or voice note. |
filePerformer | string | null | Performer or subtitle of an audio track. |
fileSize | string | null | Size of a plain file as Telegram displays it. |
unavailableReason | string | null | Why a row has no file: no_file_published for files, audio and voice notes, not_viewable_outside_telegram for media Telegram keeps inside its own apps. |
isAlbum | boolean | true when the attachment came from a multi-image post. |
positionInPost | number | This attachment's place in its post, starting at 1, in the order Telegram published them — so a post mixing pictures and video keeps the order it was posted in. |
itemsInPost | number | How many attachments the post carried in total. |
caption | string | null | The text of the post the attachment belongs to. null when the post had none. |
viewCount | number | null | Views of the post at the moment of collection. null when the channel does not publish views. |
viewCountIsExact | boolean | null | false when the figure was published in rounded form. |
viewCountPublished | string | null | Exactly what Telegram displayed, e.g. "29K". |
reactionCount | number | null | All reactions on the post added together. null when the channel publishes no reactions at all. |
reactionCountIsExact | boolean | null | false when at least one reaction was published in rounded form, so the total is an approximation. null when there are no reactions to add up. |
isForwarded | boolean | Whether the post was forwarded from somewhere else. |
forwardedFrom | object | null | Where it came from: name, link and @username. |
hashtags | array | Hashtags in the caption, without the #. |
scrapedAt | string | When this row was collected, in UTC. |
Pricing
You pay per result, not for time.
| What you pay for | Price |
|---|---|
| Every media item collected | $1.20 per 1,000 items |
Nothing else is billed. A post with no attachments produces no row and costs nothing, and a channel that turns out to be unavailable costs nothing at all.
Worked example. You sweep 10 photo-heavy channels, looking through their latest 200 posts each, and get about 1,500 photos and videos. That is $1.80 for the run. A daily watch on the same 10 channels at 50 posts each returns roughly 350 items — about $0.42 a day. Set Maximum media items to put a hard ceiling on any single run, or cap the spend on the run and the actor stops cleanly at the cap, keeping everything already collected.
Limits & what this actor cannot do
- Only public Telegram channels are covered. Private channels, invite-only groups and one-to-one chats are not publicly viewable, and are reported as unavailable rather than returned empty.
- Groups are not channels. A public group's messages are not published for reading, so a group handle is reported as unavailable rather than returned empty.
- Files, audio and voice notes have no downloadable link. Telegram publishes their title, performer and kind and nothing more. Those rows say so in
unavailableReasoninstead of being dropped or given a fake link. - Some posts carry media Telegram does not make viewable outside its own apps. Those rows are returned with the poster frame, the duration and
unavailableReasonset, so the post is never silently missing from your data. - Photo and video links point at Telegram's own storage. Treat them as fresh at collection time and download soon after a run rather than months later.
- View, reaction and subscriber counts are a snapshot at the moment of collection and keep changing afterwards.
- Telegram publishes very large counts in rounded form, so the biggest numbers are approximate. Every row says which of its numbers were rounded, so you never have to guess.
- Absent is not zero. Some channels publish no view counts and some publish no reactions at all. Those fields arrive as
null, which means "Telegram never published this" — not "this post got none". - A run only looks through the number of recent posts you set per channel, so anything older is left alone until you raise that number.
- One channel can answer on two different names. When two of the names you paste turn out to be the same channel, it is collected once and the run log names the pair — you are never charged twice for the same file.
- Occasionally a channel stops being readable part-way through a run. It keeps everything collected up to that point and the run log says the channel stopped early, so a truncated channel is never presented as a complete one.
- Some channels are restricted in some countries. The country setting is only used on a second attempt, after Telegram declines the first, so most runs are unaffected by it.
- Speed depends on the size of the job and on Telegram's own response times; no fixed throughput is promised.
- Telegram's terms govern automated access. You are responsible for using the data lawfully, in line with the source site's terms, and for handling any personal data in line with applicable privacy law.
FAQ
Do I need a Telegram account? No. Nothing is connected to any account of yours.
Does it need my phone number or a login? No. There is nothing to sign in to and nothing to authorise. You paste channel names and press start.
Can I schedule it? Yes. Schedule it on Apify to run hourly, daily or weekly, and each run writes a fresh dataset you can export or send onward.
Is the data complete? It is complete for what Telegram publishes publicly. Every image in an album is returned, not just the first. What it cannot give you is a file for attachments Telegram publishes no file for — files, audio, voice notes, and the occasional post whose media stays inside Telegram's own apps. Those are returned and marked, never quietly skipped.
Are photo albums one row or many?
Many — one row per image, each with its own link and its own place in the album (positionInPost of itemsInPost). Grouping rows by postId puts an album back together.
Can I actually download the files?
Yes. Every row where isDownloadable is true carries a direct link to the file itself, which any downloader or spreadsheet tool can fetch.
Why do some rows have no file link?
Because Telegram publishes none for that kind of attachment. unavailableReason says which case it is, and the row still carries the title, the caption, the timing and the engagement of the post it belongs to.
How do I get only videos? Set Media to collect to Videos alone. Photos and files are then left out entirely and you are not billed for them.
What happens if I paste a channel that does not exist? It is reported as unavailable, with the reason, and the rest of the run continues. You are never charged for it.