# Telegram Channel Scraper: Whole Message History (`luzivanlt/telegram-channels-scraper`) Actor

A public Telegram channel's messages back to its first post, with views and every reaction. $0.50 per 1,000 messages. Media links, polls and the subscriber count.

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

## Pricing

from $0.35 / 1,000 messages

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: Whole Message History

Get a public Telegram channel's messages, newest first, all the way back to
its first post: the text, the date, views, every reaction (paid stars
included), photos, videos, files, polls, link previews, forwards and replies,
with the channel's title, description and subscriber count on every row.
Paste usernames or t.me links. No Telegram account needed.

Tested daily. Latest checks: two channels read whole, 424 and 426 messages
back to their oldest posts; 10,000 messages from five channels in 7 minutes.

### What does this Actor do?

You give it public Telegram channels. For each one it reads the channel's
messages from the newest back, about 20 at a time, and saves one row per
message until it reaches your limit, your date, or the channel's first
message.

Each message comes with:

- its link, id, date and type (text, photo, video, album, document, audio,
  voice, sticker, round video, location, poll, or service when you ask for
  service messages), and whether it was edited
- its text, as plain text and as HTML, with the links, hashtags and
  @mentions in it
- its view count, each reaction with its count, the reactions' total and the
  paid stars
- its photos and videos (links, thumbnails and lengths), files and audio
  (name and size or performer), its poll (question and each answer's share)
  and its link preview
- where it was forwarded from, and the message it replies to
- the author's signature, when the channel signs its posts
- the channel's id, username, title, description (and the links in it),
  picture, verified badge and its counts of subscribers, photos, videos, files and links

### Why use it?

- **The whole history, not just the latest.** This Actor keeps going to a
  channel's very first message, or stops at your limit or your date.
- **Start anywhere.** Paste a link to one post and the read starts there and
  goes back.
- **Every reaction, counted.** Each emoji's count, plus the paid stars, not
  just a total.
- **The channel on every row.** Subscribers and the channel's media counts
  sit beside each message, so one export compares channels.
- **Monitor a channel.** Run it daily with **Only messages newer than** set to
  `1 day`.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Paste one or more channels into **Channels**: `durov`, `@durov`,
   `https://t.me/durov` and `https://t.me/s/durov` all work. A post link such
   as `https://t.me/durov/300` starts at that post.
2. Optionally, set **Only messages newer than** and **Max messages per
   channel**.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   messages or download them.

Only public channels can be read. Invite links (`t.me/+…`, `t.me/joinchat/…`),
private channels, groups, users and bots are not supported. Put one channel
on each line of the list.

Run it with no input to see a sample: up to 500 messages each from two public
channels, @durov and @telegram, charged as usual.

### Input

| Field                                                   | What it does                                                                                                  | Default |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------- |
| **Channels** (`channels`)                               | The channels to read: usernames, channel links or post links. Required.                                       | —       |
| **Only messages newer than** (`onlyMessagesNewerThan`)  | A date (`YYYY-MM-DD`, UTC) or a period (`7 days`, `2 weeks`, `3 months`, `1 year`). Empty = the whole history | empty   |
| **Max messages per channel** (`maxMessagesPerChannel`)  | Stop reading a channel after this many messages, from 1 to 50,000                                             | `100`   |
| **Include service messages** (`includeServiceMessages`) | Also save service messages such as "Channel created"                                                          | off     |
| **Only new messages** (`onlyNewItems`)                  | Return only the messages an earlier run did not; see New items only below                                     | off     |

Example input:

```json
{
  "channels": ["https://t.me/durov", "telegram"],
  "onlyMessagesNewerThan": "30 days",
  "maxMessagesPerChannel": 1000
}
```

### New items only

Turn on **Only new messages** (`onlyNewItems`) for a scheduled run, or a
re-run of the same task. Each run then returns only the messages it has not
returned before: it reads each channel back to a day before the last run that
read it, and skips the messages an earlier run saved. Skipped messages are
neither saved nor charged; each new message is charged as usual.

- Runs with other settings, or from another task, keep their own list, so two
  schedules on one channel never skip each other's messages.
- If a channel stops at **Max messages per channel**, the messages past that
  point are not returned later. Set the maximum above what one channel gets
  between runs.
- The list lives in your Apify account, in a key-value store named
  `telegram-channels-scraper-monitor`. Delete it to start afresh.

### Output

One row per message. An example, shortened:

```json
{
  "url": "https://t.me/example_channel/1234",
  "message_id": 1234,
  "type": "album",
  "date": "2026-10-11T14:52:40+00:00",
  "edited": false,
  "text": "Two photos and a video from today.",
  "views": 1040000,
  "views_text": "1.04M",
  "reactions": [
    { "emoji": null, "emoji_id": null, "paid": true, "count": 5720, "count_text": "5.72K" },
    { "emoji": "👍", "emoji_id": null, "paid": false, "count": 12300, "count_text": "12.3K" }
  ],
  "reactions_total": 12300,
  "paid_stars": 5720,
  "photo_urls": ["https://cdn4.telesco.pe/file/…jpg", "https://cdn4.telesco.pe/file/…jpg"],
  "video_urls": ["https://cdn4.telesco.pe/file/…mp4"],
  "is_forwarded": false,
  "channel_id": "1000000001",
  "channel_username": "example_channel",
  "channel_title": "Example Channel",
  "channel_subscribers": 10300000,
  "channel_photos": 102,
  "channel_videos": 47,
  "channel_links": 200
}
```

| Field                                                                | What it is                                                                                                                                                                       |
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`                                                                | The message's link                                                                                                                                                               |
| `message_id`                                                         | The message's number in its channel                                                                                                                                              |
| `type`                                                               | `text`, `photo`, `video`, `album`, `document`, `audio`, `voice`, `sticker`, `round_video`, `location`, `poll` or `service`                                                       |
| `date`                                                               | When it was posted (UTC)                                                                                                                                                         |
| `edited`                                                             | `true` when it was edited                                                                                                                                                        |
| `text`                                                               | Its text, or its caption; `null` when it has none                                                                                                                                |
| `text_html`                                                          | The same text with its formatting and links, as HTML                                                                                                                             |
| `author_signature`                                                   | The author's name, when the channel signs its posts                                                                                                                              |
| `views`                                                              | Its views, as a number (Telegram rounds large counts: 1.04M reads as 1040000)                                                                                                    |
| `views_text`                                                         | The views as Telegram shows them                                                                                                                                                 |
| `reactions`                                                          | Each reaction: `emoji` (or `emoji_id` for a custom emoji), `paid` for paid stars, `count` and `count_text`                                                                       |
| `reactions_total`                                                    | The reactions added up, paid stars left out                                                                                                                                      |
| `paid_stars`                                                         | The paid stars it received                                                                                                                                                       |
| `links`                                                              | The links in its text                                                                                                                                                            |
| `hashtags`, `mentions`                                               | The `#hashtags` and `@usernames` in its text                                                                                                                                     |
| `media`                                                              | Each photo, video, file, audio, voice note, sticker or location: `type`, `url`, `thumbnail_url`, `duration`, `title`, `details` (a file's size or a song's performer) and `link` |
| `photo_urls`, `video_urls`                                           | The photo and video links on their own                                                                                                                                           |
| `poll`                                                               | Its poll: `question`, `type` and each answer's `text` and `percent`                                                                                                              |
| `link_preview`                                                       | The preview of the link it shares: `url`, `site_name`, `title`, `description` and `image_url`                                                                                    |
| `is_forwarded`                                                       | `true` when it was forwarded from elsewhere                                                                                                                                      |
| `forwarded_from_name`, `forwarded_from_url`                          | Where it was forwarded from, when Telegram shows it                                                                                                                              |
| `reply_to_message_id`, `reply_to_url`                                | The message it replies to                                                                                                                                                        |
| `reply_to_author`, `reply_to_text`                                   | That message's author and the start of its text                                                                                                                                  |
| `channel_id`                                                         | Telegram's id for the channel                                                                                                                                                    |
| `channel_username`, `channel_url`                                    | The channel's username and link                                                                                                                                                  |
| `channel_title`, `channel_description`                               | The channel's name and description                                                                                                                                               |
| `channel_description_links`                                          | The links in the channel's description                                                                                                                                           |
| `channel_verified`                                                   | `true` when the channel has the verified badge                                                                                                                                   |
| `channel_photo_url`                                                  | The channel's picture                                                                                                                                                            |
| `channel_subscribers`                                                | Its subscribers when it was read (rounded as Telegram shows it); `channel_subscribers_text` is the shown value                                                                   |
| `channel_photos`, `channel_videos`, `channel_files`, `channel_links` | The channel's counts of photos, videos, files and links; `null` when it shows none                                                                                               |
| `source_link`                                                        | The channel this message was read from                                                                                                                                           |

Not included: comments under posts, the files themselves (only links to
photos and videos, and the names of files), and the link of a video too large
to play outside the Telegram app (it keeps its thumbnail and length).

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

You pay for what you get:

- **$0.50 per 1,000 messages** ($0.0005 a message). Each message is charged once per run.
- No start fee, and nothing per channel.

So 1,000 messages from each of 3 channels cost $1.50. If you set a maximum cost for a run, the Actor stops when it reaches it and keeps every message saved so far.

### How long does a run take?

About 275 messages a minute from each channel, with up to five channels read
at once: 2,000 messages from each of five channels took 7 minutes.

### Good to know

- **Check your input first.** A link that is not a Telegram channel or post
  link stops the run before anything is read, and the message names it.
- **One channel that cannot be read does not stop the run.** A name that is a
  user, a bot, a group, a private channel or no one at all ends with a
  message, the others carry on, and the run's status lists the channels that
  could not be read. The run fails only when no channel could be read.
- **Counts are rounded.** Telegram shows large views, reactions and
  subscriber counts rounded (`10.3M`); the number fields hold that rounded
  value and the `_text` fields what Telegram shows.
- **Counts move.** Views and reactions are the numbers at the moment the
  message was read.
- **Media links expire.** Photo and video links point at Telegram's servers
  and stop working after a while: download what you need soon after the run.
- **An album is one row.** Several photos or videos sent together are one
  message with several entries in `media`.
- **Remove repeats by `url`.** A daily run reads recent messages again,
  unless **Only new messages** is on.

### More Actors from us

- [AliExpress Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/aliexpress-products-scraper): Every product of an AliExpress search to its last page, with exact sold counts and ratings.
- [Amazon Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/amazon-products-scraper): Every product on Amazon's search pages to the last page, sponsored marked, with monthly sales.
- [App Store Reviews Scraper: All Reviews, Not 500](https://apify.com/luzivanlt/app-store-reviews-scraper): Every written App Store review of an app, not just the newest 500.
- [Facebook Ads Library Scraper: Meta Ads by Keyword or Page](https://apify.com/luzivanlt/facebook-ads-library-scraper): Meta Ad Library ads by keyword, Page or Ad Library link, with text, images, videos and dates.
- [Facebook Comments Scraper: With Replies](https://apify.com/luzivanlt/facebook-comments-scraper): Comments and replies from public Facebook posts, reels and videos, with reactions by type.
- [Facebook Pages Scraper: Contacts, Followers & Ratings](https://apify.com/luzivanlt/facebook-pages-scraper): Facebook Page details from links: exact follower count, phone, email, address, websites.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~telegram-channels-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "channels": ["https://t.me/durov", "telegram"],
  "maxMessagesPerChannel": 500,
  "includeServiceMessages": false
}
```

Its inputs, in the order of the input form:

| Input                                               | What it takes                                                                                                                                                                                                                                               | Default |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `channels` (Channels)                               | Public Telegram channels to read: a username (durov or @durov), a channel link (https://t.me/durov, t.me/s/durov or telegram.me/durov) or a link to one of its posts (https://t.me/durov/300), which starts the read at that post and goes back from there. | —       |
| `onlyMessagesNewerThan` (Only messages newer than)  | Keep only messages from this date on: a date (YYYY-MM-DD, UTC) or a period, e.g. "7 days", "2 weeks", "3 months" or "1 year".                                                                                                                               | —       |
| `maxMessagesPerChannel` (Max messages per channel)  | Stop reading a channel after this many messages, newest first, from 1 to 50,000.                                                                                                                                                                            | `100`   |
| `includeServiceMessages` (Include service messages) | Also save the channel's service messages, such as "Channel created" or a new channel photo.                                                                                                                                                                 | `false` |
| `onlyNewItems` (Only new messages)                  | Turn this on for a scheduled run, or a re-run of the same task: each run then returns only the messages it has not returned before, reading each channel back to a day before the last run that read it.                                                    | —       |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/telegram-channels-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=luzivanlt/telegram-channels-scraper"
    }
  }
}
```

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per message delivered; the sample input above costs at most $0.50.

### FAQ

**Do I need a Telegram account?**
No. The Actor reads what anyone can see in a public channel.

**Can it read private channels or groups?**
No, only public channels.

**Can it read the comments under a post?**
Not yet: this Actor reads the channel's own messages.

**Can I search Telegram by keyword?**
Not yet: this Actor reads the channels you give it.

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/telegram-channels-scraper/changelog.md

# Actor input Schema

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

Public Telegram channels to read: a username (durov or @durov), a channel link (https://t.me/durov, t.me/s/durov or telegram.me/durov) or a link to one of its posts (https://t.me/durov/300), which starts the read at that post and goes back from there. Each channel gives you its messages, newest first. Invite links (t.me/+…) and private channels cannot be read. Example: telegram

## `onlyMessagesNewerThan` (type: `string`):

Keep only messages from this date on: a date (YYYY-MM-DD, UTC) or a period, e.g. "7 days", "2 weeks", "3 months" or "1 year". The date cannot be in the future. Applies to every channel; older messages are not saved or charged. Leave empty for the whole history.

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

Stop reading a channel after this many messages, newest first, from 1 to 50,000. The form starts at 500; left empty, it is 100. Each message is charged once ($0.50 per 1,000 messages), so this caps what one channel costs: 1,000 messages cost at most $0.50.

## `includeServiceMessages` (type: `boolean`):

Also save the channel's service messages, such as "Channel created" or a new channel photo. Off by default: they carry no post. When on, each service message saved is a row, charged like any other message.

## `onlyNewItems` (type: `boolean`):

Turn this on for a scheduled run, or a re-run of the same task: each run then returns only the messages it has not returned before, reading each channel back to a day before the last run that read it. Skipped messages are neither saved nor charged; each new message is charged as usual. Runs with other settings, or from another task, keep their own list. Off by default.

## Actor input object example

```json
{
  "channels": [
    "https://t.me/durov",
    "telegram"
  ],
  "maxMessagesPerChannel": 500,
  "includeServiceMessages": false
}
```

# Actor output Schema

## `messages` (type: `string`):

Every message the run saved, one row per message.

## `allFields` (type: `string`):

The same rows with every field.

# 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": [
        "https://t.me/durov",
        "telegram"
    ],
    "maxMessagesPerChannel": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/telegram-channels-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": [
        "https://t.me/durov",
        "telegram",
    ],
    "maxMessagesPerChannel": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/telegram-channels-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": [
    "https://t.me/durov",
    "telegram"
  ],
  "maxMessagesPerChannel": 500
}' |
apify call luzivanlt/telegram-channels-scraper --silent --output-dataset

```

## MCP server setup

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