# 2GIS (2ГИС) Scraper - Places, Phones + Public Reviews (`lanternlab318/2gis`) Actor

Search 2GIS by keyword and city, or paste place links: public business cards (phones, website, rating, hours) and public reviews. No login.

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

## Pricing

from $3.60 / 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

## 2GIS (2ГИС) Scraper — Places, Phones + Public Reviews

A Lantern Lab Actor. Search 2GIS by keyword and city, or paste place links, and get the public business card back: name, categories, address, coordinates, the business's own published phones, website, email and messenger links, rating, review count and opening hours — plus public reviews with star rating, text, publish time and the owner's reply. Works for every 2GIS city: Russia, Kazakhstan, Kyrgyzstan, Uzbekistan, the UAE and the rest. No 2GIS login, no cookies, no account of your own.

**Price:** pay per result — one charge per complete place row and one per review row. Partial place rows (contacts unknown or reviews cut short), empty results, per-input status rows and the run summary are free.

### What you get

```json
{
  "recordType": "place",
  "placeId": "70000001113359188",
  "name": "Здрасте, кофейня",
  "rubrics": ["Кофейни", "Кафе", "Доставка еды"],
  "primaryRubric": "Кофейни",
  "address": "Крымская набережная, 10 ст2",
  "fullAddress": "Москва, Крымская набережная, 10 ст2",
  "postalCode": "119049",
  "district": "Якиманка",
  "city": "Москва",
  "cityCode": "moscow",
  "country": "Россия",
  "latitude": 55.735952,
  "longitude": 37.605268,
  "phones": ["+79966574489"],
  "website": "http://zdrastecafe.ru",
  "websites": ["http://zdrastecafe.ru", "http://zdraste.ru"],
  "emails": [],
  "socialLinks": [
    { "type": "vkontakte", "url": "https://vk.com/zdrastecoffeebar" },
    { "type": "telegram", "url": "https://t.me/zdrastecafe" }
  ],
  "rating": 4.8,
  "reviewCount": 107,
  "ratingCount": 122,
  "schedule": { "Mon": ["10:00-22:00"], "Tue": ["10:00-22:00"], "Sun": ["10:00-22:00"] },
  "isOpen24x7": false,
  "organizationName": "Здрасте, кофейня",
  "branchCount": 103,
  "sourceUpdatedAt": "2026-10-05T05:39:06Z",
  "url": "https://2gis.ru/moscow/firm/70000001113359188",
  "source": "search_query",
  "searchQuery": "кофейня",
  "rank": 1,
  "placePageStatus": "ok",
  "partial": false,
  "partialReason": null,
  "collectedAt": "2026-10-24T03:10:41.512Z"
}
```

```json
{
  "recordType": "review",
  "reviewId": "308508053",
  "placeId": "70000001113359188",
  "placeName": "Здрасте, кофейня",
  "placeUrl": "https://2gis.ru/moscow/firm/70000001113359188",
  "rating": 5,
  "text": "Здрасьте хороший сервис пример как нужно вести себя с клиентами, кофе вкусный выпечка свежая всегда…",
  "publishedAt": "2026-10-22T03:56:23.736Z",
  "editedAt": null,
  "likes": 0,
  "commentsCount": 1,
  "photoCount": 0,
  "provider": "2gis",
  "ownerReplyText": "Спасибо вам за такие тёплые слова! Нам невероятно приятно читать ваши отзывы…",
  "ownerReplyAt": "2026-10-22T06:12:01.675Z",
  "collectedAt": "2026-10-24T03:10:42.004Z"
}
```

### Input

```json
{
  "searchQueries": ["кофейня", "стоматология"],
  "city": "moscow",
  "placeUrls": ["https://2gis.kz/almaty/firm/70000001102984632"],
  "maxPlaces": 50,
  "includeReviews": true,
  "maxReviewsPerPlace": 100
}
```

- `searchQueries` — one search term per line, best in the local language. Each is searched separately in `city`.
- `city` — the 2GIS city code from the address bar (`moscow`, `spb`, `novosibirsk`, `kazan`, `almaty`, `astana`, `bishkek`, `tashkent`, `dubai`), or a 2GIS city link. Cities outside Russia are served from their own 2GIS site automatically. Default `moscow`.
- `placeUrls` — 2GIS place links from any 2GIS site, or bare numeric place IDs.
- `maxPlaces` (default 50) — places per search term. 2GIS serves 12 per page.
- `includeReviews` (default off) and `maxReviewsPerPlace` (default 50) — public reviews, newest first.
- `maxUpstreamRequests` — optional hard ceiling on requests to 2GIS. Left empty, the Actor derives one from your input, so a run is never unbounded.

### Every input is accounted for

Besides `place` and `review` rows, each search term and each place link gets one free `input_status` row: how many places and reviews it returned, 2GIS's own total for the term, and whether the result is complete. A term with no result says so (`partial: false`, 0 places); a term cut short by the request ceiling, the maximum charge, or a refused request is `partial: true` with a `partialReason` — never silently reported as zero. A place found by two of your terms is written and charged once. The last row is the `RUN_SUMMARY`, also stored in the run's key-value store.

### Limits

- Only what the logged-out 2GIS pages show. Phones, websites and emails are the ones the business published on its 2GIS card; when a place's own page cannot be read, those fields are `null` (unknown, not empty) and the place row is `partial` with `partialReason: "contacts_missing"`.
- Nothing about reviewers is collected — no name, no photo, no profile.
- 2GIS publishes no creation date for a place; `sourceUpdatedAt` is when 2GIS last updated the card.
- Search results and their order are 2GIS's own and change over time; 2GIS stops serving results for most terms somewhere in the hundreds.
- Short `go.2gis.com` links are not resolved; paste the full place link instead.

# Actor input Schema

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

One 2GIS search term per line, in the local language where you can - "кофейня" returns far more than "coffee shop" in Moscow. Each term is searched separately in the City below and its results are labelled with it. A place that matches several of your terms is returned once and charged once.

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

The 2GIS city code from the address bar: "moscow", "spb", "novosibirsk", "ekaterinburg", "kazan", "almaty", "astana", "bishkek", "dubai". You can also paste a 2GIS city link such as https://2gis.kz/almaty. Cities outside Russia are served from their own 2GIS site automatically. Defaults to moscow.

## `placeUrls` (type: `array`):

Collect specific places instead of, or in addition to, searching. Paste the 2GIS place link (https://2gis.ru/moscow/firm/70000001113359188, from any 2GIS country site) or just the numeric place ID. Search terms are not required when this is filled in.

## `maxPlaces` (type: `integer`):

Upper bound on the places one search term may produce. 2GIS serves 12 places per result page. When 2GIS runs out of results first, the row count is 2GIS's limit, not this setting, and the input row shows 2GIS's own total.

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

With this on, every place also gets its public reviews as separate rows, newest first: star rating, review text, publish time, likes, photo count and the owner's reply when there is one. Nothing about the reviewer is collected. Reviews come 50 per request. Off by default.

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

Upper bound on the review rows one place may produce. Only used when Also collect public reviews is on.

## `maxUpstreamRequests` (type: `integer`):

Hard ceiling on the HTTP requests this run sends to 2GIS: search pages, place pages, reviews requests and retries together. At the ceiling collection stops - the inputs not reached are written with partialReason "upstream_request_cap" and the run then ends normally. Leave empty and the Actor works a ceiling out from your inputs and limits, so a run is never unbounded.

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

The proxy the requests to 2GIS go through. Keep the default. A run that is refused anyway reports blocked with the refusing response's own signature, never zero results.

## Actor input object example

```json
{
  "searchQueries": [
    "кофейня"
  ],
  "city": "moscow",
  "maxPlaces": 50,
  "includeReviews": false,
  "maxReviewsPerPlace": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (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": [
        "кофейня"
    ],
    "city": "moscow"
};

// Run the Actor and wait for it to finish
const run = await client.actor("lanternlab318/2gis").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": ["кофейня"],
    "city": "moscow",
}

# Run the Actor and wait for it to finish
run = client.actor("lanternlab318/2gis").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": [
    "кофейня"
  ],
  "city": "moscow"
}' |
apify call lanternlab318/2gis --silent --output-dataset

```

## MCP server setup

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

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/wQYdscbTe2TQpBApx/builds/itZGwkjoC7Eee7yMU/openapi.json
