# Telegram Public Channel History & Watchlist (`jpmarketdata/telegram-public-channel-history`) Actor

Bulk-export public Telegram channel watchlists with contact-redacted text, dates, source links, views and visible reactions. Older-page history, date/keyword filters and message checkpoints; no login or downloads. $0.30/1k messages. Unofficial.

- **URL**: https://apify.com/jpmarketdata/telegram-public-channel-history.md
- **Developed by:** [h ichi](https://apify.com/jpmarketdata) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.30 / 1,000 unique public channel post delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Telegram Public Channel History & Watchlist

Export a watchlist of public broadcast-channel posts for news monitoring and competitor content research. One message row contains privacy-screened text, source date/link, approximate views, public reply context, visible reactions and media-type flags. This unofficial tool reads anonymous t.me/s/ web previews and follows their older-page links.

### Input

Provide 1–5 channels as usernames, @handles or public t.me/s/CHANNEL URLs. Empty input alone defaults to channels=\["telegram"]. maxMessagesPerChannel defaults 100, maxItems 500. Set UTC ISO 8601 since/until, or pass afterMessageIds keyed by normalized channel for incremental monitoring. keywords filters text within known channels; this does not search all Telegram or discover channels. Public groups, private/invite links, phone URLs and accounts are rejected. Order is descending public channel post ID, not inferred edit chronology.

### Output

Each unique message has channel, messageId, sourceUrl, redacted text/flag, publishedAt, approximate views and viewsRaw, edited marker, same-channel replyToMessageId if visible, aggregate reactionCounts, mediaTypes, sanitized externalUrls, public_web_preview coverage, sourceRank and observedAt. Optional unavailable fields are omitted. Album media with one post ID is one row/event. No author/signature, forwarded person, subscriber identities, private replies or media files are returned. Uncharged SUMMARY records per-channel pages/counts, skipped/redacted counts, first/last message IDs, next older boundary and cap/source/date/checkpoint stop. Advance the checkpoint to the highest delivered message ID only after the intended interval is fully reconciled. If SUMMARY reports source_cap, older messages in that interval may remain undelivered: keep the previous checkpoint until they have been recovered and checked. Run often enough or reconcile the interval separately before advancing; a capped export alone is not a complete checkpoint.

### Charging

$0.0003 per distinct delivered message through message-exported; $0.30/1000. No actor-specific start event or trial. Collect all requested sources into a bounded sanitized buffer before output/billing. Required-source failures leave zero rows/events. Duplicates, filters, metadata and SUMMARY incur no event. If no deliverable messages across all channels, fail without charging. Mixed genuine empty windows are recorded uncharged when other channels produce rows.

### Limits

256MB, HTTP/HTML, no login, bot token, API credentials, paid API, proxy, browser or downloads. About 20 visible messages/page; follow actual before links with strict decreasing-ID/no-repeat checks.80-request budget,1-second pacing,20-second request timeout,2MiB response cap and 300-second run timeout. Per-channel 200/global 1000-row ceiling. Real source/date/checkpoint boundaries can deliver fewer than the ceiling. Logs contain counts/status only. Missing identity/content, login redirect,429, changed markup and nonprogress fail explicitly. No cross-run checkpoint storage.

### Privacy

Exclude sender names/IDs/signatures, forwarded-person identities, member/subscriber identifiers, profile bios/avatars, contact addresses, phones, credentials and precise location. Requested broadcast-channel handle and public message link are the only identity references for provenance. Redact email/phone/@mention/contactURL/secret-like substrings before persistence. Discard raw response bodies and exclude source-restricted preview records. Pattern checks cannot guarantee prose names never appear; this is contact minimization, not anonymization or identity research.

### Source and terms

Reads only public t.me/s/ broadcast previews and older before links. t.me robots currently 404; check every run and honor future Disallow. Telegram content-licensing terms restrict user-content scraping, aggregation and AI uses. The scout records the exact applicable excerpt and DR-0007 treatment. No login/closed-chat/paywall bypass or media download. This is current owner-selected channel monitoring, not an AI training or platform-wide content archive product. An AI agent can retrieve announcements for a requested channel comparison using the same limited rows. DC is unverified; independent review, private default/nondefault runs and PPE/dataset parity remain release gates.

### If something goes wrong

- **Wrong number or a failed run?** Open a ticket on the **Issues** tab. I read every one and reply within 2 business days (Japan time).
- **You never get a fake "empty" result.** If the site can't be read, the run fails and says so.
- **Delivered rows only.** One validated unique row is one billable event. Duplicates, summaries, failed acquisition and undelivered rows are not charged.
- **Checked every week.** An automatic test runs this tool weekly; if the site changes, I fix it.
- **Public source data only.** No login or member/applicant records. Contact patterns are screened before delivery; prose may still name people.

### More tools by the same author

- [Mercari Japan Sold Prices — What Items Really Sell For](https://apify.com/jpmarketdata/mercari-japan-price-checker)
- [Yahoo! Auctions Japan Sold Prices — Median, Range, Bids](https://apify.com/jpmarketdata/yahoo-auction-sold-comps)

All tools (Japan marketplaces, real estate, jobs, racing, prediction markets): <https://apify.com/jpmarketdata>

### Disclaimer

Unofficial, independent tool — **not affiliated with, endorsed by, or sponsored by Telegram**. Product names and logos belong to their owners and only say where the data comes from. Data is read from public pages, for market research; check before you act on it.

# Actor input Schema

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

One to five exact public broadcast-channel usernames, @handles, or t.me/s/CHANNEL URLs. Public groups, invite links, private chats and phone URLs are rejected. Empty input defaults only to telegram.

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

Maximum distinct visible posts per channel,1–200. Older preview pages are followed until this ceiling or an evidenced source/date/checkpoint boundary.

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

Global cap on distinct delivered and charged posts. Album submedia are not extra messages.

## `since` (type: `string`):

Optional ISO8601 UTC lower source message-time bound.

## `until` (type: `string`):

Optional ISO8601 UTC upper bound; must follow since.

## `afterMessageIds` (type: `object`):

Optional JSON mapping normalized channel names to last processed source post ID; only larger source message IDs are delivered.

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

Optional case-insensitive words/phrases; any match qualifies. This does not discover channels or search all Telegram.

## Actor input object example

```json
{
  "channels": [
    "telegram"
  ],
  "maxMessagesPerChannel": 100,
  "maxItems": 500,
  "afterMessageIds": {}
}
```

# Actor output Schema

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

Privacy-screened visible public broadcast posts with explicit preview coverage.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "channels": [
        "telegram"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/telegram-public-channel-history").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "channels": ["telegram"] }

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/telegram-public-channel-history").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "channels": [
    "telegram"
  ]
}' |
apify call jpmarketdata/telegram-public-channel-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpmarketdata/telegram-public-channel-history"
        }
    }
}
```

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/dJO8NSV6HCtDo2Prr/builds/bTCrgjkBVMPcI1t8p/openapi.json
