# 2GIS Places Scraper (`mina_safwat/2gis-scraper`) Actor

Scrapes businesses from 2GIS (Russia, Kazakhstan, UAE, Uzbekistan, Kyrgyzstan, Azerbaijan, Cyprus, Chile and more) by search query and city or by link: name, categories, address, coordinates, phones, website, e-mails, social links, opening hours, rating and optional reviews.

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

## Pricing

from $2.00 / 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.

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

### What does 2GIS Places Scraper do?

**2GIS Places Scraper** collects **businesses from [2GIS](https://2gis.ru)**, the city directory and map used across **Russia, Kazakhstan, the UAE (Dubai, Abu Dhabi, Sharjah), Uzbekistan, Kyrgyzstan, Azerbaijan, Cyprus and Chile**. Type what you are looking for and a city, or paste 2GIS links, and get one row per business with its **name, categories, address, coordinates, phone numbers, website, e-mails, social links, opening hours, rating and review count**, plus the **newest reviews** if you want them.

Try it with the prefilled input: open the Actor, click **Start**, and ten Dubai coffee shops are ready in a few seconds. Because it runs on the Apify platform, you also get API access, scheduled runs, integrations (Google Sheets, Make, Zapier, Slack, webhooks), proxy rotation and run monitoring.

### Why scrape 2GIS?

- **Lead generation.** 2GIS lists phones, websites, e-mails and messenger links (WhatsApp, Telegram, VK, Instagram and more) for most businesses, and phone numbers come in full, not masked.
- **Market research.** Count the dentists, car services or cafes in a city, see which chains have the most branches, and map where they are.
- **Local SEO and reputation.** Track ratings and review counts for your branches and your competitors, and read the newest reviews with the owner's replies.
- **Data enrichment.** Add coordinates, opening hours, categories and features (payment methods, Wi-Fi, average bill…) to a list of businesses you already have.

### How to scrape businesses from 2GIS

1. Under **Search queries**, type what you want, one per line, just as you would on 2GIS: `cafe`, `стоматология`, `car service`, `Starbucks`.
2. Under **City**, type the city: `Dubai`, `Abu Dhabi`, `Moscow`, `Москва`, `Almaty`, `Tashkent`, `Baku`, `Limassol`…
3. Or paste **2GIS links** instead: a business, a search, a category, or all branches of a company. Links from any 2GIS site work (2gis.ru, 2gis.ae, 2gis.kz, 2gis.uz, 2gis.kg, 2gis.az, 2gis.com.cy, 2gis.cl).
4. Choose how many places you want per search, and turn on **Include reviews** if you need them.
5. Click **Start**, then download the results when the run finishes.

### Input

Everything is set on the Input tab. In JSON, the input looks like this:

```json
{
    "searchQueries": ["coffee", "dentist"],
    "city": "Dubai",
    "startUrls": [
        "https://2gis.ru/moscow/search/кафе",
        "https://2gis.ae/dubai/firm/70000001006365610"
    ],
    "maxPlacesPerSearch": 100,
    "includeReviews": true,
    "maxReviewsPerPlace": 20,
    "language": "en"
}
```

| Field | What it does |
|---|---|
| `searchQueries` | What to search for, one per line. Each query is searched in `city`. |
| `city` | The city for the search queries, in English or the local language. The run log names the city it found (for example "Searching in Abu Dhabi, UAE"). |
| `startUrls` | 2GIS links, one per line: a business (`…/dubai/firm/70000001006365610`), a search (`…/moscow/search/кафе`), a category (`…/search/Кафе/rubricId/161`), all branches of a company (`…/moscow/branches/70000001034739764`), or a bare place ID. Plain strings and `{"url": "…"}` objects both work, with or without `https://`. A search link searches the whole 2GIS region of its city (for example the whole UAE for `2gis.ae/dubai`). |
| `maxPlacesPerSearch` | Stops after this many places per search query or search link, in 2GIS's own order. `0` takes every place 2GIS lists. Default: 100. |
| `includeReviews` | Adds the newest reviews with a star rating to each place. Default: off. |
| `maxReviewsPerPlace` | How many reviews per place when reviews are on. `0` takes all. Default: 20. |
| `language` | `en`, `ru`, `ar`, `kk`, `uz`, `ky`, `az`, `es` and others, for names, categories and addresses. Each country has only a few versions (UAE: English or Arabic; Russia: Russian, English and others; Kazakhstan: Russian or Kazakh), so when a country lacks the one you chose, its default is used and the log says so. Leave empty for each site's own language. |
| `proxyConfiguration` | Leave it empty. The Actor uses Apify's datacenter proxy and switches to residential proxy on its own if 2GIS stalls or refuses. |

### Output

Each business becomes one row. Here is a real example, with its review list shortened to one:

```json
{
    "id": "70000001006365610",
    "name": "Hard Rock, cafe",
    "category": "Cafe / Restaurants",
    "rubrics": ["Cafe / Restaurants"],
    "address": "Dubai Festival City Mall, 9, Crescent Drive",
    "addressComment": "2 Floor",
    "postcode": null,
    "district": "Al Kheeran",
    "city": "Dubai",
    "country": "UAE",
    "lat": 25.22365,
    "lng": 55.351308,
    "phones": ["+97142328900"],
    "website": "http://cafe.hardrock.com",
    "websites": ["http://cafe.hardrock.com"],
    "emails": [],
    "socialLinks": {
        "twitter": "https://twitter.com/hardrockcafedxb",
        "youtube": "https://youtube.com/user/hardrock",
        "instagram": "https://instagram.com/hardrockcafedxb",
        "facebook": "https://facebook.com/hardrockcafedxb"
    },
    "workingHours": {
        "Mon": "12:00-01:00", "Tue": "12:00-01:00", "Wed": "12:00-01:00",
        "Thu": "12:00-01:00", "Fri": "12:00-02:00", "Sat": "12:00-02:00",
        "Sun": "12:00-01:00"
    },
    "utcOffset": "+04:00",
    "rating": 4.6,
    "reviewCount": 137,
    "photoCount": 64,
    "attributes": ["Average bill 60 AED", "American cuisine", "Live music", "Wi-Fi", "Payment by credit cards"],
    "organizationId": "70000001006365611",
    "branchCount": 3,
    "isAdvertiser": false,
    "url": "https://2gis.ae/dubai/firm/70000001006365610",
    "reviews": [
        {
            "id": "305299300",
            "rating": 5,
            "text": "5/5",
            "date": "2026-10-12T01:19:17.893345+07:00",
            "editedDate": null,
            "authorName": "Inderpreet Singh",
            "likes": 0,
            "photoCount": 0,
            "ownerReply": null,
            "ownerReplyDate": null,
            "source": "2gis"
        }
    ],
    "scrapedAt": "2026-10-20T15:12:22.472251+00:00"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. The Output tab has two views: **Places** (the main columns) and **Full details** (every field).

### Data fields

| Field | Description |
|---|---|
| `id` | The business's 2GIS branch ID. |
| `name` | Name as 2GIS shows it, usually "Brand, type". |
| `category` | The main 2GIS category. |
| `rubrics` | Every 2GIS category the business is listed in. |
| `address` | Street address, or the building name and address. |
| `addressComment` | Floor, office or entrance note, when given. |
| `postcode` | Postcode, where 2GIS has one (common in Russia, rare in the UAE). |
| `district`, `city`, `country` | Where the business is. |
| `lat`, `lng` | Coordinates. |
| `phones` | Phone numbers in international format. |
| `website` | The business's own website (2GIS's click-tracking link is removed). |
| `websites` | Every website the business lists, the first one being `website`. |
| `emails` | Public business e-mail addresses. |
| `socialLinks` | One link per network, such as `whatsapp`, `telegram`, `instagram`, `facebook`, `vkontakte`, `youtube`. |
| `workingHours` | Opening hours per day in the place's local time, such as `"09:00-18:00"`; `"closed"` for days off and `"00:00-24:00"` for places open around the clock. Empty when 2GIS has no hours. |
| `utcOffset` | The place's time zone as an offset from UTC, such as `"+04:00"` in Dubai. |
| `rating` | Average rating out of 5, or `null` for places without ratings. |
| `reviewCount` | Number of reviews on 2GIS. |
| `photoCount` | Number of photos on 2GIS. |
| `attributes` | Features 2GIS lists, such as payment methods, average bill, cuisine, Wi-Fi or awards. |
| `organizationId`, `branchCount` | The company the branch belongs to, and how many branches it has. |
| `isAdvertiser` | `true` when the business advertises on 2GIS. |
| `url` | Link to the business on 2GIS. |
| `reviews` | Only with **Include reviews**: newest first, each with `rating`, `text`, `date` and `editedDate` (ISO 8601 with time zone), `authorName`, `likes`, `photoCount`, `ownerReply`, `ownerReplyDate` and `source`. |
| `scrapedAt` | When the row was saved, in UTC. |

### How much does it cost to scrape 2GIS?

The Actor uses **pay-per-event** pricing: you pay for each business saved and, when reviews are on, for each review saved. See the **Pricing** tab for the exact prices. Searches and links that find nothing are never charged, and if you set a maximum cost for a run, the Actor stops as soon as it is reached.

Runs are light and fast: the Actor reads 2GIS's own data service over plain HTTP, 50 businesses per request, without a browser. In testing, 1,000 Moscow cafes took about 35 seconds.

### Tips for scraping 2GIS

- **Use the city field for one city.** `Abu Dhabi` searches only Abu Dhabi, while a pasted `2gis.ae/dubai/search/…` link searches the whole UAE region, which is how the 2GIS site itself works.
- **Category links are precise.** On 2GIS, click a category (such as Cafes), copy the address bar, and paste it: you get exactly the businesses in that category.
- **All branches of a chain**: open a business, click its branches, and paste that `…/branches/…` link.
- **Keep reviews off** when you only need contacts: runs are faster and cheaper.
- A business found by two searches is saved once.
- **Saudi Arabia**: 2GIS shows the map there but has almost no business listings yet, so searches usually find nothing.

### FAQ, disclaimers and support

**Why did my search return fewer places than I asked for?** 2GIS listed fewer matching businesses in that city. Searches that find nothing, cities 2GIS doesn't know, and links that are not 2GIS businesses or searches are listed with their reason in the `FAILED_INPUTS` record of the run's key-value store, and the status message gives the counts. A run fails only when every input could not be loaded because of an error on 2GIS's side or the network.

**What about businesses that closed?** Places 2GIS has removed from its directory are skipped in searches, and a link to one is listed in `FAILED_INPUTS` as "removed from 2GIS" with the date, so you are never charged for them.

**Are short go.2gis.com links supported?** Not yet. Open the short link in your browser and paste the full address it opens.

**Is it legal to scrape 2GIS?** This Actor collects business information that 2GIS publishes for anyone to see. Business contacts are the businesses' own. Reviews include the reviewer's display name as 2GIS shows it publicly; if you store or republish reviews, personal data rules such as the GDPR may apply. You are responsible for making sure your use complies with 2GIS's terms and the laws that apply to you. If in doubt, ask a lawyer.

**Found a problem or need a custom solution?** Open an issue on the **Issues** tab and we will look into it. Custom scrapers and data feeds are available on request.

# Actor input Schema

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

What to search for, one per line, just as you would type it into 2GIS: a category (cafe, dentist, car service), a brand (Starbucks) or any words. Each query is searched in the city below.

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

The city to search in, in English or the local language, such as Dubai, Abu Dhabi, Moscow, Москва, Almaty, Tashkent, Riyadh or Limassol. Needed for search queries; links carry their own city.

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

2GIS links, one per line, from any 2GIS site (2gis.ru, 2gis.ae, 2gis.kz, 2gis.uz…): a place (https://2gis.ae/dubai/firm/70000001006365610), a search (https://2gis.ru/moscow/search/кафе), a category (…/search/Кафе/rubricId/161), or all branches of a company (https://2gis.ru/moscow/branches/70000001034739764). A bare place ID works too. Links pasted without https:// are fine.

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

Stops after this many places for each search query or search link, in 2GIS's own order. Set 0 for every place 2GIS lists (a big city can have several thousand cafes).

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

Adds the newest reviews with a star rating to each place, in a reviews list. Each review is billed as one review event on top of the place.

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

How many of the newest reviews to add to each place when reviews are on. Set 0 for all of them.

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

Language for names, categories and addresses. 2GIS translates each country into a few languages only (for example English or Arabic in the UAE, Russian or English in Russia); when a country has no such version, its default language is used and the log says so. Review texts are always as their authors wrote them.

## `proxyConfiguration` (type: `object`):

Leave this empty: the Actor uses Apify's datacenter proxy, and retries through residential proxy on its own if 2GIS ever refuses.

## Actor input object example

```json
{
  "searchQueries": [
    "coffee"
  ],
  "city": "Dubai",
  "startUrls": [],
  "maxPlacesPerSearch": 10,
  "includeReviews": false,
  "maxReviewsPerPlace": 20,
  "language": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "searchQueries": [
        "coffee"
    ],
    "city": "Dubai",
    "maxPlacesPerSearch": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/2gis-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 = {
    "searchQueries": ["coffee"],
    "city": "Dubai",
    "maxPlacesPerSearch": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/2gis-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 '{
  "searchQueries": [
    "coffee"
  ],
  "city": "Dubai",
  "maxPlacesPerSearch": 10
}' |
apify call mina_safwat/2gis-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mina_safwat/2gis-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/nz8VoxsG41bQJCP0T/builds/DE5pbHvkcUHM6Nxkx/openapi.json
