# Telegram Channel Scraper: Posts, Views, Reactions & Media (`kuezi/telegram-channel-scraper`) Actor

Scrape any public Telegram channel without login or API keys: posts with full text, date, views, reactions, photos, videos, links, link previews and forwards, plus channel stats. Search inside channels, filter by date, monitor for new posts.

- **URL**: https://apify.com/kuezi/telegram-channel-scraper.md
- **Developed by:** [Ishema Hugues](https://apify.com/kuezi) (community)
- **Categories:** Social media, News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Telegram Channel Scraper: posts, views, reactions and media

Scrape any **public Telegram channel** without logging in, without a Telegram account and without API keys. Each post comes with:

- full text (line breaks kept);
- date, **view count**, reactions and paid stars;
- photos, videos (file and thumbnail) and documents;
- links, link previews, forwards, replies, polls, hashtags and mentions.

Every run also records **channel stats**: title, description, subscriber count, photo, video and link counts, and the verified badge.

**Why this one:**

- **$0.50 per 1,000 posts.** No start fee, no monthly rent.
- **Newest posts first**, paging back as far as you want (`maxMessagesPerChannel`).
- **Search inside a channel** with Telegram's own search (`searchQuery`).
- **Date filters**: the Actor stops paging as soon as it passes `dateFrom`, so you don't pay for old posts.
- **Monitoring mode** (`onlyNewMessages`): schedule it and each run returns only posts published since the last run.
- Clean numbers: `18.9M` views becomes `18900000`.

### Use cases

- **Crypto, trading and news monitoring:** follow signal, announcement and news channels and push new posts to Slack, Sheets or your own pipeline.
- **Brand and competitor tracking:** see what competitors post and which posts get the most views and reactions.
- **Research and OSINT:** archive public channels with dates, views and forwards for analysis.
- **Content and growth analysis:** compare engagement (views, reactions) across channels and over time.
- **AI and LLM pipelines:** feed clean post text plus metadata into RAG, summarization or sentiment models.

### Ready-made tasks (one click to run)

Start from a saved setup and change the inputs to your own:

- [Monitor new posts from crypto Telegram channels](https://apify.com/kuezi/telegram-channel-scraper/examples/monitor-crypto-telegram-channels)
- [Export a Telegram channel's posts with views to CSV](https://apify.com/kuezi/telegram-channel-scraper/examples/export-telegram-channel-to-csv)
- [Search a Telegram channel for keywords](https://apify.com/kuezi/telegram-channel-scraper/examples/search-telegram-channel-keywords)
- [Compare Telegram channels' subscribers and engagement](https://apify.com/kuezi/telegram-channel-scraper/examples/telegram-channel-engagement-stats)

### Input

| Field | What it does |
|---|---|
| `channels` | Usernames (`durov`), `@username` or links (`https://t.me/durov`). |
| `maxMessagesPerChannel` | Number of newest posts to save per channel (default 100). |
| `searchQuery` | Optional. Only posts matching this text. |
| `dateFrom` / `dateTo` | Only posts in this date range (YYYY-MM-DD). |
| `onlyNewMessages` | Monitoring: only posts newer than the newest one seen in previous runs. |

```json
{
  "channels": ["durov", "https://t.me/telegram"],
  "maxMessagesPerChannel": 500,
  "dateFrom": "2026-01-01"
}
```

### Output

One row per post (a real result from a test run on 2026-10-02):

```json
{
  "channel": "telegram",
  "messageId": 460,
  "url": "https://t.me/telegram/460",
  "date": "2026-08-26T19:12:34+00:00",
  "text": "For all the info from today's update and a look back at 13 years of Telegram features — check out our blog:\nhttps://telegram.org/blog/welcome-messages-buttons-TG-13\n\nAugust Features\n1 • 2 • 3 • 4 • 5 • More",
  "views": 1600000,
  "author": null,
  "isEdited": false,
  "forwardedFrom": null,
  "replyTo": null,
  "hashtags": [],
  "mentions": [],
  "links": ["https://telegram.org/blog/welcome-messages-buttons-TG-13", "https://t.me/telegram/455"],
  "reactions": [],
  "paidStars": null,
  "photos": [],
  "videos": [],
  "documents": [],
  "linkPreview": {
    "url": "https://telegram.org/blog/welcome-messages-buttons-TG-13",
    "siteName": "Telegram",
    "title": "Welcome Messages, Buttons in Messages and Signed Gifts",
    "description": "Introducing Welcome Messages to greet new members of groups or channels, Buttons in Messages to make any text interactive, Inline Documents in Messages and much more.",
    "imageUrl": "https://cdn4.telesco.pe/file/..."
  },
  "poll": null,
  "channelTitle": "Telegram News",
  "channelSubscribers": 9420000,
  "scrapedAt": "2026-10-02T11:49:42.410Z"
}
```

Reactions look like `{ "emoji": "👍", "count": 1200 }`. For a Telegram custom emoji, the `emoji` field is empty and `customEmojiId` is set instead. Video rows include the `.mp4` URL and a thumbnail.

The `SUMMARY` record holds channel stats for each channel: title, username, description, photo, verified, subscribers, photos, videos, links and files.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Post saved (`message`) | **$0.0005** ($0.50 per 1,000) |
| Channel stats (`channel-info`) | $0.001 per channel per run |

Failed or private channels are never charged. Set a maximum cost per run and the Actor stops cleanly.

### Notes and limits

- **Public channels only.** That means channels that have a public `t.me/s/<name>` web preview. Private channels, groups, bots and user accounts have no public preview and are reported in `FAILED`.
- Some posts carry media that Telegram's web preview doesn't show, such as certain stickers or polls in some clients. Those posts still come with their text, date and views, and `hasUnsupportedMedia` is set to `true`.
- Media URLs come from Telegram's CDN and expire after some time. Download them during the run if you need to keep them.
- View counts are rounded by Telegram (for example `1.6M`).

### FAQ

**Do I need a Telegram account or API key?** No. The Actor reads the public web preview Telegram shows to everyone.

**How far back can it go?** As far back as the channel's history goes. It pages 20 posts at a time. Use `dateFrom` to stop early.

**How do I get only new posts every hour?**

1. Turn on `onlyNewMessages`.
2. Save the input as a task.
3. Schedule it.

Connect the dataset to Slack, Google Sheets, a webhook or Zapier with Apify integrations.

### More from the same developer

- [Google Ads Transparency Scraper](https://apify.com/kuezi/google-ads-transparency-scraper): competitors' ads, ad copy and landing pages.
- [Google Trends Scraper](https://apify.com/kuezi/google-trends-scraper): unlimited keywords on one scale, breakouts, Trending Now.
- [Google Flights Scraper](https://apify.com/kuezi/google-flights-scraper) and [Google Hotels Scraper](https://apify.com/kuezi/google-hotels-scraper).

# Actor input Schema

## `channels` (type: `array`):

Public channels: username (durov), @username or link (https://t.me/durov). One per line.

## `maxMessagesPerChannel` (type: `integer`):

Newest posts first. The Actor pages back through the channel until it has this many.

## `searchQuery` (type: `string`):

Optional. Only posts that match this word or phrase (Telegram's own channel search).

## `dateFrom` (type: `string`):

Only posts on or after this date (YYYY-MM-DD). The Actor stops paging once it reaches older posts.

## `dateTo` (type: `string`):

Only posts on or before this date (YYYY-MM-DD).

## `onlyNewMessages` (type: `boolean`):

Remembers the newest post seen for each channel (and search) and only returns posts published after it. Schedule the Actor to get a feed of new posts.

## `maxRetries` (type: `integer`):

Retries for a page that fails to load.

## `proxyConfiguration` (type: `object`):

Telegram's public pages usually work without a proxy. Turn on Apify Proxy if you scrape thousands of pages quickly.

## Actor input object example

```json
{
  "channels": [
    "durov",
    "telegram"
  ],
  "maxMessagesPerChannel": 100,
  "onlyNewMessages": false,
  "maxRetries": 4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `posts` (type: `string`):

One row per post: channel, ID, date, text, views, reactions, media, links.

## `fullResults` (type: `string`):

Every field, including link previews, polls, replies, hashtags and mentions.

## `summary` (type: `string`):

Per channel: title, description, subscribers, photo/video/link counts, verified flag and posts saved.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "channels": [
        "durov",
        "telegram"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kuezi/telegram-channel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "channels": [
        "durov",
        "telegram",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("kuezi/telegram-channel-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "channels": [
    "durov",
    "telegram"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call kuezi/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kuezi/telegram-channel-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/IcVBgQ8d28YoKbQKf/builds/0AbHxfM2YfrvWkEG9/openapi.json
