# How to download a public Telegram channel's posts to CSV with Python (no API key, no phone number)

> **AI-assistance note:** this article and the example code were written with the help of an AI assistant (Claude, by Anthropic). The code was run and the numbers below come from a real run on 26 Oct 2026. I also built the Actor used here, so I am not a neutral reviewer of it.

Telegram's official API needs an account, a phone number and an app registration. For *public* channels there is an easier door: Telegram publishes a web preview of every public channel at `t.me/s/<channel>`. It shows the latest posts with text, date, views and reactions, 20 posts per page.

You can read that page yourself, but a real job needs more than one request: paging backwards, retries when Telegram answers 429, parsing the markup, turning `5.84M` into a number, telling a forwarded post from an original one. Here is the short route.

## What you need

- A free Apify account. The free plan includes $5 of platform credit per month, and Apify's pricing page says paid Store Actors draw on the same credits.
- The [Telegram Channel Posts Scraper](https://apify.com/kilometric_camp/telegram-channel-posts-scraper) Actor. I built it. It costs $1 per 1,000 results (a post or a channel summary row each count as one), with no start fee. By my arithmetic the free credit covers about 5,000 posts a month.
- Python 3.11+ (required by the current `apify-client`) and two small scripts from [this repo](https://github.com/thecbstudio/telegram-channel-posts-examples) (MIT).

## Download the posts

```bash
pip install -r requirements.txt
export APIFY_TOKEN=...        # Apify Console -> Settings -> API & integrations
python fetch_posts.py durov telegram --max 60
```

You get `posts.csv` with channel, post link, date (UTC), views, reactions, media types, hashtags and text. Filters help for real work: `--since "30 days"` and `--keywords price launch` keep only recent posts that mention your words.

## What the data showed

I ran it on two official channels, 60 posts each (26 Oct 2026):

| Channel | Subscribers | Posts covered | Median views | Best post |
| --- | --- | --- | --- | --- |
| durov | 10.2M | 13 Apr – 11 Oct 2026 | 4.74M | 24.4M (15 Jun) |
| telegram | 9.24M | 18 Aug 2025 – 26 Aug 2026 | 2.06M | 3.88M (2 Sep 2025) |

A few things a report like this makes easy to see:

- **When they post.** Most posts of the durov channel went out at 15:00 UTC (10 of 60), then 14:00 and 17:00 (7 each). The `telegram` channel clusters at 16:00–17:00 UTC (30 of 60).
- **What got the most views.** The three biggest durov posts were a contest announcement, a formatting update and a policy post, with 24.4M, 23.2M and 19.0M views.
- **Media vs text.** Text-only durov posts averaged 7.35M views, photo posts 4.81M. That is 33 versus 9 posts, so treat it as a hint, not a rule.

```bash
python channel_report.py posts.csv
```

prints this kind of summary for any CSV you make.

## Limits to know about

- Only channels whose public web preview is switched on can be read. Private channels, groups, users and bots cannot.
- Telegram rounds big numbers on that page, so views and subscribers above a few thousand are approximate.
- Media links are temporary, so download files soon after the run.
- There is no search across all of Telegram. You give the channels, the keyword filter works inside each one.
- Be careful with personal data. Follow Telegram's terms and the privacy laws that apply to you.

## Try it, tell me what breaks

If a channel returns nothing or a field looks wrong, open an issue on the repo or on the Actor page with the channel name and what you expected. I read them.

*Not affiliated with Telegram.*
