# 2GIS Places Scraper: Every Result, Contacts (`luzivanlt/2gis-places-scraper`) Actor

2GIS places with phones, emails, sites, socials, hours and ratings, every result of a search. $2 per 1,000 places. Russia, Kazakhstan, UAE.

- **URL**: https://apify.com/luzivanlt/2gis-places-scraper.md
- **Developed by:** [Luzi](https://apify.com/luzivanlt) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 places

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?

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 Places Scraper: Every Result, Contacts

Get every place a 2GIS search finds, not just the first pages: each search is
read to the last result 2GIS counts for it, with phones, emails, websites,
social profiles, opening hours, rating and reviews count on every row, at no
extra cost. Russia, Kazakhstan, the UAE and every other 2GIS city. No
account, login or cookies needed.

Tested daily. Latest checks: an Almaty café search read whole, 2,929 places
against the 2,926 that 2GIS counts, in under 5 minutes; and 200 places from
two UAE searches in English.

### What does this Actor do?

You give it search terms and cities, 2GIS category ids, or 2GIS links. For
each search it reads the places 2GIS finds and saves one row per place with
everything 2GIS lists for it. A source can be:

- a **search term in a city**, such as `кафе` in `Moscow` or `dentist` in
  `Almaty`
- a **category in a city**, such as `161` (cafes) in `Almaty`, read whole
- a **2GIS search or category page**, such as
  `https://2gis.ru/moscow/search/кафе` or
  `https://2gis.ru/moscow/search/Кафе/rubricId/161`
- a **place page**, such as `https://2gis.kz/almaty/firm/70000001012345678`

Each row comes with:

- the place id, its link, name (full, short and the kind of business), type
  (a business, or a building or station a search lists)
- the main category, every category with its id, and the 2GIS summary
- the address as shown and in full, its comment (floor, entrance), postcode,
  street and house number, the building's name, purpose and floor count,
  landmark, country, region, city and district, and the coordinates
- phones, emails, websites and social profiles (Telegram, WhatsApp, VK,
  Instagram, YouTube, …), and every contact as 2GIS lists it, with its comment
- opening hours for each day, as a table and as text, and whether it is open
  24/7
- the rating and reviews count, the count of rated reviews, the rating of the
  whole chain, and the rating and reviews count of each review site 2GIS shows
- the organization and brand behind it, and how many branches each has
- the average check, lunch price, payment methods, awards and every feature
  2GIS lists (Wi-Fi, delivery, terrace, …), grouped as on 2GIS
- the nearest stops and metro stations with their distance, parking, and
  entrances
- whether it advertises on 2GIS, and its promotion text
- when 2GIS added and last updated it, its taxpayer id and staff count where
  2GIS shows them
- the search it came from, the number of results 2GIS counts for that search,
  and its position there

### Why use it?

- **Every result, checked against 2GIS's own count.** A search is read page
  after page until the last result 2GIS counts, thousands of places if the
  city has them, and the run says for each search whether all of them were
  read.
- **Contacts on every row at no extra cost.** Phones, emails, websites and
  social profiles are part of each place, not a paid add-on.
- **Every 2GIS city.** Russia, Kazakhstan, Uzbekistan, Kyrgyzstan, the UAE,
  Azerbaijan, Armenia, Georgia, Cyprus, Saudi Arabia and the rest, in the
  city's own language or another 2GIS has for it.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Type **Search terms** and **Cities**, add **Category ids**, or paste
   **2GIS links**.
2. Optionally, set **Max places per search** and **Language**.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   places or download them.

Run it with no input to see a sample: 50 cafes in Moscow, charged as usual.

### Input

| Field                                            | What it does                                                          | Default  |
| ------------------------------------------------ | --------------------------------------------------------------------- | -------- |
| **Search terms** (`searchTerms`)                 | What to search 2GIS for; each term is searched in each city           | —        |
| **Cities** (`cities`)                            | The 2GIS cities to search in, by name or by the code in a 2GIS link   | —        |
| **Category ids** (`categoryIds`)                 | 2GIS category ids to read whole in each city, such as `161` for cafes | —        |
| **2GIS links** (`startUrls`)                     | Search, category or place pages on any 2GIS site                      | —        |
| **Max places per search** (`maxPlacesPerSearch`) | The most places to save from each search, category or link (1–50,000) | 100      |
| **Language** (`language`)                        | The language of names, categories and addresses                       | `"auto"` |

Give at least one search term or category with a city, or a link. Example
input:

```json
{
  "searchTerms": ["dentist", "pharmacy"],
  "cities": ["Almaty", "Astana"],
  "startUrls": ["https://2gis.ae/dubai/search/restaurant"],
  "maxPlacesPerSearch": 1000,
  "language": "auto"
}
```

### Output

One row per place. An example, with made-up values and shortened lists:

```json
{
  "place_id": "70000001012345678",
  "type": "branch",
  "name": "Example Coffee, coffee house",
  "name_primary": "Example Coffee",
  "short_name": "Example",
  "name_extension": "coffee house",
  "url": "https://2gis.ru/moscow/firm/70000001012345678",
  "category": "Cafes",
  "categories": ["Cafes", "Coffee houses"],
  "category_ids": ["161", "162"],
  "summary": "Specialty coffee and pastries",
  "address": "Example street, 12",
  "full_address": "Moscow, Example street, 12",
  "address_comment": "2nd floor",
  "postcode": "100001",
  "street": "Example street",
  "house_number": "12",
  "building_name": "Example Plaza",
  "building_purpose": "Shopping centre",
  "building_floors": 5,
  "country": "Russia",
  "region": "Moscow",
  "city": "Moscow",
  "district": "Central",
  "latitude": 55.7558,
  "longitude": 37.6173,
  "phone": "+70000000000",
  "phones": ["+70000000000"],
  "email": "hello@example.com",
  "emails": ["hello@example.com"],
  "website": "https://example.com",
  "websites": ["https://example.com"],
  "social_profiles": [{ "type": "telegram", "url": "https://t.me/example" }],
  "opening_hours": {
    "Mon": [{ "from": "08:00", "to": "22:00" }],
    "Tue": [{ "from": "08:00", "to": "22:00" }]
  },
  "opening_hours_text": "Mon 08:00-22:00; Tue 08:00-22:00; …",
  "is_open_24x7": false,
  "rating": 4.7,
  "reviews_count": 312,
  "rated_reviews_count": 290,
  "org_rating": 4.6,
  "org_reviews_count": 1203,
  "review_providers": [{ "provider": "flamp", "rating": 4.5, "review_count": 40 }],
  "org_id": "70000001012345677",
  "org_name": "Example Coffee",
  "org_branch_count": 8,
  "brand_name": null,
  "average_check": "Average check 600 ₽",
  "payment_methods": ["Card", "Cash"],
  "awards": [],
  "features": ["Card", "Wi-Fi", "Takeaway"],
  "nearest_stations": [{ "name": "Example station", "distance": 300, "route_types": ["metro"] }],
  "is_advertised": false,
  "promo_text": null,
  "created_at": "2019-03-01T00:00:00Z",
  "updated_at": "2026-10-01T00:00:00Z",
  "taxpayer_id": "7700000000",
  "search_query": "кафе",
  "search_city": "Москва",
  "search_total": 8595,
  "search_order": "relevance",
  "position": 1,
  "source": "https://2gis.ru/moscow/search/кафе"
}
```

#### Output fields

- `place_id`, `type`, `url`: the place, what it is (`branch` for a business;
  a search can also list a `building`, `station` or `attraction`) and its 2GIS
  page
- `name`, `name_primary`, `short_name`, `name_extension`, `name_addition`,
  `full_name`, `caption`: the name as shown, its parts, and the full name of a
  building
- `category`, `categories`, `category_ids`, `rubrics`: the main category,
  every category and its id, and each category with its kind and parent
- `poi_category`, `purpose`, `summary`: the map category, a building's
  purpose, and 2GIS's short description
- `address`, `full_address`, `address_comment`, `postcode`, `street`,
  `house_number`, `address_components`: the address as shown, in full, its
  comment, and its parts
- `building_id`, `building_name`, `building_purpose`, `building_floors`,
  `landmark`: the building the place is in
- `country`, `region`, `city`, `district`, `district_id`, `district_area`,
  `living_area`, `admin_divisions`, `city_alias`: where it is
- `latitude`, `longitude`, `centroid`, `timezone`, `timezone_offset`: the
  point on the map and the local time zone
- `phone`, `phones`, `email`, `emails`, `website`, `websites`: the first and
  every phone, email and website
- `social_profiles`: every social or messenger profile, with its kind
- `contacts`: every contact as 2GIS lists it, with its text, its comment and
  the group it is in (a branch can list a separate group for delivery)
- `opening_hours`, `opening_hours_text`, `opening_hours_comment`,
  `is_open_24x7`, `contact_group_hours`: hours for each day, as text, any
  note, 24/7, and the hours of each contact group
- `rating`, `reviews_count`, `rated_reviews_count`: the 2GIS rating and its
  reviews
- `branch_rating`, `branch_reviews_count`, `recommendation_count`,
  `flamp_rating`, `flamp_reviews_count`, `review_providers`,
  `is_reviewable`, `is_reviewable_on_flamp`: the rating of each review site
  2GIS shows
- `org_rating`, `org_reviews_count`, `org_rated_reviews_count`: the rating of
  every branch of the organization together
- `org_id`, `org_name`, `org_primary_name`, `org_extension`,
  `org_branch_count`: the organization behind the place and its branch count
- `brand_id`, `brand_name`, `brand_extension`, `brand_branch_count`: the
  brand, for chains
- `branches_in_building`: how many places 2GIS lists in a building
- `employees_org_count`, `taxpayer_id`: staff count and taxpayer id (INN),
  where 2GIS shows them
- `average_check`, `lunch_cost`, `payment_methods`, `awards`, `features`,
  `attribute_groups`: what 2GIS lists about the place, flat and grouped as on
  2GIS
- `has_photos`, `badges`: whether it has photos, and any 2GIS badge
- `is_advertised`, `is_promoted`, `promo_text`, `promo_warning`,
  `promo_link_text`, `promo_link_url`: its advertising on 2GIS
- `has_goods`, `has_pinned_goods`, `has_discount`, `has_exchange`,
  `has_realty`, `has_apartments_info`, `has_dynamic_congestion`: what else
  2GIS has for it
- `floors_ground_count`, `group`, `is_main_in_group`: a building's floors and
  the group it belongs to
- `nearest_stations`, `nearest_metro`, `nearest_parking_ids`, `parking`,
  `entrances`, `database_entrances`: stops, metro, parking and entrances
- `search_context`: why 2GIS matched it to the search
- `created_at`, `updated_at`: when 2GIS added it and last updated it
- `region_id`, `segment_id`, `locale`: the 2GIS city and the language read
- `search_query`, `search_rubric_id`, `search_city`, `search_total`,
  `search_order`, `position`, `source`: the search, the number of results 2GIS
  counts for it, the order it was read in (`relevance`, 2GIS's own, `name` or
  `opened_time`), the place's position in that order, and the link or search
  it came from

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

This Actor is priced per place saved:

- **$2 per 1,000 places** ($0.002 a place). A place found by two searches in
  one run is saved and charged once.
- No start fee, nothing per search, and no extra charge for contacts.

So a search of 500 places costs $1. If you set a maximum cost for a run, the
Actor stops when it reaches it and keeps every place saved so far.

### How long does a run take?

About 10 seconds for the sample (50 places). A whole Almaty café search,
2,926 places by 2GIS's count, took 276 seconds, about 10 places a second;
a search read whole is read in two orders, so it takes about twice the pages
of a capped one (the price is per place either way).

### Good to know

- **A search is read to the end.** It stops at **Max places per search** or
  at the last result 2GIS counts, whichever comes first; the run's status
  names any search that ended below 2GIS's count.
- **The order depends on whether the whole search fits.** When Max places per
  search covers every result, the search is read twice, in name order and by
  opening date (`search_order`), because 2GIS answers from servers whose lists
  differ slightly and no single order lists every place; each place is saved
  and charged once. When it does not, you get the first places in 2GIS's own
  order (`"relevance"`), and 2GIS's reshuffling between pages can leave a
  capped search a few places short of the cap.
- **A city is a 2GIS region.** Moscow includes the towns of its oblast, and
  2GIS's Dubai covers the whole UAE (`search_city` says `UAE`). Add the town
  or district to the search term to narrow it: `restaurant Dubai Marina`,
  `cafe Khimki`.
- **Searches list more than businesses.** A search can also list buildings,
  stations or sights; each row's `type` says which.
- **A place found twice in a run is saved once,** with the first search that
  found it as its `source`.
- **Reviews and photos are not included.** Each row has the rating and
  reviews count, not the review texts or photo links.
- **Links with filters are not supported yet.** Remove the filters from a
  2GIS link, or use the matching category id.
- **One search that cannot be read does not stop the run.** The others carry
  on, and the run's status lists the ones that could not be read.
- **Check your links first.** A link that is not a 2GIS search, category or
  place page stops the run before anything is read, and the message names it.

### More Actors from us

- [Airbnb Scraper: Every Stay, Past the 15-Page Limit](https://apify.com/luzivanlt/airbnb-listings-scraper): Every stay of an Airbnb search, past the 15 pages Airbnb shows, checked against its count.
- [Alibaba Products Scraper: Price Tiers & Suppliers](https://apify.com/luzivanlt/alibaba-products-scraper): Alibaba.com products by keyword or link, with price tiers in US dollars on every row.
- [AliExpress Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/aliexpress-products-scraper): Every product of an AliExpress search to its last page, with exact sold counts and ratings.
- [Amazon Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/amazon-products-scraper): Every product on Amazon's search pages to the last page, sponsored marked, with monthly sales.
- [App Store Reviews Scraper: All Reviews, Not 500](https://apify.com/luzivanlt/app-store-reviews-scraper): Every written App Store review of an app, not just the newest 500.
- [Woolworths Coles ALDI Scraper: AU Grocery Prices](https://apify.com/luzivanlt/au-supermarkets-scraper): Woolworths, Coles and ALDI products for any search in one run, every results page to the end.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~2gis-places-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "searchTerms": ["кафе"],
  "cities": ["Moscow"],
  "maxPlacesPerSearch": 50,
  "language": "auto"
}
```

Its inputs, in the order of the input form:

| Input                                        | What it takes                                                                                                                                                                                                                                                                                                | Default  |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `searchTerms` (Search terms)                 | What to search 2GIS for, as you would type it on the map, e.g. кафе, dentist or car wash.                                                                                                                                                                                                                    | —        |
| `cities` (Cities)                            | The 2GIS cities to search in, by name in any spelling or by the code in a 2GIS link: e.g. Moscow, Москва, spb, Almaty, Astana, Tashkent or Dubai.                                                                                                                                                            | —        |
| `categoryIds` (Category ids)                 | 2GIS category ids to read whole in each city, e.g. 161 for cafes or 164 for restaurants (the number after rubricId/ in a 2GIS category link).                                                                                                                                                                | —        |
| `startUrls` (2GIS links)                     | 2GIS search pages (https://2gis.ru/moscow/search/кафе), category pages (https://2gis.ru/moscow/search/Кафе/rubricId/161) or place pages (https://2gis.kz/almaty/firm/70000001012345678), on any 2GIS site: 2gis.ru, 2gis.kz, 2gis.ae, 2gis.uz, 2gis.kg, 2gis.am, 2gis.az, … A link given twice is read once. | —        |
| `maxPlacesPerSearch` (Max places per search) | The most places to save from each search, category or link.                                                                                                                                                                                                                                                  | `100`    |
| `language` (Language)                        | The language of names, categories and addresses, where 2GIS has it for that city (English for Moscow and Dubai, Kazakh for Almaty, …).                                                                                                                                                                       | `"auto"` |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/2gis-places-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=luzivanlt/2gis-places-scraper"
    }
  }
}
```

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per place delivered; the sample input above costs at most $0.20.

### FAQ

**Do I need a 2GIS account or cookies?**
No. The Actor reads what anyone can see on 2GIS.

**Can I get all the cafes in a city?**
Yes. Add the cafe category id (161) and the city, or the search term `кафе`,
and raise **Max places per search** to the number of results you want; the
run says whether all of 2GIS's count was read.

**Can I keep a list up to date?**
Yes. Run it on a schedule; each row has `updated_at` and its position, so you
can compare runs.

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/2gis-places-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

What to search 2GIS for, as you would type it on the map, e.g. кафе, dentist or car wash. Each term is searched in each city below and read to the last result 2GIS counts for it. Leave empty to use only categories or links.

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

The 2GIS cities to search in, by name in any spelling or by the code in a 2GIS link: e.g. Moscow, Москва, spb, Almaty, Astana, Tashkent or Dubai. A 2GIS city is a region: Moscow includes its oblast's towns, and Dubai is 2GIS's region for the whole UAE (Abu Dhabi and Sharjah included). To narrow a search, add the town or district to the search term (cafe Khimki, restaurant Dubai Marina). Needed for search terms and categories.

## `categoryIds` (type: `array`):

2GIS category ids to read whole in each city, e.g. 161 for cafes or 164 for restaurants (the number after rubricId/ in a 2GIS category link). Each category × city is one search.

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

2GIS search pages (https://2gis.ru/moscow/search/кафе), category pages (https://2gis.ru/moscow/search/Кафе/rubricId/161) or place pages (https://2gis.kz/almaty/firm/70000001012345678), on any 2GIS site: 2gis.ru, 2gis.kz, 2gis.ae, 2gis.uz, 2gis.kg, 2gis.am, 2gis.az, … A link given twice is read once. Links with filters are not supported yet. Example: https://2gis.ae/dubai/search/restaurant

## `maxPlacesPerSearch` (type: `integer`):

The most places to save from each search, category or link. A search is read in 2GIS's own order until this many, or to the last result 2GIS counts. Default 100. You pay per place saved.

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

The language of names, categories and addresses, where 2GIS has it for that city (English for Moscow and Dubai, Kazakh for Almaty, …). Auto uses 2GIS's default for each city: Russian where 2GIS has it (Russia, Kazakhstan, Uzbekistan, …), English in the UAE. e.g. en for English names in Moscow.

## Actor input object example

```json
{
  "searchTerms": [
    "кафе"
  ],
  "cities": [
    "Moscow"
  ],
  "maxPlacesPerSearch": 50,
  "language": "auto"
}
```

# Actor output Schema

## `places` (type: `string`):

Every place the run saved, one row per place.

## `allFields` (type: `string`):

The same rows with every field.

## `runReport` (type: `string`):

What happened to each input: places saved, nothing found, refused by the site, stopped at your limit, or the error.

# 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 = {
    "searchTerms": [
        "кафе"
    ],
    "cities": [
        "Moscow"
    ],
    "maxPlacesPerSearch": 50,
    "language": "auto"
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/2gis-places-scraper").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 = {
    "searchTerms": ["кафе"],
    "cities": ["Moscow"],
    "maxPlacesPerSearch": 50,
    "language": "auto",
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/2gis-places-scraper").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 '{
  "searchTerms": [
    "кафе"
  ],
  "cities": [
    "Moscow"
  ],
  "maxPlacesPerSearch": 50,
  "language": "auto"
}' |
apify call luzivanlt/2gis-places-scraper --silent --output-dataset

```

## MCP server setup

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

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/96vPq5ysTGn4oXLXq/builds/dxEyIEiJxDL1S5Zmm/openapi.json
