# Telegram Channel Scraper | Posts Messages (`easytools/telegram-channel-scraper`) Actor

Scrape Telegram channels posts and messages. Export text, media, views, reactions, sender data, and links

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

## Pricing

from $0.00005 / actor start

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/platform/actors/running/actors-in-store#pay-per-event

## 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 — export posts, media, and channel data from Telegram 🚀

This **Telegram Channel Scraper** helps you collect Telegram posts, message metadata, and downloadable media without manually scrolling channels or exporting chats by hand. It is built for teams that need a reliable telegram posts scraper for research, monitoring, archives, enrichment, and reporting.

You get structured output after each run, and billing happens only when the actor successfully delivers a post to the dataset. That makes it practical for recurring collection, one-off telegram data export jobs, and large historical backfills. ✅

**What you get after each run 🎁**
- **Dataset:** one row per delivered Telegram post plus one `source_summary` row per source; exportable from Apify in JSON, CSV, Excel, XML, and RSS 📊
- **Files/Storage:** downloadable media files are stored in the default key-value store and exposed in output as direct URLs when `downloadMedia=true` 🗄️

**Modes / Features ⚙️**
- `Full scrape` — collect posts, text, reactions, sender data, webpage and poll metadata 🔎
- `Resolve only` — validate sources and resolve invite links without scraping messages 🧾


### Support
For issues, use the Actor page [**Issues**](https://console.apify.com/actors/nNfoTlSejBXPTlaUr/issues) or send email artur.novikk@gmail.com or message in [Telegram](https://t.me/systorer)


> 💡 **Tip:** Use this actor when you need a Telegram channel downloader, telegram message export workflow, or searchable dataset instead of raw Telegram export files.

---

### Table of contents 📚
- Key features
- Use cases
- How to scrape Telegram channel posts
- Pricing
- Input
- Output
- Statuses & error codes
- FAQ


---

### Key features ✨
- Scrape Telegram sources from `@username`, plain usernames, public `t.me/...` links, and invite links.
- Export one dataset row per post, with album posts grouped into one row by `albumId`.
- Download media and keep direct file URLs in output for photo, document, video, and audio posts.
- Capture views, forwards, reactions, sender metadata, webpage previews, and poll artifacts.
- Resume from checkpoints so repeated runs can continue historical collection instead of starting from scratch.

### Use cases 🎯
- Competitive research — monitor channel activity, reactions, and posting volume over time.
- Content archiving — create a clean telegram channel export with media links and message metadata.
- Lead generation and enrichment — collect channel titles, usernames, descriptions, and post URLs.
- Media collection — use it as a media saver for Telegram channels with downloadable assets.
- Reporting and analytics — build dashboards from views, forwards, replies, and reactions.

### How to scrape Telegram channel posts 🧭
1. Add your Telegram sources in the `sources` field.
2. Select `fromDate` and `toDate` with the built-in date picker if you need a bounded scrape.
3. Turn on `downloadMedia` if you want direct file links in the output.
4. Enable the metadata you need: reactions, views, forwards, sender, webpage, and poll artifacts.
5. Run the actor and export the resulting dataset or download media from the provided URLs.

### Pricing 💸
- `$0.01` per delivered text post
- `$0.015` per delivered media post

> #### ⚠️ Important pricing note
>
> - The actor charges only after a post is successfully delivered to the dataset.
> - Invalid input, failed resolution, filtered-out posts, and `resolveOnly` runs do not create delivery charges for posts.
> - Charging is event-based, not dataset-item-based.


### Input ⌨️

#### Fields
- `sources` (`array`, required): Telegram sources to process. Supports `@username`, `username`, `https://t.me/username`, `https://t.me/+inviteHash`, and `https://t.me/joinchat/inviteHash`.
- `maxMessagesPerChannel` (`integer`, optional): Maximum number of delivered posts per source. Leave empty to continue through all available history from the checkpoint.
- `downloadMedia` (`boolean`, optional, default `true`): Download supported media files and expose direct URLs in output.
- `mediaTypes` (`array`, optional, default `["photo","document","video","audio","webpage","poll"]`): Media categories to keep.
- `includeReactions` (`boolean`, optional, default `true`): Include Telegram reactions.
- `includeViews` (`boolean`, optional, default `true`): Include Telegram view counters when available.
- `includeForwards` (`boolean`, optional, default `true`): Include Telegram forward counters when available.
- `includeSender` (`boolean`, optional, default `true`): Include sender identity fields when available.
- `includeWebpageArtifacts` (`boolean`, optional, default `true`): Include normalized webpage preview data.
- `includePollArtifacts` (`boolean`, optional, default `true`): Include normalized poll data.
- `keywords` (`array`, optional): Keep only posts containing at least one keyword.
- `mediaOnly` (`boolean`, optional, default `false`): Keep only posts with downloadable media.
- `textOnly` (`boolean`, optional, default `false`): Keep only posts without downloadable media.
- `fromDate` (`string`, optional): Lower date bound selected with the Apify calendar UI. Format: `YYYY-MM-DD`.
- `toDate` (`string`, optional): Upper date bound selected with the Apify calendar UI. Format: `YYYY-MM-DD`.
- `joinOnInvite` (`boolean`, optional, default `true`): Attempt to join or import an invite link before scraping.
- `resolveOnly` (`boolean`, optional, default `false`): Validate and resolve sources without scraping posts.

#### Input examples ✅
**Example 1 — scrape a public channel with media downloads**
```json
{
  "sources": ["@TEST_MEDIA"],
  "downloadMedia": true,
  "mediaTypes": ["photo", "document", "video", "audio", "webpage", "poll"],
  "includeReactions": true,
  "includeViews": true,
  "includeForwards": true,
  "includeSender": true,
  "includeWebpageArtifacts": true,
  "includePollArtifacts": true,
  "keywords": [],
  "mediaOnly": false,
  "textOnly": false,
  "fromDate": "2026-03-02",
  "toDate": "2026-03-26",
  "joinOnInvite": true,
  "resolveOnly": false
}
````

**Example 2 — text-only message scrape for multiple sources**

```json
{
  "sources": [
    "https://t.me/pack333",
    "https://t.me/ekvlvsem"
  ],
  "maxMessagesPerChannel": 100,
  "downloadMedia": false,
  "includeReactions": true,
  "includeViews": true,
  "includeForwards": true,
  "includeSender": false,
  "includeWebpageArtifacts": true,
  "includePollArtifacts": false,
  "keywords": ["youtube", "traffic"],
  "mediaOnly": false,
  "textOnly": true,
  "joinOnInvite": true,
  "resolveOnly": false
}
```

**Example 3 — resolve invite links without scraping**

```json
{
  "sources": [
    "https://t.me/+F3m2kcP1Fo0MmYy",
    "@TEST_MEDIA"
  ],
  "downloadMedia": false,
  "includeReactions": false,
  "includeViews": false,
  "includeForwards": false,
  "includeSender": false,
  "includeWebpageArtifacts": false,
  "includePollArtifacts": false,
  "keywords": [],
  "mediaOnly": false,
  "textOnly": false,
  "joinOnInvite": true,
  "resolveOnly": true
}
```

### Output 📦

#### Where output is stored 🗂️

- **Default dataset:** contains both `message` rows and `source_summary` rows.
- **Default key-value store:** contains checkpoint state and downloaded media files.
- **Output tabs in Apify Console:** `Messages` and `Source Summaries`.

#### Example output item

```json
{
  "itemType": "message",
  "id": "TEST_MEDIA:14567",
  "channel": "@TEST_MEDIA",
  "channelLink": "https://t.me/TEST_MEDIA",
  "sourceInput": "@TEST_MEDIA",
  "sourceId": 1234327890,
  "canonicalSource": "TEST_MEDIA",
  "channelTitle": "TEST Media",
  "channelUsername": "TEST_MEDIA",
  "channelDescription": "News and analytics",
  "subscribers": 125000,
  "messageId": 14567,
  "postUrl": "https://t.me/TEST_MEDIA/14567",
  "date": "2026-03-24T10:15:00Z",
  "dateLabel": "2026-03-24",
  "postType": "regular",
  "text": "Market update and charts.",
  "views": 18234,
  "forwards": 87,
  "replyCount": 0,
  "reactions": [
    { "emoji": "🔥", "count": 44 },
    { "emoji": "👍", "count": 21 }
  ],
  "reactionMap": {
    "🔥": 44,
    "👍": 21
  },
  "totalReactions": 65,
  "likes": 65,
  "links": ["https://example.com/report"],
  "hasMedia": true,
  "mediaTypes": ["photo"],
  "albumId": null,
  "media": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/14567.jpg?disableRedirect=1&token=TOKEN",
  "sender": {
    "id": 1234567890,
    "username": "TEST_MEDIA",
    "name": "TEST Media",
    "firstName": null,
    "lastName": null
  },
  "status": "DELIVERED",
  "errorCode": null,
  "scrapedAt": "2026-03-26T12:00:00Z"
}
```

#### Output fields

- `itemType`: `message` or `source_summary`.
- `id`: Stable row identifier.
- `channel`: Human-readable channel handle such as `@TEST_MEDIA`.
- `channelLink`: Public channel URL when available.
- `sourceInput`: Original source provided by the user.
- `sourceId`: Telegram numeric source ID when available.
- `canonicalSource`: Canonical internal source identifier used by the actor.
- `channelTitle`: Resolved channel title.
- `channelUsername`: Resolved public username when available.
- `channelDescription`: Resolved channel description when available.
- `subscribers`: Subscriber/member count when Telegram exposes it.
- `messageId`: Telegram message ID.
- `postUrl`: Public post URL when available.
- `date`: Post timestamp in UTC ISO format.
- `dateLabel`: Short UTC date label.
- `postType`: `regular` or `service`.
- `text`: Post text.
- `views`: View count when available.
- `forwards`: Forward count when available.
- `replyCount`: Reply count when available.
- `reactions`: Array of `{emoji, count}` objects.
- `reactionMap`: Flattened reaction map for analytics.
- `totalReactions`: Sum of all reactions.
- `likes`: Alias for total reactions.
- `links`: URLs detected in post text or webpage metadata.
- `hasMedia`: Whether the post contains downloadable media.
- `mediaTypes`: Media types found on the post.
- `replyToMessageId`: Parent message ID when available.
- `albumId`: Shared Telegram `grouped_id` for album posts.
- `forwardInfo`: Forward metadata when Telegram provides it.
- `postAuthor`: Telegram post author field when present.
- `media`: A single direct media URL or an array of direct media URLs for album posts.
- `webpage`: Normalized webpage preview object when enabled.
- `poll`: Normalized poll object when enabled.
- `sender`: Sender object when enabled and available.
- `contentHash`: Stable content hash used for idempotency logic.
- `status`: Delivery or summary status.
- `errorCode`: Error code when the row represents a failure or skipped outcome.
- `scrapedAt`: Actor timestamp when the row was written.
- `checked`, `messagesSeen`, `messagesSaved`, `mediaDownloaded`, `errorMessage`, `startedAt`, `finishedAt`: Summary fields used by `source_summary` rows.

### Statuses & error codes 🧾

#### Statuses

- `DELIVERED` — a message row was successfully written.
- `RESOLVED_ONLY` — source was resolved, but no scraping was requested.
- `SCRAPED` — source scraping completed and at least one post was saved.
- `FAILED` — source failed without producing saved posts.
- `INVALID_INPUT` — source or input field was invalid.
- `WAITING_FOR_APPROVAL` — Telegram invite exists but requires approval.
- `BUDGET_EXCEEDED` — delivery charging was blocked by the configured budget.
- `FAILED_AFTER_CHARGE` — a charged delivery did not complete dataset persistence cleanly.
- `SKIPPED_BUDGET` — remaining sources were skipped after budget stop.
- `SKIPPED_FAILSAFE` — remaining sources were skipped after a failsafe stop.

#### Error codes

- `INVALID_INPUT_EMPTY` — `sources` is missing or empty.
- `INVALID_INPUT` — generic invalid input, including too many sources.
- `INVALID_INPUT_CONFLICT` — conflicting flags such as `mediaOnly=true` and `textOnly=true`.
- `INVALID_INPUT_NEGATIVE_LIMIT` — negative `maxMessagesPerChannel`.
- `INVALID_INPUT_DATE_RANGE` — `fromDate` is after `toDate`.
- `INVALID_DATE_FORMAT` — invalid date value.
- `INVALID_FORMAT` — invalid source format.
- `INVALID_INVITE` — invite link is invalid.
- `JOIN_REQUEST_PENDING` — invite requires approval.
- `RESOLVE_FAILED` — source could not be resolved.
- `CONFIG_MISSING_SECRET` — missing Telegram secret.
- `CONFIG_INVALID_API_KEY` — invalid Telegram credentials or unauthorized session.
- `CONFIG_INVALID_MONETIZATION` — pay-per-event is not configured correctly.
- `CHARGE_FAILED` — charge failed or limit was reached.
- `TELEGRAM_RATE_LIMIT` — Telegram flood wait or rate limit failure.
- `TELEGRAM_API_ERROR` — Telegram-side request failure.
- `CHECKPOINT_SAVE_FAILED` — checkpoint persistence failed.
- `DATASET_PUSH_FAILED` — dataset write failed.
- `MEDIA_DOWNLOAD_FAILED` — media download or validation failed.

### Best practices ✅

- Start with one or two channels before running a large historical scrape.
- Use date filters to reduce scan volume for high-traffic channels.
- Disable `downloadMedia` when you only need metadata and post URLs.
- Keep `includeSender`, `includeReactions`, and `includeViews` enabled only when you need those fields downstream.
- Use `resolveOnly=true` to validate invite links before a large production run.

### FAQ ❓

#### How do I scrape Telegram channel posts by date?

Use `fromDate` and `toDate` in the actor input. In the Apify UI those fields now open a calendar picker and submit dates in `YYYY-MM-DD` format.

#### Can I use this as a telegram media downloader?

Yes. Turn on `downloadMedia=true`. The actor will keep direct media URLs in the `media` field for supported downloadable files.

#### Does it export Telegram messages to CSV or Excel?

Yes. The output is stored in the default dataset, so you can export it from Apify as JSON, CSV, Excel, XML, or RSS.

#### Is this a telegram channel exporter or only a message scraper?

It does both. You get resolved channel metadata plus delivered post rows, which makes it useful as a telegram channel exporter and a messages scraper.

#### Where do I download the media files?

If `downloadMedia=true`, the actor stores media in the default key-value store and writes direct URLs into the `media` field of each message row.

#### Why was a source marked `WAITING_FOR_APPROVAL`?

That status means Telegram accepted the invite format, but the source requires a manual join approval before scraping can continue.

#### Can it handle albums with multiple images or files?

Yes. Album posts are grouped into one row, and `media` becomes an array of direct links when the post contains multiple downloadable files.

# Actor input Schema

## `sources` (type: `array`):

List of Telegram sources to scrape. Supports @username, username, https://t.me/username, https://t.me/+inviteHash, and https://t.me/joinchat/inviteHash.

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

Optional cap for the number of messages to process per source. Leave empty to scrape all available history from the current checkpoint.

## `downloadMedia` (type: `boolean`):

When enabled, the actor downloads supported media artifacts into internal storage.

## `mediaTypes` (type: `array`):

Media types to keep or download. Recommended values for v1: photo, document, video, audio, webpage, poll.

## `includeReactions` (type: `boolean`):

Include Telegram reaction counters in delivered message items.

## `includeViews` (type: `boolean`):

Include view counters when Telegram provides them.

## `includeForwards` (type: `boolean`):

Include forward counters when Telegram provides them.

## `includeSender` (type: `boolean`):

Include sender identity fields when available.

## `includeWebpageArtifacts` (type: `boolean`):

Include normalized webpage metadata for webpage posts.

## `includePollArtifacts` (type: `boolean`):

Include normalized poll metadata for poll posts.

## `keywords` (type: `array`):

Keep only messages containing at least one of these keywords.

## `mediaOnly` (type: `boolean`):

Keep only posts that contain media artifacts.

## `textOnly` (type: `boolean`):

Keep only posts without downloadable media artifacts.

## `fromDate` (type: `string`):

Optional lower date bound. Select a calendar date. The UI returns the value in YYYY-MM-DD format.

## `toDate` (type: `string`):

Optional upper date bound. Select a calendar date. The UI returns the value in YYYY-MM-DD format.

## `joinOnInvite` (type: `boolean`):

When invite access is available, attempt to join or import the invite before scraping.

## `resolveOnly` (type: `boolean`):

Resolve and validate sources without full scraping.

## Actor input object example

```json
{
  "sources": [
    "https://t.me/pigeee228",
    "https://t.me/soldierobovsem",
    "https://t.me/+Fg75wjxP1Fo0MmYy"
  ],
  "downloadMedia": true,
  "mediaTypes": [
    "photo",
    "document",
    "video",
    "audio",
    "webpage",
    "poll"
  ],
  "includeReactions": true,
  "includeViews": true,
  "includeForwards": true,
  "includeSender": true,
  "includeWebpageArtifacts": true,
  "includePollArtifacts": true,
  "mediaOnly": false,
  "textOnly": false,
  "joinOnInvite": true,
  "resolveOnly": false
}
```

# Actor output Schema

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

No description

## `sourceSummaries` (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 = {
    "sources": [
        "https://t.me/pigeee228",
        "https://t.me/soldierobovsem",
        "https://t.me/+Fg75wjxP1Fo0MmYy"
    ],
    "mediaTypes": [
        "photo",
        "document",
        "video",
        "audio",
        "webpage",
        "poll"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("easytools/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 = {
    "sources": [
        "https://t.me/pigeee228",
        "https://t.me/soldierobovsem",
        "https://t.me/+Fg75wjxP1Fo0MmYy",
    ],
    "mediaTypes": [
        "photo",
        "document",
        "video",
        "audio",
        "webpage",
        "poll",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("easytools/telegram-channel-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 '{
  "sources": [
    "https://t.me/pigeee228",
    "https://t.me/soldierobovsem",
    "https://t.me/+Fg75wjxP1Fo0MmYy"
  ],
  "mediaTypes": [
    "photo",
    "document",
    "video",
    "audio",
    "webpage",
    "poll"
  ]
}' |
apify call easytools/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Telegram Channel Scraper | Posts Messages",
        "description": "Scrape Telegram channels posts and messages. Export text, media, views, reactions, sender data, and links",
        "version": "0.1",
        "x-build-id": "2Z5Q0u39x9QfEm1Uk"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/easytools~telegram-channel-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-easytools-telegram-channel-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/easytools~telegram-channel-scraper/runs": {
            "post": {
                "operationId": "runs-sync-easytools-telegram-channel-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/easytools~telegram-channel-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-easytools-telegram-channel-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": [
                    "sources"
                ],
                "properties": {
                    "sources": {
                        "title": "Sources",
                        "type": "array",
                        "description": "List of Telegram sources to scrape. Supports @username, username, https://t.me/username, https://t.me/+inviteHash, and https://t.me/joinchat/inviteHash.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxMessagesPerChannel": {
                        "title": "Maximum messages per source",
                        "type": "integer",
                        "description": "Optional cap for the number of messages to process per source. Leave empty to scrape all available history from the current checkpoint."
                    },
                    "downloadMedia": {
                        "title": "Download media",
                        "type": "boolean",
                        "description": "When enabled, the actor downloads supported media artifacts into internal storage.",
                        "default": true
                    },
                    "mediaTypes": {
                        "title": "Media types",
                        "type": "array",
                        "description": "Media types to keep or download. Recommended values for v1: photo, document, video, audio, webpage, poll.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeReactions": {
                        "title": "Include reactions",
                        "type": "boolean",
                        "description": "Include Telegram reaction counters in delivered message items.",
                        "default": true
                    },
                    "includeViews": {
                        "title": "Include views",
                        "type": "boolean",
                        "description": "Include view counters when Telegram provides them.",
                        "default": true
                    },
                    "includeForwards": {
                        "title": "Include forwards",
                        "type": "boolean",
                        "description": "Include forward counters when Telegram provides them.",
                        "default": true
                    },
                    "includeSender": {
                        "title": "Include sender info",
                        "type": "boolean",
                        "description": "Include sender identity fields when available.",
                        "default": true
                    },
                    "includeWebpageArtifacts": {
                        "title": "Include webpage artifacts",
                        "type": "boolean",
                        "description": "Include normalized webpage metadata for webpage posts.",
                        "default": true
                    },
                    "includePollArtifacts": {
                        "title": "Include poll artifacts",
                        "type": "boolean",
                        "description": "Include normalized poll metadata for poll posts.",
                        "default": true
                    },
                    "keywords": {
                        "title": "Keywords filter",
                        "type": "array",
                        "description": "Keep only messages containing at least one of these keywords.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "mediaOnly": {
                        "title": "Media only",
                        "type": "boolean",
                        "description": "Keep only posts that contain media artifacts.",
                        "default": false
                    },
                    "textOnly": {
                        "title": "Text only",
                        "type": "boolean",
                        "description": "Keep only posts without downloadable media artifacts.",
                        "default": false
                    },
                    "fromDate": {
                        "title": "From date",
                        "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
                        "type": "string",
                        "description": "Optional lower date bound. Select a calendar date. The UI returns the value in YYYY-MM-DD format."
                    },
                    "toDate": {
                        "title": "To date",
                        "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
                        "type": "string",
                        "description": "Optional upper date bound. Select a calendar date. The UI returns the value in YYYY-MM-DD format."
                    },
                    "joinOnInvite": {
                        "title": "Join invite links",
                        "type": "boolean",
                        "description": "When invite access is available, attempt to join or import the invite before scraping.",
                        "default": true
                    },
                    "resolveOnly": {
                        "title": "Resolve only",
                        "type": "boolean",
                        "description": "Resolve and validate sources without full scraping.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
