# Telegram Channel Scraper - Posts, Channel Info & Search (`vulnv/telegram-channel-scraper`) Actor

Scrape public Telegram channels: channel profile and subscriber counts, a channel's posts with views, reactions, media and link previews, single posts by t.me link, and keyword search inside a channel's recent posts. Export to JSON/CSV/Excel. No Telegram account or phone number needed.

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

## Pricing

from $2.00 / 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.

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, Channel Info & In-Channel Search

**Scrape public Telegram channels and export channel profiles and posts to JSON, CSV or Excel.** Get a channel's title, description, verified badge and subscriber count, pull its posts with views, reactions, photos, videos and link previews, fetch single posts by their t.me link, or search a channel's recent posts for a keyword - all from one Actor. Each result is one clean, flat row.

No Telegram account, no phone number, no session file and no proxies to configure - data is read from Telegram's public channel preview through a fast, managed pipeline. Just pick an operation, add your channels and press **Start**.

> **Unofficial notice:** This is an independent tool and is **not** affiliated with, endorsed by, or connected to Telegram or Telegram Messenger Inc. "Telegram" is a trademark of its respective owner, used here only to describe what the Actor scrapes.

### What is Telegram?

Telegram is a cloud messaging app with around a billion monthly users. Its public **channels** are one-to-many broadcast feeds used by news outlets, creators, brands, crypto projects, communities and public figures, some with tens of millions of subscribers. Every public channel has a web preview at `t.me/s/<channel>`. This scraper turns those public channels into structured data so you can monitor news, track engagement and archive posts at scale without logging in to Telegram.

### Operations

Pick one **Operation** and fill in the matching field:

| Operation | Input field | What you get |
|-----------|-------------|--------------|
| **Channel info** | `channels` | A channel's profile: title, description, verified badge, photo, subscribers, and photo / video / link counts. |
| **Channel posts** | `channels` | A channel's posts, newest first, paginated back through its history, with views, reactions, media and link previews. |
| **Post details** | `postUrls` | The full detail of each post from its t.me link. |
| **Search posts in a channel** | `channels` + `searchQuery` | Posts in each channel that contain your keyword. |

`channels` accept `https://t.me/<channel>` links, `@username` or a bare username. `postUrls` accept links like `https://t.me/durov/548` (or `durov/548`) - one per line.

**About in-channel search:** Telegram's public preview has no native search, so **Search posts in a channel** checks roughly the channel's **100 most recent posts**, not its full history. To scan older posts, use **Channel posts** with a higher limit and filter the results yourself. There is no global search across all of Telegram.

Only **public** channels can be scraped. Private channels, groups, and channels that have turned off their public web preview are skipped with a clear log message. Post comments and "similar channels" are not available from the public preview, so this Actor does not offer them.

### How to use it (step by step)

1. Choose an **Operation**.
2. Fill in the matching input:
   - Channel info / Channel posts -> add one or more **Channels** (e.g. `durov`, `https://t.me/telegram`).
   - Post details -> paste **Post URLs** (e.g. `https://t.me/durov/548`).
   - Search posts in a channel -> add **Channels** and a **Search keyword**.
3. Set **Maximum results per input** (default 100, or 0 for all available) for Channel posts and Search.
4. Press **Start**. Export the dataset as JSON, CSV, Excel, XML or via the API.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `operation` | string | **Required.** `channel_info`, `channel_posts`, `post_detail`, or `search_channel_posts`. |
| `channels` | array | Channel links, @usernames or usernames (for `channel_info`, `channel_posts`, `search_channel_posts`). |
| `postUrls` | array | Post links like `https://t.me/durov/548` (for `post_detail`). |
| `searchQuery` | string | Keyword to look for (for `search_channel_posts`). |
| `maxItems` | integer | Max results per channel. `0` = all available. Default `100`. |

### Output

Every row carries a `record_type` of `channel` or `post`. Post fields:

| Field | Description |
|-------|-------------|
| `post_id`, `channel`, `post_url` | Post identity and its public t.me link. |
| `post_type`, `date`, `text`, `author` | `text` / `photo` / `video`, publish time (ISO-8601 UTC), plain text and signature. |
| `views_count` | View count. |
| `reactions_count`, `paid_reactions_count`, `reactions` | Free emoji reactions, paid Star reactions, and the per-reaction breakdown. |
| `is_forwarded`, `forwarded_from`, `forwarded_from_url` | Forward source, when the post was forwarded. |
| `reply_to_url`, `reply_to_text` | The post this one replies to, when it is a reply. |
| `link_preview_url`, `link_preview_title`, `link_preview_site` | The link preview card. |
| `photo_count`, `photo_urls`, `video_count`, `video_urls`, `video_thumbnail_url`, `video_duration_seconds` | Attached media. |

Channel (`channel`) rows carry `channel_url`, `title`, `description`, `verified`, `photo_url`, `subscribers_count`, `photos_count`, `videos_count` and `links_count`. Search rows also carry the `search_query` that matched.

Telegram shows large numbers rounded (for example `1.81M` views or `13.8K` reactions). The Actor converts them to plain integers (`1810000`, `13800`), so treat big counts as approximate.

Example post row:

```json
{
  "record_type": "post",
  "operation": "post_detail",
  "input": "https://t.me/durov/548",
  "post_id": "548",
  "channel": "durov",
  "post_url": "https://t.me/durov/548",
  "post_type": "text",
  "date": "2026-09-11T16:04:02+00:00",
  "text": "Telegram has become the sponsor of Codeforces...",
  "author": "Pavel Durov",
  "views_count": 1810000,
  "reactions_count": 46370,
  "paid_reactions_count": 13800,
  "link_preview_url": "https://codeforces.com/blog/entry/156620",
  "photo_count": 0,
  "video_count": 0
}
```

### Common use cases

- **News and media monitoring** - follow news, government and industry channels and collect every new post.
- **Engagement tracking** - compare views and reactions across posts and channels over time.
- **Brand and crypto project monitoring** - watch announcements and mentions of a keyword inside the channels you care about.
- **Research and archiving** - build datasets of public channel posts, media links and forward chains.

### Notes on reliability

- Photo and video URLs are served by Telegram's CDN and are temporary; download them promptly if you need them.
- View and reaction counts reflect what Telegram shows at scrape time and are rounded for large numbers.
- Custom (premium) emoji reactions are counted, but their `emoji` is empty because Telegram does not expose them in the public preview.
- If a channel or post is private, deleted or unavailable, that input is skipped and the run continues.

### FAQ

**Do I need a Telegram account or phone number?** No. Just add your channels and press Start.

**Can I scrape private channels or groups?** No. Only public channels that have a public web preview can be scraped.

**Does the search cover the whole channel history?** No. It covers roughly the channel's 100 most recent posts. Use Channel posts to go further back.

**Can I get post comments?** No. Comments are not available from the public channel preview.

**Can I run several channels at once?** Yes - add multiple lines. Duplicate posts across inputs are removed automatically.

**Can I try it for free?** Yes. Users on the free Apify plan can fetch up to 10 results in total to try the Actor. Upgrade to a paid Apify plan to run it without that limit.

**What export formats are supported?** JSON, CSV, Excel, XML and HTML, plus the Apify API and integrations such as Google Sheets, Zapier, Make and webhooks.

### Pricing

This Actor is **pay per result**: you are charged for each record it returns (channel posts and channel profiles), plus standard Apify platform usage. Different record types have different prices; see the **Pricing** tab for current rates. You are never charged for inputs that return nothing.

### Related scrapers

- **[Threads Scraper](https://apify.com/vulnv/threads-scraper)** - Threads creators, profiles, posts and comments.
- **[X (Twitter) Comments Scraper](https://apify.com/vulnv/twitter-comments-scraper)** - export the replies to any tweet.
- **[Reddit Posts Search Scraper](https://apify.com/vulnv/reddit-posts-search-scraper)** - Reddit posts by keyword.

# Actor input Schema

## `operation` (type: `string`):

What to scrape. Each operation uses a different input field below:

• Channel info → Channels
• Channel posts → Channels
• Post details → Post URLs
• Search posts in a channel → Channels + Search keyword

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

For the "Channel info", "Channel posts" and "Search posts in a channel" operations. Paste public channel links (https://t.me/durov), @usernames or bare usernames - one per line.

## `postUrls` (type: `array`):

For the "Post details" operation. Paste public post links like https://t.me/durov/548 (or durov/548) - one per line.

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

For "Search posts in a channel" only. The keyword to look for in each channel's posts. The search covers roughly the channel's 100 most recent posts, not its full history.

## `maxItems` (type: `integer`):

Upper bound on results per channel (for Channel posts and Search). Cost scales linearly. Set 0 to fetch all available.

## Actor input object example

```json
{
  "operation": "channel_posts",
  "channels": [
    "durov",
    "telegram"
  ],
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped Telegram results in the default dataset.

## `overview` (type: `string`):

Overview table of the scraped results.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vulnv/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",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vulnv/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"
  ]
}' |
apify call vulnv/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vulnv/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/LBNQQUn4uo9DMFqWL/builds/FKrgYO34itdJv72rC/openapi.json
