# 2GIS Scraper: Businesses, Phones & Categories (`themineworks/2gis-places-search`) Actor

Scrape 2GIS business listings across Russia, Central Asia, Cyprus and the UAE. Phone numbers, published emails, ratings, addresses and branch counts, by city or category.

- **URL**: https://apify.com/themineworks/2gis-places-search.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 businesses

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?

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

## 2GIS Scraper: Businesses, Phones, Emails & Ratings

🏆 Part of The Mine Works' 149-actor portfolio · 40,000+ runs · 200,000+ results delivered across our full distribution stack · 99.9%+ success rate

💰 $0.50 / 1,000 results.

⚡ Business listings across roughly 200 cities in Russia, Central Asia, Cyprus and
the UAE: phone numbers, published emails, ratings, branch counts and coordinates,
read from 2GIS's own catalog API rather than scraped out of HTML.
💸 No login, no API key of your own.

Pay only for results delivered. [Browse all Actors](https://apify.com/themineworks).

Scrape business listings from 2GIS, the mapping and business directory used across Russia, Kazakhstan, Uzbekistan, Azerbaijan, Cyprus and the UAE. No login, no API key of your own, no browser.

✅ Phone on 97% of records · ✅ Website on 91% · ✅ **Email on 71%** · ✅ Rating and review count on 99% · ✅ Around 200 cities · ✅ Empty runs never billed

### Scrape businesses by category and city

```json
{
  "queries": ["кафе"],
  "city": "Москва",
  "maxItems": 500
}
```

Search in the local language for far better coverage. A single query like `кафе` in Moscow has over 8,600 businesses behind it.

### Any city 2GIS covers

The city field takes a name in its local spelling and is resolved against 2GIS's own live city list, so all roughly 200 covered cities work, not a fixed shortlist.

```json
{
  "queries": ["стоматология"],
  "city": "Алматы",
  "maxItems": 300
}
```

Moscow · Saint Petersburg · Novosibirsk · Yekaterinburg · Kazan · Almaty · Astana · Tashkent · Baku · Cyprus · Dubai and many more. A numeric 2GIS region id also works if you already have one.

### What you get for each business

Real record from a live run:

```json
{
  "name": "Му-Му, кафе",
  "category": "Кафе",
  "categories": ["Кафе", "Доставка еды", "Быстрое питание", "Столовые"],
  "address": "Манежная площадь, 1 ст2",
  "district": "Тверской",
  "city": "Москва",
  "latitude": 55.755301,
  "longitude": 37.614586,
  "phone": "+7 (495) 781-87-81",
  "website": "cafemumu.ru",
  "email": "dostavka@cafemumu.ru",
  "social_links": ["https://vk.com/cafemumu"],
  "rating": 4.8,
  "review_count": 1094,
  "chain_name": "Му-Му, кафе",
  "chain_branch_count": 18,
  "is_chain": true
}
```

| Field | Description |
| --- | --- |
| 🏢 `name`, `category`, `categories` | Business name and every category 2GIS assigns it |
| 📍 `address`, `building`, `district`, `city`, `region`, `country`, `postcode` | Full location breakdown, including city district |
| 🌐 `latitude`, `longitude` | Coordinates, named explicitly so there is no lat/lon swap |
| 📞 `phone`, `phones` | Primary number plus every other number listed |
| 🔗 `website`, `websites` | Real hostname, with 2GIS's redirect wrapper stripped off |
| 📧 `email`, `emails` | Published contact addresses |
| 💬 `social_links` | VK, Telegram, Instagram, Facebook, WhatsApp, YouTube profiles |
| ⭐ `rating`, `review_count` | Star rating and review volume |
| 🏬 `chain_name`, `chain_branch_count`, `is_chain` | Whether this is one outlet of a chain, and how many branches it has |
| 🕒 `schedule_is_24x7` | Whether the business is always open |

#### Why the email coverage is unusual

Most business-directory scrapers return a phone and nothing else. This one returns a **published email on roughly 7 in 10 records**, because 2GIS's own directory carries them. For outbound work that is often the difference between a usable list and one that needs a separate enrichment step.

### How this actor gets contact details

Worth knowing, because it explains the coverage. 2GIS's **search page HTML contains no contact details at all**: its embedded state carries entrances, nearest metro and parking, but no phone, website or email. An HTML-scraping build of this actor returned 53 businesses with zero phones and zero websites.

This actor instead reads **2GIS's own public catalog API**, the one their website's frontend uses, which returns contacts inline. That single change means:

| | HTML route | This actor |
| --- | --- | --- |
| Businesses per request | 12 | **50** |
| Phone and website | none at all | **97% / 91%** |
| Results reachable per query | 53 before repeating | **8,600+** |

You do not need an API key of your own. The actor reads 2GIS's public browser key from their site at startup and falls back to a known value, so a key rotation does not break your runs.

### Common use cases

**B2B lead generation across Russia and Central Asia**, with phone and email in the same record.

**Franchise and retail site selection**, using district, coordinates and local competitive density.

**Chain and competitor mapping.** The `chain_branch_count` field separates independents from multi-branch operators in one pass.

**Market sizing.** Every query reports how many businesses exist in that city and category.

### Pricing

| Event | Price | You pay when |
| --- | --- | --- |
| Business | $0.0005 | A 2GIS business record is delivered to your dataset |
| Actor Start | $0.005 | Once per run start (one event per GB of memory, minimum one) |

Flat rate, the same on every Apify plan from Free to Diamond. A query that
returns nothing delivers nothing and bills nothing beyond the start event.

### Run it on a schedule

1. Run once with the input you want repeated, then click **Save as a task**.
2. Turn on **Monitor mode** so later runs return only newly listed businesses.
3. In the Apify Console go to **Schedules** and add the saved task.

Nothing is charged just for a schedule existing.

### FAQ

**Do I need a 2GIS API key?**
No. The actor uses the same public browser key 2GIS's own website uses, and reads it live so rotations do not break anything.

**Should I search in Russian or English?**
In the local language, for anything generic. `аптека` vastly outperforms `pharmacy`.

**How deep can one query go?**
Very deep. A common category in a large city has thousands of businesses, and the actor pages through them 50 at a time up to your `maxItems`.

**Are duplicates possible?**
No. Every business is deduplicated on its 2GIS id within a run, and monitor mode extends that across runs.

**Is this GDPR compliant?**
It collects business contact details that businesses have published in a public directory. You are responsible for having a lawful basis for contacting them.

### Use from Claude, ChatGPT and any MCP agent

```
https://mcp.apify.com/?tools=themineworks/2gis-places-search
```

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/2gis-places-search').call({
    queries: ['кафе'],
    city: 'Москва',
    maxItems: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Part of the Russia and CIS local business suite

Cross-check the same city on
[Yandex Maps Search](https://apify.com/themineworks/yandex-maps-search) for a
second source of ratings and contact data, or pull live marketplace pricing from
[Ozon Product Search](https://apify.com/themineworks/ozon-product-search) if you
are looking at the retail side of the same market.

Keywords: 2GIS scraper, Russia business directory API, Central Asia business
listings, business phone number scraper Russia, 2GIS catalog API, CIS lead
generation, franchise site selection Russia

# Actor input Schema

## `queries` (type: `array`):

Business types or names. Searching in the local language returns far more results, e.g. "кафе" rather than "cafe".

## `city` (type: `string`):

City name in its local spelling, e.g. Москва, Алматы, Toshkent, Bakı. Any of the ~200 cities 2GIS covers works, and a numeric 2GIS region id is also accepted.

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

Maximum businesses to return across all queries. Default 50, maximum 5000.

## `monitorMode` (type: `boolean`):

Run on a schedule and get ONLY businesses not delivered in a previous run. Keep the input the same across runs.

## Actor input object example

```json
{
  "queries": [
    "кафе"
  ],
  "city": "Москва",
  "maxItems": 50,
  "monitorMode": false
}
```

# 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 = {
    "queries": [
        "кафе"
    ],
    "city": "Москва",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/2gis-places-search").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 = {
    "queries": ["кафе"],
    "city": "Москва",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/2gis-places-search").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 '{
  "queries": [
    "кафе"
  ],
  "city": "Москва",
  "maxItems": 50
}' |
apify call themineworks/2gis-places-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/2gis-places-search"
        }
    }
}

```

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/kGTTH5jDgkzEpnd1t/builds/uQhK6KAYa3t9W6Uoa/openapi.json
