# Telegram Channel Scraper - Messages & Views (`thirdwatch/telegram-scraper`) Actor

Scrape public Telegram channel messages via the t.me/s/ web preview. Get message text, view counts, timestamps, author/signature, media flags, forwards, and message URLs. Optional keyword filter. No login, API key, or proxy needed.

- **URL**: https://apify.com/thirdwatch/telegram-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Social media
- **Stats:** 3 total users, 2 monthly users, 80.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 public Telegram channel messages by username, with view counts, timestamps, media flags, and forwards. Use it for OSINT, brand and crypto monitoring, news tracking, market intelligence, research datasets, and trend discovery.

### What you get

Public Telegram channels are a fast-moving source of announcements, news, and community chatter, but Telegram has no official export for non-members. This actor reads any public channel and converts its posts into clean dataset rows with message text, view count, date, author/signature, media flags, forward info, and a direct message URL, so you can schedule monitoring or export history without joining channels or wrangling raw web pages yourself.

Best fit:

- OSINT and research teams tracking public channels.
- Crypto, markets, and news teams watching announcement channels.
- Brand and comms teams monitoring mentions and leaks.
- Analysts building repeatable message datasets.
- Builders feeding Telegram content into alerts, dashboards, or LLM pipelines.

### Output fields

| Field | Description |
|-------|-------------|
| `channel` | Channel username scraped |
| `message_id` | Numeric message id within the channel |
| `text` | Message text (line breaks preserved) |
| `views` | View count as displayed (e.g. `12.3K`) |
| `datetime` | ISO-8601 publish timestamp |
| `author` | Post signature / author name when present |
| `has_photo` | Message contains a photo |
| `has_video` | Message contains a video or round video |
| `has_document` | Message contains a file, voice, or audio |
| `has_poll` | Message is a poll |
| `has_sticker` | Message is a sticker |
| `is_forwarded` | Message is a forward |
| `forwarded_from` | Original source name when forwarded |
| `is_reply` | Message is a reply |
| `url` | Direct link to the message |

### Input parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `channel` | Yes | Public channel username or `t.me` link (e.g. `durov` or `https://t.me/durov`). |
| `keyword` | No | Only return messages containing this text (case-insensitive). |
| `maxMessages` | No | Maximum messages to return, newest first (default 50). Start small to control cost; raise to pull deeper history. |

#### Example inputs

##### Latest 50 messages from a channel

```json
{
  "channel": "durov",
  "maxMessages": 50
}
````

#### Keyword filter across recent history

```json
{
  "channel": "telegram",
  "keyword": "update",
  "maxMessages": 200
}
```

#### Deep history pull

```json
{
  "channel": "durov",
  "maxMessages": 1000
}
```

You can also paste a full URL such as `https://t.me/durov` or `https://t.me/s/durov` for the `channel` field; it is normalized to the username automatically.

### Example output

```json
{
  "channel": "durov",
  "message_id": 351,
  "text": "Telegram now has 900 million monthly active users.",
  "views": "1.2M",
  "datetime": "2026-03-21T14:05:11+00:00",
  "author": "",
  "has_photo": true,
  "has_video": false,
  "has_document": false,
  "has_poll": false,
  "has_sticker": false,
  "is_forwarded": false,
  "forwarded_from": "",
  "is_reply": false,
  "url": "https://t.me/durov/351"
}
```

### Use cases

- **OSINT and monitoring:** Track public channels for announcements, leaks, and activity over time.
- **Crypto and markets:** Watch token, exchange, and project announcement channels.
- **News tracking:** Capture posts from news and aggregator channels by keyword.
- **Brand monitoring:** Detect mentions of a company, product, or person across channels.
- **Research datasets:** Build repeatable message datasets with timestamps and engagement signals.
- **LLM and automation pipelines:** Feed channel content into summarizers, classifiers, or alerts.

### What you need to run it

Only a public channel username (or its `t.me` link). The actor reads Telegram's public channel preview, walking backwards through history until it reaches your `maxMessages` cap or the start of available history. No Telegram account, login, API key, or setup is required, and only **public** channels with web preview enabled can be read.

### Limitations

- Only public channels with web preview enabled can be scraped. Private channels, groups, and DMs are not accessible and return an error record.
- View counts are the display string Telegram renders (for example `12.3K`), not exact integers.
- Reactions, comment counts, and full media files are not returned; media is reported as boolean flags.
- The web preview exposes channel history but not every historical message for very large or old channels.
- Telegram may rate-limit aggressive pagination; the actor backs off and retries.

### Compared to alternatives

Telegram channel scrapers are crowded on the Apify Store. Here is how this actor differs from the most common options:

- **vs. other Apify Telegram channel scrapers (e.g. `pamnard/telegram-channels-scraper`):** Many existing actors bill you for variable platform usage, so a long run costs whatever the underlying compute happens to use. This actor charges a flat, predictable price per message returned, so you know your cost before you start. It is also lightweight and fast (no heavy browser session, no API token needed to drive it), and returns clean boolean media flags plus normalized ISO-8601 timestamps out of the box.
- **vs. the Telegram Bot API:** The Bot API cannot read arbitrary public channel history unless the bot is an admin of that channel. This actor needs no bot and no membership.
- **vs. account-based scrapers (phone number + API credentials):** Those require a logged-in Telegram session and risk account bans. This actor is login-free and read-only against the public channel preview.
- **vs. manual export:** Telegram Desktop export only works for chats you have already joined. This actor works on any public channel without joining.

### FAQ

**Do I need a Telegram account?**
No. The actor only reads the public web preview that Telegram exposes for public channels.

**Can I scrape private channels or groups?**
No. Only public channels with web preview enabled are accessible. Private channels return an error record instead of failing the run.

**Are view counts exact?**
They are the display values Telegram shows, such as `1.2M` or `12.3K`.

**Can I get full media files?**
Not directly. The actor reports media presence as boolean flags (photo, video, document, poll, sticker).

**How far back can I scrape?**
Up to `maxMessages`, paginating backwards until Telegram stops returning older messages.

### Support and custom builds

Need reactions, comment threads, media downloads, multi-channel batches, scheduled alerts, or dashboard-ready exports? Contact Thirdwatch at [thirdwatch.dev](https://thirdwatch.dev) or through the Apify actor support channel.

Last verified: 2026-06

# Actor input Schema

## `channel` (type: `string`):

Public Telegram channel username to scrape (e.g. 'durov'). You can paste a full URL like 'https://t.me/durov' or 't.me/s/durov' -- it will be normalized to the username. The channel must be public and have web preview enabled.

## `keyword` (type: `string`):

Optional. If set, only messages whose text contains this keyword (case-insensitive) are returned. Leave empty to return all messages.

## `maxMessages` (type: `integer`):

Maximum number of messages to return. The actor paginates backwards through channel history until this many messages are collected or the channel history ends.

## Actor input object example

```json
{
  "channel": "durov",
  "keyword": "",
  "maxMessages": 50
}
```

# 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 = {
    "channel": "durov",
    "maxMessages": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/telegram-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 = {
    "channel": "durov",
    "maxMessages": 50,
}

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

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

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

```

## CLI example

```bash
echo '{
  "channel": "durov",
  "maxMessages": 50
}' |
apify call thirdwatch/telegram-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=thirdwatch/telegram-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Telegram Channel Scraper - Messages & Views",
        "description": "Scrape public Telegram channel messages via the t.me/s/ web preview. Get message text, view counts, timestamps, author/signature, media flags, forwards, and message URLs. Optional keyword filter. No login, API key, or proxy needed.",
        "version": "1.0",
        "x-build-id": "C8DC6XzspvWfWGVDS"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/thirdwatch~telegram-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-thirdwatch-telegram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/thirdwatch~telegram-scraper/runs": {
            "post": {
                "operationId": "runs-sync-thirdwatch-telegram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/thirdwatch~telegram-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-thirdwatch-telegram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "channel"
                ],
                "properties": {
                    "channel": {
                        "title": "Channel Username",
                        "type": "string",
                        "description": "Public Telegram channel username to scrape (e.g. 'durov'). You can paste a full URL like 'https://t.me/durov' or 't.me/s/durov' -- it will be normalized to the username. The channel must be public and have web preview enabled."
                    },
                    "keyword": {
                        "title": "Keyword Filter (optional)",
                        "type": "string",
                        "description": "Optional. If set, only messages whose text contains this keyword (case-insensitive) are returned. Leave empty to return all messages.",
                        "default": ""
                    },
                    "maxMessages": {
                        "title": "Max Messages",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of messages to return. The actor paginates backwards through channel history until this many messages are collected or the channel history ends.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
