# Telegram Channel Scraper (`tortuga/telegram-channel-scraper`) Actor

Scrape posts, views, media links and channel info from any public Telegram channel without login or API keys.

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

## Pricing

from $2.00 / 1,000 result items

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Telegram Channel Scraper

Scrape posts, views, media links and channel info from any public Telegram channel without login or API keys.

Telegram Channel Scraper reads the public web preview of a channel (`https://t.me/s/<channel>`) and turns it into a clean dataset: every post with its text, date, view count, photos, videos, documents, polls, link previews, forwards, replies and reactions, plus one channel-info item with the subscriber count. No Telegram account, phone number, bot token or API ID is needed. Download the results as JSON, CSV or Excel, or pull them through the API into Google Sheets, n8n, or an LLM pipeline. You pay only for the items you get.

### What data does Telegram Channel Scraper extract?

Each run produces two kinds of items, distinguished by the `type` field.

#### Post items (`type: "post"`)

| Field | Description |
|---|---|
| `channel` | Channel username, e.g. `telegram` |
| `postId` | Numeric message id inside the channel |
| `url` | Permalink, `https://t.me/<channel>/<postId>` |
| `date` | Publish time, ISO 8601 with timezone (`2026-05-14T16:08:31+00:00`) |
| `text` | Plain text with line breaks preserved |
| `textHtml` | Original formatted HTML (bold, links, spoilers, emoji) |
| `views` | View count as an integer (`1.4M` becomes `1400000`) |
| `author` | Post signature, when the channel signs posts |
| `isEdited` | `true` when the post was edited |
| `forwardedFrom` | `{name, url, author}` of the original channel/user for forwarded posts |
| `replyToPostId`, `replyToUrl` | The post this one replies to (comments-style replies inside the channel) |
| `media` | List of attachments, see below |
| `links` | All URLs in the text |
| `hashtags` | Hashtags in the text, without `#` |
| `mentions` | `@usernames` mentioned in the text, without `@` |
| `reactions` | `[{emoji, count}]` when the channel shows reactions |
| `isPinned` | Always `null`: the web preview does not expose pinned status |

Media entries have a `type` of `photo`, `video`, `round_video`, `audio`, `voice`, `document`, `sticker`, `location`, `poll` or `link_preview`, plus whatever is available for that type: `url` (direct CDN file link for photos, videos, voice and stickers), `thumbnail`, `duration` in seconds, `title`/`extra` for documents and audio, `question`/`options`/`voters` for polls and `siteName`/`title`/`description` for link previews.

#### Channel items (`type: "channel"`)

| Field | Description |
|---|---|
| `username` | Channel username |
| `url` | `https://t.me/<username>` |
| `title` | Display name |
| `description` | Channel bio |
| `subscribers` | Subscriber count as an integer (`9.61M` becomes `9610000`) |
| `photosCount`, `videosCount`, `filesCount`, `linksCount` | Media counters when Telegram shows them |
| `photoUrl` | Channel avatar |
| `isVerified` | Verified badge present |
| `webPreview` | `true` when posts are available; `false` when only the channel card could be read |

### How to use Telegram Channel Scraper

1. Paste channel usernames or links into **Channels**, one per line: `durov`, `@telegram`, `https://t.me/telegram`.
2. Set **Max posts per channel** (newest first) and **Max items** to cap the run and the cost.
3. Leave **Include channel info** on if you want the subscriber count and description.
4. Click **Start**. Results appear in the **Dataset** tab; export from there or use the API.

### Input example

```json
{
  "channels": ["telegram", "https://t.me/durov"],
  "maxPostsPerChannel": 100,
  "maxItems": 500,
  "includeChannelInfo": true
}
```

### Output example

```json
{
  "type": "post",
  "channel": "telegram",
  "postId": 441,
  "url": "https://t.me/telegram/441",
  "date": "2026-05-14T16:08:31+00:00",
  "text": "Bot-to-Bot Communication. Bots are now able to respond to other bots, not just users.\n\nAI enthusiasts can utilize this to create custom workflows with autonomous agents.",
  "textHtml": "<b>Bot-to-Bot Communication.</b> Bots are now able to respond to <b>other bots</b>, not just users.<br/><br/>…",
  "views": 1400000,
  "author": null,
  "isEdited": false,
  "forwardedFrom": null,
  "replyToPostId": null,
  "media": [
    {
      "type": "video",
      "url": "https://cdn1.telesco.pe/file/c01503a63e.mp4?token=…",
      "thumbnail": "https://cdn1.telesco.pe/file/ar1oQlpf….jpg",
      "duration": 6
    }
  ],
  "links": ["https://t.me/telegram/440"],
  "hashtags": [],
  "mentions": [],
  "reactions": []
}
```

```json
{
  "type": "channel",
  "username": "telegram",
  "url": "https://t.me/telegram",
  "title": "Telegram News",
  "description": "The official Telegram on Telegram. Much recursion. Very Telegram. Wow.",
  "subscribers": 9610000,
  "photosCount": 16,
  "videosCount": 228,
  "linksCount": 378,
  "photoUrl": "https://cdn1.telesco.pe/file/….jpg",
  "isVerified": true
}
```

### Does it work without a Telegram account or API key?

Yes. The scraper uses only the public web preview that Telegram publishes for every public channel, the same page you see when you open `https://t.me/s/telegram` in a browser while logged out. No account, phone number, session file, bot token or `api_id`/`api_hash` is required, so there is nothing that can get banned.

### How to scrape the full history of a Telegram channel

Set **Max posts per channel** to the number you need (and **Max items** at least as high). The scraper starts from the newest post and walks back through the history 20 posts per page until it reaches your limit or the first post of the channel. Every run re-reads from the top, so to keep a channel up to date schedule the Actor and use the `url` field to deduplicate.

### Can it scrape private channels, groups or user chats?

No, and it never tries to. Only public channels with a username are supported. Invite links (`t.me/+…`, `t.me/joinchat/…`), private `t.me/c/…` links, groups and personal accounts are skipped with a clear message in the run log. A small number of public channels have the web preview switched off by their owner; for those the scraper can still return the channel card (title, description, subscriber count) but not the posts.

### How to get Telegram post views and subscriber counts as numbers

Telegram shows counters as `1.4M` or `9.61K`. The scraper converts them into plain integers (`views`, `subscribers`, `voters`, reaction `count`) so they sort and sum correctly in spreadsheets and databases. Note that the displayed value is rounded by Telegram, so `1.4M` means roughly 1.4 million, not an exact figure.

### Can I download the photos and videos?

Every photo, video, voice message and sticker comes with a direct `url` on Telegram's CDN, and videos also include a `thumbnail` and `duration`. Video links carry a time-limited token, so download them shortly after the run if you need the files themselves. Large videos that Telegram does not stream in the browser only provide a thumbnail.

### Pricing

Pay per result: each post or channel-info item costs a fraction of a cent, with no subscription and no minimum. Apify's free plan is enough to try it on a few thousand posts.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets, or schedule the Actor to keep a channel archive fresh.

### Is it legal to scrape Telegram?

This Actor collects only publicly available, non-personal data: content that Telegram itself publishes on the open web for anyone to read without an account. It does not access private channels, groups or direct messages and does not collect phone numbers or user profiles. You are responsible for how you use the data and for complying with Telegram's terms and applicable law, including the copyright of channel owners.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

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

Public channel usernames or links, one per line: `durov`, `@telegram`, `https://t.me/telegram` or `https://t.me/s/telegram`. Private channels, invite links (t.me/+...) and groups are skipped.

## `maxPostsPerChannel` (type: `integer`):

Newest posts to collect from each channel. History is walked 20 posts per page, oldest available first at the end.

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

Overall cap on dataset items across all channels (posts plus channel-info items). Keeps cost predictable.

## `includeChannelInfo` (type: `boolean`):

Push one `type: "channel"` item per channel with title, description, subscriber count, photo and media counters.

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

Apify Proxy is recommended for reliability when scraping many channels; t.me does not currently block datacenter IPs.

## Actor input object example

```json
{
  "channels": [
    "telegram",
    "durov"
  ],
  "maxPostsPerChannel": 100,
  "maxItems": 500,
  "includeChannelInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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": [
        "telegram",
        "durov"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/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": [
        "telegram",
        "durov",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/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": [
    "telegram",
    "durov"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

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