# Telegram Bulk Check Phone Numbers (`akula.marketing/telegram-bulk-check-phone-numbers`) Actor

Verify which phone numbers are registered on Telegram in bulk. Upload a list or file and get registration status for every number — built for lead verification, CRM list cleaning, and contact-list enrichment at scale.

- **URL**: https://apify.com/akula.marketing/telegram-bulk-check-phone-numbers.md
- **Developed by:** [akula.marketing](https://apify.com/akula.marketing) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 phone number checkeds

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 Bulk Phone Number Checker

> 💬 Questions, bulk pricing, or a custom solution? Talk to us on Telegram — [@KoteamSupport](https://t.me/KoteamSupport).

**Telegram Bulk Phone Number Checker** verifies which phone numbers are registered on Telegram — in bulk, in a single run. Upload a list or a file and get registration status for every number back as clean, structured data. Built for **bulk lead verification**, **CRM list cleaning**, and **contact-list enrichment** at scale, not one-off lookups.

### How it differs from Telegram Get Phone Info

[Telegram Get Phone Info](https://apify.com/akula.marketing/telegram-get-phone-info) checks **one** number per run and returns a full public profile (username, name, photo, premium/bot flags) straight from Telegram.

This Actor checks large batches of numbers per run and returns whether each is registered on Telegram — built for volume, not depth. Because it batches, it's priced at **1/5 the per-result price** of the single-number actor.

### What can this Actor do?

- Verify Telegram registration for an entire contact list in one run
- Accept input either as a pasted list or an uploaded file
- Get one dataset row per phone number, ready for CRM or spreadsheet import
- Keep the raw Excel export in the run's key-value store for reference

### How it works

1. Provide 500–10,000 phone numbers in international format (digits, optional leading `+`) — either paste them as a list, or upload a plain-text file with one number per line.
2. The Actor keeps only the numbers from whichever country makes up the largest share of your list, and drops the rest — checking is more reliable when a batch isn't mixing countries. You're only charged for the numbers actually checked (see [Pricing](#pricing)), and the run log tells you how many were dropped this way. If no single country reaches the 500-number minimum, the run stops before anything is submitted or charged — see the [FAQ](#faq).
3. The Actor submits the filtered list as a single check task and immediately logs a **result link** — an unauthenticated URL you can open (or `curl`) any time to poll status or download the result, no API key needed.
4. From here you have two options:
   - **Stop the run** right away to save compute time, and check the result link later once the check has finished server-side.
   - **Let it keep running** — it polls for up to 15 minutes. If the check finishes in time, results are downloaded, parsed, and pushed as one dataset row per phone number automatically. If it's still running after 15 minutes, the run ends anyway (it does not fail) and you fall back to the result link.

```json
{
  "phones": ["79990000001", "79990000002", "...500 to 10,000 numbers..."]
}
```

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `phones` | Array of strings | One of `phones`/`phonesFile` | 500 to 10,000 phone numbers, international format, digits with optional leading `+`. Ignored if `phonesFile` is set. |
| `phonesFile` | File | One of `phones`/`phonesFile` | Alternative to `phones`: upload a plain-text file with one phone number per line (500–10,000 numbers). Takes priority over `phones` if both are set. |
| `name` | String | No | Label stored on the check task, for your own reference. |

<details>
<summary>Input schema (JSON)</summary>

```json
{
  "phones": {
    "title": "Phone numbers",
    "type": "array",
    "description": "500 to 10,000 phone numbers in international format (digits, optional +). Example: 1234567890. Ignored if \"Phone numbers file\" is set.",
    "editor": "stringList",
    "minItems": 500,
    "maxItems": 10000
  },
  "phonesFile": {
    "title": "Phone numbers file",
    "type": "string",
    "description": "Alternative to \"Phone numbers\": upload a plain-text file with one phone number per line (500-10,000 numbers). Takes priority over \"Phone numbers\" if both are set.",
    "editor": "fileupload"
  }
}
```

</details>

### Output

If the check finishes within the run's 15-minute wait, the run pushes one dataset row per submitted phone number. Row shape is discovered at run time from the downloaded Excel file's header row, and every row always carries a `phone` field. The raw Excel file is also saved to the run's key-value store as `checker-result.xlsx`.

Either way — finished in time or not — the result link is saved to the run's key-value store as `check-result-link.json` (`{"taskId": ..., "resultUrl": ...}`), and printed in the run log right after the check task is created.

### Pricing

This Actor runs on the [Apify Pay-Per-Event](https://apify.com/pricing) model, priced at **$10 per 1,000 phone numbers** ($0.01/phone). You're charged as soon as the run starts checking, not per dataset row — so the charge happens whether the check finishes inside the run or you end up using the result link. The charge is based on the filtered count (your input list, deduplicated, with only the largest single country's numbers kept — see [How it works](#how-it-works)), not the raw number of entries you submitted.

Checks run server-side and can take a while for larger batches. The Actor polls for up to 15 minutes and pushes results automatically if the check finishes in that window; otherwise stop the run (or let it end on its own) and use the result link once it's done — you're not charged extra for waiting on the link.

### FAQ

#### What happens if a number can't be checked?

Numbers that can't be resolved are skipped rather than failing the whole batch; the dataset row count reflects what could be returned.

#### Can I submit numbers from multiple countries in one run?

You can submit them, but only the numbers from your list's single largest country are actually checked — the rest are dropped before submission (and you're not charged for them). This is a reliability requirement on the checking side, not a limitation you can turn off. If you need multiple countries checked, split your list by country and run each separately.

#### Can I check fewer than 500 numbers?

No — a minimum batch of 500 *from a single country* is required. If your list mixes countries, that minimum applies after the other countries are filtered out, so a 10,000-number list split thin across many countries can still fail this check even though the total is well over 500. For a single number, use [Telegram Get Phone Info](https://apify.com/akula.marketing/telegram-get-phone-info) instead.

#### Can I check more than 10,000 numbers?

Not in one run. Split larger lists across multiple runs.

#### Why did my run end without pushing any results?

The check didn't finish within the 15-minute wait window. This isn't a failure — use the result link from the run log or the `check-result-link.json` key-value store record to get the data once the check finishes.

#### Do I have to keep the run active while I wait?

No — once you see the result link in the log, you can stop the run immediately to save compute time. The check itself runs server-side, not inside the Actor.

### Support

24/7 support via [@KoteamSupport](https://t.me/KoteamSupport). We also build custom Telegram data solutions — reach out if this Actor doesn't cover your use case.

⭐ Found this useful? [Leave a review](https://apify.com/akula.marketing/telegram-bulk-check-phone-numbers#reviews) — it helps others find this Actor and tells us what to build next.

# Actor input Schema

## `phones` (type: `array`):

500 to 10,000 phone numbers in international format (digits, optional +). Example: 1234567890. Ignored if "Phone numbers file" is set.

## `phonesFile` (type: `string`):

Alternative to "Phone numbers": upload a plain-text file with one phone number per line (500-10,000 numbers). Takes priority over "Phone numbers" if both are set.

## `name` (type: `string`):

Optional label stored on the check task.

## Actor input object example

```json
{
  "name": "Telegram check"
}
```

# Actor output Schema

## `phoneResults` (type: `string`):

Bulk Telegram check rows.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("akula.marketing/telegram-bulk-check-phone-numbers").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("akula.marketing/telegram-bulk-check-phone-numbers").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 '{}' |
apify call akula.marketing/telegram-bulk-check-phone-numbers --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,akula.marketing/telegram-bulk-check-phone-numbers"
        }
    }
}

```

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/fwoS7alUMMq55mdh3/builds/RtD7fJKI6tFauUfhz/openapi.json
