# Telegram Channel Lookup — Subscribers & Channel Info API (`accountable_eel/telegram-channel-lookup`) Actor

Look up any public Telegram channel by username: title, subscriber count, verification badge, description, and recent messages. Reads Telegram's own public t.me preview pages directly, no Bot API token or login needed. Charged only for channels actually found.

- **URL**: https://apify.com/accountable\_eel/telegram-channel-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.04 / 1,000 successful lookups

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

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

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

# README

## Telegram Channel Lookup — Subscribers & Channel Info API

Paste a list of public Telegram channel usernames and get each channel's live profile —
title, verified badge, description, subscriber count, media counts and its most recent
messages. This reads `t.me/s/<channel>`, Telegram's own server-rendered public preview, so
there's no bot token, no API key, no login, and no JavaScript to execute.

### Who it's for

Built for anyone who needs to qualify Telegram channels in bulk without joining them.
Trust-and-safety and OSINT analysts use it to check whether a handle pulled from a report is a
real, verified channel and how large its audience actually is. Growth and affiliate marketers
screen influencer and crypto channels before paying for a placement — subscriber count,
recent activity and the verified badge arrive in one row, so a dead or fake channel is obvious
before money moves. Sales teams cleaning lead lists run their Telegram handles through it and
keep only the ones that resolve. And because it reads Telegram's own public preview pages,
there's no bot to register and nothing to install: paste handles, get a table.

### Why this one

- **No bot token and no phone number.** Telegram's own public preview is server-rendered HTML.
  You don't register a bot, join the channel, or authenticate as a user.
- **You don't pay for handles that don't resolve.** A private channel, a deleted one, a user
  account, or a typo comes back `found: false` and is never billed.
- **Subscriber count both ways.** `subscribersRaw` keeps Telegram's own `11.1M` string;
  `subscribers` gives you `11100000` as a number you can sort and compare.
- **Recent messages included.** The latest posts come back with the profile, so a single
  lookup tells you both how big a channel is and whether it's still active.
- **Handles with or without `@`.** `@telegram` and `telegram` both resolve.

### What you get

One row per input handle. Field names are frozen — a Clay column or an agent that maps the
schema today can keep reading it next month.

| Field | Type / format | Description |
|---|---|---|
| `query` | text | The handle exactly as submitted, including any leading `@`. |
| `found` | boolean | Whether the handle resolved to a real public channel. Gates billing — `false` rows are never charged. |
| `scrapedAt` | date (ISO 8601) | When the lookup ran. |
| `data.title` | text | Channel display name. |
| `data.username` | text | The normalized handle, without `@`. |
| `data.verified` | boolean | Whether Telegram shows the verified badge. |
| `data.description` | text | Channel bio as shown on the preview page. |
| `data.subscribers` | number | Subscriber count parsed to an integer — `11.1M` becomes `11100000`. |
| `data.subscribersRaw` | text | Telegram's own abbreviated string, e.g. `11.1M`. |
| `data.photosCount` | number | Photos counter, where the channel publishes one. |
| `data.videosCount` | number | Videos counter, where the channel publishes one. |
| `data.linksCount` | number | Links counter, where the channel publishes one. |
| `data.recentMessages` | array | The latest posts Telegram renders on the preview — roughly the most recent 20. Each carries `text`, `date` and `views`. |

### What t.me/s/ can and can't see

Everything this actor returns comes from `t.me/s/<channel>` — the preview page Telegram
itself renders for public channels, the one you see when you open a channel link without the
app. That boundary defines the actor:

**It can see:** the channel's title, bio, verified badge, the photo/video/link counters, and
roughly the latest 20 posts with their view counts — everything Telegram chooses to show a
logged-out visitor.

**It can't see:** private or invite-only channels (no preview exists), groups and user
accounts (different page types entirely), comment threads, member lists, or anything older
than the preview window. All of those come back as `found: false` — free, but also not proof
the thing doesn't exist behind the login wall.

One subtlety worth knowing: `subscribers` is parsed from Telegram's own abbreviated display
string, so it's exact below 1,000 and rounded above — `11.1M` can only ever become
`11100000`. Rank and bucket with it; don't chart day-over-day deltas from it.

### Price

$4 per 1,000 results, plus a $0.005 start fee. Misses (`found:false`) are never charged.

You're billed per handle that resolves to a real public channel. A private channel, a deleted
one, a user account, or a typo costs nothing, no matter how many are in the list. Run 1,000
handles and, at the live FREE-tier per-row price, that's roughly **$4 if every one resolves** —
less in practice, since dead handles are free, and cheaper still on paid Apify tiers. Nothing
is rented monthly and nothing expires: the bill is the resolved rows, full stop.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `items` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~telegram-channel-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"items":["durov","telegram"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

1) Paste your handles into `items` — one per line, with or without a leading `@`.
2) Run the actor. Each handle is fetched from `t.me/s/<channel>` in parallel up to
   `maxConcurrency`.
3) Read the dataset. Each row carries the channel profile in `data`, or `found: false` if the
   handle isn't a real public channel.
4) Filter to `found: true` before you export if you only want live channels.

**Common ways teams use this:**

- **Verify a channel is authentic** before trusting or citing it, using `verified` and
  `subscribers` together.
- **Track competitor subscriber counts** by re-running on a schedule and diffing `subscribers`.
- **Check whether a channel is still active** by reading the dates on `recentMessages` rather
  than assuming a big follower count means a live channel.
- **Screen handles from a lead list** in bulk, keeping only the ones that resolve.
- **Shortlist channels by reach** in a niche by running a candidate list and sorting on
  `subscribers`.

### Input

```json
{
  "items": ["telegram", "@durov"],
  "maxConcurrency": 5,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

`items` is your list of public Telegram channel handles. A leading `@` is stripped
automatically, so `@telegram` and `telegram` are the same lookup, and you can mix both formats
in one run. One dataset row comes back per item, and rows with `found: false` are never
charged. `maxConcurrency` (default 5) caps parallel requests — keep it conservative, since this
target has no browser fallback. `proxyConfiguration` routes requests through Apify Proxy, which
is the default and is generally what you want for bulk runs.

### Sample output

| query | found | title | username | verified | subscribers | subscribersRaw | photosCount | videosCount | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| telegram | true | Telegram News | telegram | true | 11100000 | 11.1M | 45200 | 196 | 2026-08-21T00:00:00.000Z |

A single row in full:

```json
{
  "query": "telegram",
  "found": true,
  "data": {
    "title": "Telegram News",
    "username": "telegram",
    "verified": true,
    "description": "Do not open suspicious links...",
    "subscribers": 11100000,
    "subscribersRaw": "11.1M",
    "photosCount": 45200,
    "videosCount": 196,
    "linksCount": 812,
    "recentMessages": [
      { "text": "...", "date": "2026-08-15T09:00:00+00:00", "views": "1.2M" }
    ]
  },
  "scrapedAt": "2026-08-21T00:00:00.000Z"
}
```

A handle that isn't a real public channel still returns a row, with no `data`, and is never
charged:

```json
{
  "query": "not-a-real-channel",
  "found": false,
  "scrapedAt": "2026-08-21T00:00:00.000Z"
}
```

Failed handles stay visible in the dataset on purpose — auditing which of 500 leads didn't
resolve beats reverse-engineering it from a shorter output file.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~telegram-channel-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"items":["durov","telegram"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~telegram-channel-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"items":["durov","telegram"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~telegram-channel-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"items":["{{value}}"]}`, mapping the row's value into the `items` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Telegram Channel Lookup | Apify" — the agent will find and run this actor.

### Tips

- **Sort on `subscribers`, report with `subscribersRaw`.** The number is for ranking; the raw
  string is what a reader recognizes.
- **Don't diff `subscribers` daily on large channels.** It's parsed from a rounded display
  string, so a channel sitting at `11.1M` looks static for a long time. Weekly or monthly
  comparisons are meaningful; daily ones aren't.
- **Check `recentMessages` dates, not just subscriber count.** A channel with a million
  subscribers and nothing posted in a year is a dead channel.
- **Private and invite-only channels are misses by design.** `t.me/s/` only renders public
  previews, so anything gated returns `found: false` — free, but not evidence the channel
  doesn't exist.
- **Groups and user accounts aren't channels.** Both come back as misses; this actor is
  channel-specific.

### vs. alternatives

| | What it costs | What you get | Trade-off |
|---|---|---|---|
| **This actor** (`telegram-channel-lookup`) | $4 per 1,000 resolved handles (less on paid tiers), $0.005 actor start, nothing for a handle that doesn't resolve | A flat channel profile per handle — title, verified, description, subscriber count, media counts and the latest posts — with no bot token or login | Public channels only, roughly the latest 20 messages, and subscriber counts rounded as Telegram displays them. Not a full message-history scraper. |
| **truefetch/telegram-channel-message** (791 users) | $0.00035 per result, $0.01 start, $0.0008 per media item | Deep message history and media downloads, billed per message | If you want the messages themselves at volume, this is the right shape and far cheaper per message. This is a profile lookup, not a message archive. |
| **webfinity/telegram-channel-content-media-scraper** (208 users) | $9/month rental | Unlimited runs for a flat monthly fee | Flat-rate rental beats per-row pricing above a certain volume. Below it, you're paying $9 for a handful of lookups. |
| **Telegram's Bot API** | Free | Official access to channels your bot is a member of | It requires a bot token and channel membership. This reads the public preview with neither, which is the whole point for bulk screening of channels you don't control. |

(Prices quoted for other tools are their August 2026 list prices; confirm on their pages
before deciding on cost alone.)

### FAQ

**Do I need a bot token, an API key, or a phone number?**
No. This reads `t.me/s/<channel>`, Telegram's own server-rendered public preview. No
registration, no authentication, and no channel membership.

**What counts as "found"?**
The handle must resolve to a public channel with a rendered preview page. Private channels,
deleted channels, groups, user accounts and typos all return `found: false` and are never
charged.

**Why is `subscribers` a round number?**
Telegram displays large counts abbreviated — `11.1M` — and that string is all the preview page
carries. `subscribers` is that string parsed to an integer, so it's exact for small channels and
rounded for big ones. `subscribersRaw` preserves the original.

**Can I get more than ~20 messages of history?**
Not from this actor — the preview page is all it reads. For deep message archives, a
message-focused scraper (billed per message) is the right shape; this is a profile check.

**Does this work for groups or user profiles?**
No. Both return `found: false`. The actor is specific to public channels.

**Does the channel owner know I looked?**
No. Reading the public preview is an ordinary page view, the same as opening the channel's
link in a browser — no join, no read receipt, nothing visible to the owner.

**Can an AI agent use this?**
Yes. It's exposed through the Apify MCP server, so a Claude or Cursor agent with that MCP
connected can run a handle list and read the rows back without integration code.

### Related actors

- [Substack Publication Lookup](https://apify.com/accountable_eel/substack-publication-lookup) —
  the same profile-lookup shape for Substack publications.
- [Podcast Lookup](https://apify.com/accountable_eel/podcast-lookup) — show and episode data
  from Apple Podcasts by name or id.
- [Apple App Store Lookup](https://apify.com/accountable_eel/apple-app-store-lookup) — iOS app
  metadata and reviews by app id.

# Actor input Schema

## `items` (type: `array`):

One item per line — see the item shape and examples below. Only the items we actually find are charged — never per run, and never for a miss.

## `maxConcurrency` (type: `integer`):

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "items": [
    "durov",
    "telegram"
  ],
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "items": [
        "durov",
        "telegram"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/telegram-channel-lookup").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 = { "items": [
        "durov",
        "telegram",
    ] }

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

```

## MCP server setup

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

```

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/za4sPWLw8gKHFaY85/builds/NmHsBeAmQTcCae2Ca/openapi.json
