# Telegram Demand Map — Unique Requests by Country & Niche (`telegrambest/telegram-demand-map`) Actor

Compare classified Telegram demand by country and niche over an explicit 30-day window. Cross-posts count once per cell. Includes weekly totals and source groups. Counts request texts, not unique people.

- **URL**: https://apify.com/telegrambest/telegram-demand-map.md
- **Developed by:** [TGDen — Telegram Intelligence](https://apify.com/telegrambest) (community)
- **Categories:** Lead generation, Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 country × niche cells

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 Demand Map — Unique Requests by Country & Niche

**Compare accepted classified request texts by country and niche in an explicit 30-day snapshot.**

Part of **TGDen — Telegram Intelligence**. No Telegram account, phone number or session is required.

### From a market to buyer requests

Each cell includes **buyerSearchUrl**. One click opens a TGDen Buyer Search preview with the exact country and classified niche already filled in, showing up to three direct requests from the last 30 days. This preview does not start or charge an Apify run.

The same cell includes **buyerSearchInput**, ready to paste into the [Buyer Search Actor](https://apify.com/telegrambest/telegram-lead-finder). The preview also offers the input and an Apify export CTA. Apify's Console does not accept arbitrary input in a URL; the ready example task in the Buyer Search README uses Apify's native task-copy flow.

Demand Map remains the discovery entry: **where demand exists → prefilled Buyer Search → dated original requests**. Map counts also include soft, latent and hiring signals; the buyer preview deliberately starts with direct requests only, so its sample is not the map total.

### Try it

Use this input, run the Actor and open its dataset (JSON, CSV or the table view):

```json
{
  "countries": [
    "th"
  ],
  "includeTopGroups": true
}
```

### Real output

A shortened row read on **23 October 2026** during owner-account acceptance testing. Results change as the corpus changes.

```json
[
  {
    "country": "th",
    "niche": "services",
    "requests30d": 3795,
    "requests7d": 1225,
    "chats": 358,
    "topChats": [
      {
        "username": "pkhukete",
        "title": "pkhukete",
        "url": "https://t.me/pkhukete",
        "members": 0,
        "requests30d": 177,
        "lastRequestAt": "2026-10-23T05:23:00Z"
      },
      {
        "username": "thailand_hotels_travelask",
        "title": "thailand_hotels_travelask",
        "url": "https://t.me/thailand_hotels_travelask",
        "members": 0,
        "requests30d": 142,
        "lastRequestAt": "2026-10-23T08:06:59Z"
      }
    ],
    "windowStart": "2026-09-23T10:08:25.161782+00:00",
    "windowEnd": "2026-10-23T10:08:25.161782+00:00",
    "computedAt": "2026-10-23T10:08:25.161782+00:00",
    "countUnit": "unique request text per country and niche",
    "detailStatus": "complete"
  }
]
```

The dataset contains the delivered rows. The run's `OUTPUT` record adds counts, an explicit outcome (`results`, `valid_zero_result`, `limited` or `incomplete`), source timings and any stop reason. A source failure fails the run; it is never presented as a successful empty search.

### Cost

**$0.005 per run start + $0.050 per country × niche cell delivered.** With the 256 MB memory limit there is one start event. Ten billable results cost about **$0.505** in Actor fees. Zero matches incur only the start fee. Prices and any platform charges shown by Apify at launch are authoritative.

Set **Maximum charge per run** before starting (default $0.50). Delivery stops when the remaining budget cannot pay for another result; duplicate results are not billed twice in a run. Apify free-plan accounts receive at most 50 billable results per run. The amount of data in a snapshot may be larger than your budget permits.

### Freshness and interpretation

The computedAt, windowStart and windowEnd identify the snapshot; requests7d and requests30d use that same snapshot.

One cell means country × niche × the stated 30-day window. Identical full normalized request texts and cross-posts count once within that cell, not once per person. The same acceptance gate as Buyer Search removes obvious sellers, spam and excluded content. AI labels remain fallible. Each cell needs 50 accepted texts in at least 5 source groups. At most 60 cells are delivered; OUTPUT and the source report when the global list is truncated. Counts describe monitored coverage, not all Telegram or market share.

### Why use it

Choose where to investigate demand using consistent weekly, monthly and source-group totals, then use Buyer Search for the actual requests.

This Actor reads public catalog data. It does not join groups, send messages or contact anyone. Verify the source and suitability before outreach or business decisions.

### Watch an example

![TGDen Demand Map: a country goes in, the number of requests per niche comes out](https://api.apify.com/v2/key-value-stores/uL03GUEIHlMAysGVS/records/demandmap-motion?signature=1EAqtYSWU0jucWGQqufo6)

### API and scheduled runs

Use the same JSON input with the public Actor API. Keep your Apify token in an environment variable.

```bash
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  --data @input.json \
  "https://api.apify.com/v2/acts/telegrambest~telegram-demand-map/run-sync-get-dataset-items?memory=256&timeout=180&maxTotalChargeUsd=0.50"
```

For longer runs use Apify's asynchronous run endpoint and fetch the dataset after completion. Where available, `onlyNew=true` remembers delivered items for this Actor and your account so scheduled searches skip them. Keep it off when you want a full repeatable snapshot.

### The family

[Buyer Search](https://apify.com/telegrambest/telegram-lead-finder) · [Groups](https://apify.com/telegrambest/telegram-group-discovery) · [Similar Groups](https://apify.com/telegrambest/telegram-similar-groups) · [Channels](https://apify.com/telegrambest/telegram-channel-discovery) · [Bots](https://apify.com/telegrambest/telegram-bot-finder) · [Username Checker](https://apify.com/telegrambest/telegram-entity-enrichment) · [Marketplace Ads](https://apify.com/telegrambest/telegram-classifieds) · [Prices](https://apify.com/telegrambest/telegram-market-prices) · [Demand Map](https://apify.com/telegrambest/telegram-demand-map)

Questions or a bad result? Open an issue on this Actor and include the run link and expected behavior. Never post tokens or Telegram sessions.

# Actor input Schema

## `countries` (type: `array`):

Two-letter codes, e.g. 'ae', 'th', 'tr', 'vn', 'ru', 'kz', 'uz'. Empty — every country that reaches the threshold.

## `niches` (type: `array`):

Optional: services, goods, real-estate, jobs, freight. Empty — all.

## `includeTopGroups` (type: `boolean`):

Adds up to 24 source groups. Counts are unique accepted request texts within a cell; cross-posts count once, not as separate people.

## Actor input object example

```json
{
  "countries": [
    "ae"
  ],
  "niches": [
    "real-estate"
  ],
  "includeTopGroups": true
}
```

# Actor output Schema

## `overview` (type: `string`):

Requests per country and niche

# 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 = {
    "countries": [
        "ae",
        "th"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("telegrambest/telegram-demand-map").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 = { "countries": [
        "ae",
        "th",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("telegrambest/telegram-demand-map").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 '{
  "countries": [
    "ae",
    "th"
  ]
}' |
apify call telegrambest/telegram-demand-map --silent --output-dataset

```

## MCP server setup

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

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/bJgktOp7416SI3pAv/builds/imo6tpB50yGtc2oRW/openapi.json
