# 2GIS Business Directory Extractor for CIS & Middle East (`vexaloom-labs/2gis-business-directory-extractor-for-cis`) Actor

Search 2GIS for businesses by category and city across Russia, the UAE, Kazakhstan and the wider CIS, and get name, address, rating, hours, contacts and social links for each place.

- **URL**: https://apify.com/vexaloom-labs/2gis-business-directory-extractor-for-cis.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Lead generation, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

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

## 2GIS Business Directory Extractor for CIS & Middle East

Scrape **2GIS** business listings across 14 country sites — Russia, Kazakhstan, the UAE, Kyrgyzstan, Uzbekistan, Belarus, Azerbaijan, Armenia, Georgia, Tajikistan, Cyprus, Czechia, Italy and Chile. Search by keyword and city or map area, or paste search, place, organization and building links. Records include the address and coordinates, categories, rating and review counts when published, opening hours, contacts, social links and published attributes, plus a main photo when 2GIS exposes one. No account, API key or proxy is needed.

### What this actor does

- **Three modes:** search by keyword + city/area, read 2GIS links, or look up place IDs.
- **Rich place data:** phones, websites, emails, social links, messengers, hours, rating, review counts, attributes, nearest transit and a main photo.
- **Organization and branch discovery:** expand an organization to its branches, or read every business inside a building.
- **Real filters:** open now, 24/7, has a website, has photos, has goods/menu, has a rating or reviews, plus rating/review thresholds and category filters.
- **Optional enrichment:** review texts with rating, author, date and business replies; photo URLs.
- **Clean output:** every empty field is omitted, so records contain no nulls or placeholder values.

### Output per place

- `id` — 2GIS branch ID
- `name`, `fullName`, `shortName`, `extension`, `type`, `recordType`
- `url` — the place page on the correct 2GIS country site
- `categories`, `categoryIds`, `rubrics[]`, `primaryCategory`
- `address`, `addressComment`, `postcode`, `street`, `houseNumber`, `landmark`
- `country`, `region`, `city`, `addressCity`, `district`, `districtArea`, `cityAlias`
- `latitude`, `longitude`, `timezoneOffset`
- `phones`, `phonesFormatted`, `website`, `websites`, `emails`, `socialLinks`, `messengers`
- `rating`, `reviewCount`, `ratingCount`, `orgRating`, `orgReviewCount`, `ratingCategory`, `reviewProviders[]`
- `workingHours[]`, `scheduleText`, `is24x7`, `isClosed`
- `orgId`, `orgName`, `orgBranchCount`, `brand`
- `attributes[]`, `attributeGroups[]`, `attributesByTag`
- `photoCount` (when 2GIS returns it), `mainPhotoUrl`, `photos[]` (when photo URLs are enabled)
- `reviews[]` — review text, rating, author, date, photos and business reply (when enabled)
- `isPromoted`, `hasGoods`, `hasDiscount`, `delivery`
- `nearestStations[]`, `nearestMetro[]`
- `searchQuery`, `searchCity`, `scrapedAt`, `updatedAt`, `createdAt`, `description`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search`, `urls` or `ids` |
| `searchQueries` | array | – | Search terms (mode=search) |
| `locationQuery` | string | – | City to search in (mode=search) |
| `cities` | array | – | Additional cities; every term runs in each city |
| `cityIds` | array | – | Exact 2GIS city IDs instead of names |
| `startUrls` | array | – | Search, `/firm/`, `/branches/`, `/inside/` or short links (mode=urls) |
| `placeIds` | array | – | Branch IDs (mode=ids) |
| `latitude`, `longitude` | number | – | Center for a point search |
| `radiusMeters` | integer | `20000` | Radius around the point (1–50000) |
| `bbox` | string | – | Map rectangle as `lon1,lat1,lon2,lat2` |
| `country` | string | `auto` | Country site: `ru`, `kz`, `ae`, `kg`, `uz`, `by`, `az`, `am`, `ge`, `tj`, `cy`, `cz`, `it`, `cl` |
| `language` | string | `auto` | Content language, e.g. `ru_RU`, `ru_KZ`, `en_AE`, `kk_KZ` |
| `maxItems` | integer | `50` | Max places per search term + city/area |
| `sortBy` | string | `relevance` | `relevance`, `rating`, `distance`, `flamp_rating`, `creation_time`, `opened_time`, `name` |
| `rubricIds` | array | – | Category IDs, e.g. `162` for coffee shops |
| `districtIds` | array | – | District IDs for splitting large cities |
| `minRating` | number | – | Keep places rated at least this value |
| `minReviews` | integer | – | Keep places with at least this many reviews |
| `websiteFilter` | string | `all` | `all`, `with` or `without` a website |
| `filterHasPhotos` | boolean | false | Only places with photos |
| `filterOpenNow` | boolean | false | Only places open now |
| `filter24x7` | boolean | false | Only places open around the clock |
| `filterHasGoods` | boolean | false | Only places with goods or a menu |
| `filterHasRating` | boolean | false | Only places with a rating |
| `filterHasReviews` | boolean | false | Only places with reviews |
| `filterDelivery` | boolean | false | Only places whose attributes mention delivery |
| `filterTakeaway` | boolean | false | Only places whose attributes mention takeaway |
| `filterCardPayment` | boolean | false | Only places whose attributes mention card payment |
| `filterWifi` | boolean | false | Only places whose attributes mention Wi-Fi |
| `minAverageCheck`, `maxAverageCheck` | integer | – | Filter by published average check |
| `skipAds` | boolean | false | Drop promoted results |
| `includeContacts` | boolean | true | Add phones, websites, emails, socials and messengers |
| `includeReviews` | boolean | false | Add review texts |
| `maxReviewsPerPlace` | integer | `10` | Max review texts per place |
| `reviewsSort` | string | `date_created` | `date_created`, `date_edited` or `rating` |
| `reviewsMinRating` | integer | – | Keep reviews with at least this rating |
| `reviewsWithAnswer` | boolean | false | Keep only reviews with a business reply |
| `reviewsSince` | string | – | Keep reviews since `YYYY-MM-DD` |
| `reviewsKeyword` | string | – | Keep reviews containing this word |
| `includePhotos` | boolean | false | Add photo URLs |
| `maxPhotosPerPlace` | integer | `5` | Max photo URLs per place |
| `scrapeOrgBranches` | boolean | false | Expand a place link to its organization's branches |

#### Example: coffee shops in Moscow

```json
{
  "mode": "search",
  "searchQueries": ["coffee"],
  "locationQuery": "Moscow",
  "maxItems": 25,
  "websiteFilter": "with",
  "sortBy": "rating"
}
```

#### Example: Dubai restaurants that are open now

```json
{
  "mode": "search",
  "searchQueries": ["restaurant"],
  "locationQuery": "Dubai",
  "filterOpenNow": true,
  "includeContacts": true,
  "maxItems": 50
}
```

#### Example: read a place and its organization's branches

```json
{
  "mode": "urls",
  "startUrls": ["https://2gis.ru/moscow/firm/70000001044357973"],
  "scrapeOrgBranches": true,
  "includeReviews": true,
  "maxReviewsPerPlace": 5
}
```

#### Example: every business inside a building

```json
{
  "mode": "urls",
  "startUrls": ["https://2gis.ru/moscow/inside/4504235290707169"],
  "maxItems": 100
}
```

### Use cases

- **Local lead generation** — collect businesses by city and category with phone, website and email contacts.
- **Market research** — compare category coverage, ratings and review volumes across cities and countries.
- **Competitor tracking** — follow a chain's branches, addresses, hours and rating changes.
- **Reputation monitoring** — export ratings, review counts and optional review texts with business replies.
- **Directory enrichment** — fill missing contacts, coordinates and opening hours in your own listings.
- **Coverage checks** — find businesses without a website, without photos or without reviews.

### FAQ

#### Do I need a 2GIS account or API key?

No. The actor reads 2GIS's public directory data and needs no account, API key, cookie or proxy. Just choose a search term and a city.

#### Which countries are supported?

Russia, Kazakhstan, the UAE, Kyrgyzstan, Uzbekistan, Belarus, Azerbaijan, Armenia, Georgia, Tajikistan, Cyprus, Czechia, Italy and Chile. The country site is detected automatically from a link or resolved from the city.

#### Why are some fields missing from a place?

2GIS listings vary. A website, email, social link, photo or review is only included when the business has published it. Empty fields are omitted rather than filled with null or placeholder values.

#### What is the difference between `rating` and `orgRating`?

`rating` belongs to the individual branch. `orgRating` and `orgReviewCount` aggregate the whole organization. `ratingCount` counts star votes, while `reviewCount` counts written reviews.

#### Do reviews and photos work for every place?

Rating and review counts are included whenever 2GIS publishes them. Review texts and photo URLs are optional and depend on what 2GIS exposes for that place. A main photo URL and an exact photo count are included when 2GIS returns them; places with no reviews or photos simply omit those fields.

#### How do I get more than the default number of places?

Raise `maxItems`. For very large categories, split the search by district, category (`rubricIds`) or several narrower search terms. The run status message tells you if more places were available than were requested.

#### How do I search in Russian, Kazakh or Arabic?

Use the local spelling in `searchQueries` and `locationQuery` (for example `кофейня` and `Москва`), or set `language` to the content language you want.

#### Is this affiliated with 2GIS?

No. This is a third-party actor that reads the public 2GIS directory. It is not affiliated with, endorsed by, or sponsored by 2GIS.

# Actor input Schema

## `mode` (type: `string`):

What to read: search the directory, expand 2GIS links, or look up place IDs.

## `searchQueries` (type: `array`):

What to look for, one term per line (mode=search). Example: coffee, restaurant, стоматология. Use the local language for better coverage.

## `locationQuery` (type: `string`):

City or area to search in (mode=search), for example Moscow, Алматы or Dubai. Can be a local or English name.

## `cities` (type: `array`):

Optional additional cities. Every search term runs in every city (mode=search).

## `cityIds` (type: `array`):

Optional exact 2GIS city IDs. Use instead of city names when you already know the ID.

## `startUrls` (type: `array`):

Search, place (/firm/), organization (/branches/) or building (/inside/) links, go.2gis.com short links, or bare place IDs (mode=urls).

## `placeIds` (type: `array`):

2GIS branch IDs to read directly (mode=ids).

## `latitude` (type: `number`):

Center latitude for an area search (mode=search). Set together with longitude; overrides the city center.

## `longitude` (type: `number`):

Center longitude for an area search (mode=search). Set together with latitude.

## `radiusMeters` (type: `integer`):

Search radius around latitude/longitude, in meters (1–50000).

## `bbox` (type: `string`):

Optional rectangle as lon1,lat1,lon2,lat2. Overrides city and point search.

## `country` (type: `string`):

2GIS country site. Leave on Auto-detect to derive it from the city or link.

## `language` (type: `string`):

Language of names and content returned by 2GIS. Auto uses the country site's default.

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

Maximum number of places per search term + city/area combination.

## `sortBy` (type: `string`):

Order of search results. Distance needs a latitude/longitude or map area.

## `rubricIds` (type: `array`):

Only places in these 2GIS categories (rubric IDs), for example 162 for coffee shops.

## `districtIds` (type: `array`):

Optional district IDs. Useful for splitting a large city into smaller searches.

## `minRating` (type: `number`):

Keep only places rated at least this value (0–5).

## `minReviews` (type: `integer`):

Keep only places with at least this many reviews.

## `websiteFilter` (type: `string`):

Return all places, only places with a website, or only places without one.

## `filterHasPhotos` (type: `boolean`):

Only return places that have photos on 2GIS.

## `filterOpenNow` (type: `boolean`):

Only return places open at the time of the run.

## `filter24x7` (type: `boolean`):

Only return places open around the clock.

## `filterHasGoods` (type: `boolean`):

Only return places that published goods or a menu.

## `filterHasRating` (type: `boolean`):

Only return places with a rating.

## `filterHasReviews` (type: `boolean`):

Only return places with reviews.

## `filterDelivery` (type: `boolean`):

Only return places whose published attributes mention delivery.

## `filterTakeaway` (type: `boolean`):

Only return places whose attributes mention takeaway or pickup.

## `filterCardPayment` (type: `boolean`):

Only return places whose attributes mention card payment.

## `filterWifi` (type: `boolean`):

Only return places whose attributes mention Wi-Fi.

## `minAverageCheck` (type: `integer`):

Keep only places whose published average check is at least this value, in local currency.

## `maxAverageCheck` (type: `integer`):

Keep only places whose published average check is at most this value, in local currency.

## `skipAds` (type: `boolean`):

Drop paid/promoted search results.

## `includeContacts` (type: `boolean`):

Add phones, websites, emails, social links and messengers.

## `includeReviews` (type: `boolean`):

Add review texts to each place when 2GIS exposes them. Rating and review counts are always included.

## `maxReviewsPerPlace` (type: `integer`):

Maximum review texts per place when reviews are enabled (1–1000).

## `reviewsSort` (type: `string`):

Order of review texts.

## `reviewsMinRating` (type: `integer`):

Keep only reviews with at least this star rating (1–5).

## `reviewsWithAnswer` (type: `boolean`):

Keep only reviews that have an official business reply.

## `reviewsSince` (type: `string`):

Keep only reviews created on or after this date (YYYY-MM-DD).

## `reviewsKeyword` (type: `string`):

Keep only reviews whose text contains this word or phrase.

## `includePhotos` (type: `boolean`):

Add photo URLs when 2GIS exposes them. A main photo URL and photo count are included whenever available.

## `maxPhotosPerPlace` (type: `integer`):

Maximum photo URLs per place when photos are enabled (1–100).

## `scrapeOrgBranches` (type: `boolean`):

When a place link is given, also return the other branches of the same organization.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "coffee"
  ],
  "locationQuery": "Moscow",
  "radiusMeters": 20000,
  "country": "auto",
  "language": "auto",
  "maxItems": 3,
  "sortBy": "relevance",
  "websiteFilter": "all",
  "filterHasPhotos": false,
  "filterOpenNow": false,
  "filter24x7": false,
  "filterHasGoods": false,
  "filterHasRating": false,
  "filterHasReviews": false,
  "filterDelivery": false,
  "filterTakeaway": false,
  "filterCardPayment": false,
  "filterWifi": false,
  "skipAds": false,
  "includeContacts": true,
  "includeReviews": false,
  "maxReviewsPerPlace": 10,
  "reviewsSort": "date_created",
  "reviewsWithAnswer": false,
  "includePhotos": false,
  "maxPhotosPerPlace": 5,
  "scrapeOrgBranches": false
}
```

# Actor output Schema

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

All 2GIS place records from the run, in the default dataset.

# 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 = {
    "mode": "search",
    "searchQueries": [
        "coffee"
    ],
    "locationQuery": "Moscow",
    "maxItems": 3,
    "includeContacts": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/2gis-business-directory-extractor-for-cis").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 = {
    "mode": "search",
    "searchQueries": ["coffee"],
    "locationQuery": "Moscow",
    "maxItems": 3,
    "includeContacts": True,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/2gis-business-directory-extractor-for-cis").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 '{
  "mode": "search",
  "searchQueries": [
    "coffee"
  ],
  "locationQuery": "Moscow",
  "maxItems": 3,
  "includeContacts": true
}' |
apify call vexaloom-labs/2gis-business-directory-extractor-for-cis --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/2gis-business-directory-extractor-for-cis"
        }
    }
}
```

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/egAceUslWJ9ezEaPL/builds/VmwSyA6i1GQqfVvgJ/openapi.json
