# Yandex Maps Scraper — Places, Reviews, Phones & Emails (`nice_dev/yandex-maps-places-scraper`) Actor

Scrape Yandex Maps places by keyword and city, map area or URL: name, address, phones, website, social links, rating, opening hours, menu, busy hours, INN, plus unlimited reviews, photos, posts and e-mails. Whole cities, not just 600 results. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/nice\_dev/yandex-maps-places-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

### 🏢 What is Yandex Maps Scraper?

**Yandex Maps Scraper** extracts **places from [Yandex Maps](https://yandex.com/maps/)** — Russia, the CIS and Turkey: **name, address, phone numbers, website, social links, rating, opening hours, categories, menu and prices, busy hours, the company's legal name and tax number (INN)** — and, on request, **all their reviews, photos, posts and the e-mails of their website**. Use it for lead lists, market studies, store locators, review monitoring or local SEO.

Type a **keyword** and a **city** (`dentist` in `Moscow`, `кафе` in `Санкт-Петербург`), draw a **map area**, or paste any Yandex Maps link, click **Start**, and download the places in JSON, CSV or Excel. No login, nothing to set up. It is **fast: about 350 places a minute** from search results (100 a minute with full details), and a whole city is covered — not just the ~650 places one Yandex search shows.

### 📋 What data can you extract from Yandex Maps?

One item per place, 73 fields:

| Category | What you get |
| --- | --- |
| 🏷️ **Place** | name, main and all categories, link, Yandex id — `Elite Denta · Dental clinic` |
| 📍 **Location** | full address, street, house, city, postal code, GPS coordinates, nearest metro and stops in meters, entrances |
| 📞 **Contacts** | every phone number, website, Telegram / VK / WhatsApp links, e-mails found on the website |
| ⭐ **Reputation** | rating, number of ratings and reviews, review topics with positive / negative counts, "Good place" award |
| 🕒 **Hours** | opening hours as shown and by day, open now, busy hours of each day |
| 🧾 **Company** | legal name and tax number (INN) of promoted places, verified owner, chain, current promotion |
| 🍽️ **Menu and prices** | menu / price list with prices and photos, average bill, features (Wi-Fi, parking, delivery…) |
| 💬 **Reviews** | author, stars, date, text, Yandex translations, likes, photos, the owner's answer |
| 🖼️ **Media** | cover photo, logo, photo gallery with author and date, videos, street panorama, business posts |
| 🔗 **More** | booking partner, similar places, Yandex collections, where the place was found |

Every field, with an example, is listed in the **Output** section below.

Search results already carry most fields. **Place details** (on by default) adds the full menu; **reviews**, **photos**, **posts** and **e-mails** are options, each priced on its own.

### ✅ Why use Yandex Maps Scraper?

- 🗺️ **A whole city, not 650 places**: when a search is full, its map area is cut into tiles automatically, and each tile is searched again.
- 💬 **Places and reviews in one run**: about twice the 600 reviews one sort order shows (all 637 of a restaurant; 1,283 of the 2,727 of a very popular one), one row per review in the **Reviews** view, with the place on every row.
- 🚀 **Fast** (measured on Apify, default 512 MB): 1,000 pharmacies of Moscow in 3 minutes; 100 dentists with full details in a minute; 2,000 reviews of 10 restaurants in a little over a minute.
- 🎯 **Type a keyword and a city**, draw a map area (center + radius, rectangle, grid), or paste a Yandex Maps search, place or short link.
- 🧩 **Yandex filters built in**: minimum rating, open now, open 24 h, "Good place", category, chain, and any other filter Yandex offers for the search — a filter Yandex ignores stops that search instead of returning unfiltered places.
- 🔔 **Monitoring built in**: only the places, or only the reviews, never delivered before.
- 🔌 API, scheduling, integrations (Make, Zapier, n8n, Google Sheets…) and JSON / CSV / Excel export via the Apify platform.

### 🚀 How to scrape Yandex Maps

1. Create a free Apify account.
2. Open **Yandex Maps Scraper**, type a **Search keyword** (e.g. `стоматология` or `dentist`) and a **Location** (e.g. `Москва`, `Istanbul`).
3. Or paste Yandex Maps links into **Start URLs**: a search, a place page or a short link — or place ids into **Place IDs**. The keyword and location are then ignored.
4. Set **Max places** (100 by default, 0 = no limit), tick **Include reviews** if you want them, then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API; open the **Reviews** view for one row per review.

### 💰 How much does it cost to scrape Yandex Maps?

This Actor uses **pay per event** pricing, cheap by default and a price per option you tick. Options cost a little less on higher Apify plans (without a subscription → Bronze → Silver → Gold and above):

| What | Price |
| --- | --- |
| Place (search result fields) | **$0.02 per 1,000 places** |
| Place details (full menu), on by default | $0.70 → $0.69 → $0.68 → $0.67 per 1,000 places |
| Review | $0.20 → $0.19 → $0.18 → $0.17 per 1,000 reviews |
| Photo gallery | $0.30 → $0.29 → $0.28 → $0.27 per 1,000 places with photos |
| Posts | $0.20 → $0.19 → $0.18 → $0.17 per 1,000 places with posts |
| E-mails from the website | $0.20 → $0.19 → $0.18 → $0.17 per 1,000 places whose website was read |
| Filter check: a place dropped by a filter of this Actor (`minRating`, `minReviewCount`, `requirePhone`, `requireWebsite`, `excludeKeywords`, `excludeBusinessIds`) | $0.01 per 1,000 places dropped  |
| Run start | $0.01 per run |

Examples, without a subscription: 10,000 dentists of Moscow with details ≈ $7.20; 10,000 without details ≈ $0.21; 200 restaurants with 500 reviews each ≈ $20. Platform usage (compute, proxy) is included in the price. A place one of the Actor's own filters drops is charged as a *Filter check*, and a place it keeps pays its own price only; the filters sent to Yandex with the search (open now, categories, "Good place"…) cost nothing extra. With a maximum cost per run set, the run stops at the last place it pays for in full, with its reviews and options: never a place charged and not saved.

### ⚙️ Input

```json
{
    "query": "стоматология",
    "location": "Москва",
    "maxItems": 500,
    "minRating": "4.5",
    "requirePhone": true
}
```

Several searches, the reviews of the last 30 days, only what was not delivered before:

```json
{
    "searchQueries": ["кафе", "пекарня"],
    "locations": ["Казань", "Екатеринбург"],
    "maxItemsPerQuery": 200,
    "includeReviews": true,
    "maxReviewsPerPlace": 0,
    "postedAfter": "30 days",
    "onlyNewReviews": true,
    "stateKey": "cafes-reviews"
}
```

Or a map area:

```json
{
    "query": "pharmacy",
    "coordinates": "37.6173,55.7558",
    "radiusKm": 3
}
```

Or your own links and ids (the search fields are then ignored):

```json
{
    "startUrls": [{ "url": "https://yandex.ru/maps/org/ryba_moya/19464848293/" }],
    "businessIds": ["1124715036"]
}
```

| Field | Notes |
| --- | --- |
| `query`, `searchQueries` | What to look for, in any language; `searchQueries` adds more keywords (one search each). |
| `location`, `locations` | City, district, street or country; every keyword is searched in every location (max 500 searches per run). A name several places share gives the one named exactly so, the nearest to Moscow first — add the region to pick another (`Пушкин, Санкт-Петербург`, `Ivanovka, Omsk Oblast`); the log line `[geo]` says which one was searched. |
| `coordinates`, `viewportSpan`, `radiusKm` | A map area instead of a named location: its center `longitude,latitude` (e.g. `37.6173,55.7558`), with a span or a radius in km. |
| `boundingBox` | A map rectangle `west,south,east,north` (e.g. `37.35,55.57,37.85,55.92`). |
| `splitArea`, `tileGrid` | Cut a full search into tiles automatically (default on); `tileGrid` cuts every area into N × N tiles from the start. |
| `startUrls`, `businessIds` | Yandex Maps search, place or short-link URLs (yandex.ru, .com, .com.tr, .kz, .by, .uz), and place ids; given, they replace the search fields. |
| `maxItems`, `maxItemsPerQuery` | Places for the whole run (`0` = unlimited) and for each search. |
| `language` | Language of names, addresses and labels: `en`, `ru`, `tr`, `uk` or `kk`. |
| `includeDetails` | One request per place for the full menu / price list (default on). |
| `minRating`, `openNow`, `open24h`, `goodPlaceOnly`, `hasPhotos`, `categoryIds`, `chainIds` | Yandex's own filters: minimum rating (`4.5`), open now, open 24 h, "Good place" award, with photos, category and chain ids. |
| `customFilters` | Any other filter Yandex offers for the search, as `filterId:value` (e.g. `car_park:1`); `debugLog` lists them for each search. |
| `requirePhone`, `requireWebsite`, `minReviewCount`, `excludeKeywords`, `excludeBusinessIds` | Drop places without a phone or website, with few reviews, with a word in their name or category, or already known. |
| `includeReviews`, `reviewSort` | Reviews of each place, in the order you choose: `newest`, `relevance`, `highest` or `lowest`. |
| `maxReviewsPerPlace` | Reviews per place (`0` = as many as possible). |
| `postedAfter`, `postedBefore`, `minReviewRating`, `maxReviewRating`, `onlyWithText`, `onlyWithBusinessReply`, `reviewKeywords` | Review filters: dates (`2026-09-01`, or `7 days`, `2 weeks`, `1 month`), stars, text, owner's answer, words. |
| `includePhotos`, `maxPhotos`, `includePosts`, `maxPosts`, `enrichEmails` | Photo gallery, business posts, e-mails found on the place's website. |
| `onlyNew`, `onlyNewReviews`, `stateKey`, `resetState` | Monitoring: only the places — or only the reviews — never delivered under this memory key; `resetState` forgets it. |
| Advanced | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

A real item of a run (`кафе` in Saint Petersburg), shortened: some columns left out, lists keep their first entry, `features` its first 4 keys.

```json
{
    "id": "1922079259",
    "url": "https://yandex.com/maps/org/fire_bird/1922079259/",
    "title": "Fire-Bird",
    "category": "Cafe",
    "categories": ["Cafe"],
    "categoryIds": ["184106390"],
    "address": "Saint Petersburg, Ligovskiy Avenue, 89/20",
    "city": "Saint Petersburg",
    "postalCode": "191040",
    "latitude": 59.923762,
    "longitude": 30.355981,
    "phone": "+7 (812) 665-85-55",
    "phones": [{"number": "+7 (812) 665-85-55", "value": "+78126658555", "type": "phone", "info": "оператор call-центра"}],
    "website": "https://pie-delivery.ru/",
    "websites": ["https://pie-delivery.ru/"],
    "socialLinks": [{"type": "viber", "url": "https://viber.click/89811308887", "label": "viber.click/89811308887"}],
    "emails": [],
    "rating": 5,
    "ratingCount": 5713,
    "reviewCount": 4403,
    "openingHours": "daily, 10:00 AM–11:00 PM",
    "openingHoursByDay": [{"day": "monday", "hours": [{"from": "10:00", "to": "23:00"}]}],
    "features": {"wi_fi": true, "price_category": ["average"], "food_delivery": true, "average_bill2": "500–1000 ₽"},
    "featureList": [{"id": "wi_fi", "name": "Wi-Fi", "value": true}],
    "priceRange": "500–1000 ₽",
    "isAdvert": true,
    "legalName": "ООО \"БАРКАД\"",
    "taxId": "7811168487",
    "goodPlaceYear": "2026",
    "reviewAspects": [{"id": "3502043738", "name": "Meal", "count": 3877, "positive": 3642, "neutral": 41, "negative": 194, "isTrusted": true}],
    "nearbyMetro": [{"name": "Ligovskiy Prospekt", "distanceMeters": 381, "distance": "380 m", "latitude": 59.920827842, "longitude": 30.354912043, "color": "#f28b24"}],
    "nearbyStops": [{"name": "Svechnoy Lane", "distanceMeters": 320, "distance": "320 m", "latitude": 59.924085466, "longitude": 30.35101244}],
    "entrances": [{"latitude": 59.92375796, "longitude": 30.35599139, "azimuth": 143.88260278046454}],
    "photoCount": 500,
    "photos": [],
    "videos": [{"id": "vplvkt37dai3vzdyvqei", "url": "https://runtime.strm.yandex.ru/player/video/vplvkt37dai3vzdyvqei", "thumbnailUrl": "https://avatars.mds.yandex.net/get-vh/15630674/2a0000019e4a0d918b9af4d1544403edfd9d/orig", "duration": null}],
    "bookingLinks": [],
    "sources": [{"id": "yandex", "name": "Yandex", "url": "https://www.yandex.com"}],
    "posts": [],
    "menu": [{"category": null, "title": "Телятина в соусе", "description": null, "price": 700, "priceText": "700", "currency": "₽", "volume": null, "photoUrl": "https://avatars.mds.yandex.net/get-sprav-products/1540730/2a0000017565f74efec17fd1aa1bb4a88b85/orig", "sourceUrl": null}],
    "similarPlaces": [],
    "collections": [],
    "reviews": [],
    "searchQuery": "кафе",
    "searchLocation": "Санкт-Петербург",
    "language": "en",
    "scrapedAt": "2026-09-24T20:21:41.969Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. The **Reviews** view (or `unwind=reviews` in the API) gives one row per review, with the place's `id` and `title` on each row.

#### All 73 fields

| Fields | What you get |
| --- | --- |
| `id`, `url`, `title`, `shortTitle` | **Place**: Yandex id, page, name — `1922079259`, `Fire-Bird` |
| `category`, `categories`, `categoryIds` | main category, all categories, their Yandex ids (usable in `categoryIds`) |
| `address`, `street`, `house`, `city`, `postalCode`, `country`, `additionalAddress` | **Location**: full address and its parts, floor / office details |
| `latitude`, `longitude`, `regionId`, `timezoneOffset` | GPS coordinates, Yandex region (`213` = Moscow), UTC offset in seconds |
| `nearbyMetro`, `nearbyStops`, `entrances` | metro stations and stops with distance in meters, entrance coordinates |
| `phone`, `phones`, `website`, `websites`, `socialLinks`, `emails` | **Contacts**: first phone and all of them, first website and all of them (tracking removed), social links, e-mails of the website |
| `rating`, `ratingCount`, `reviewCount`, `reviewAspects` | **Reputation**: rating 1-5, ratings, reviews, review topics |
| `goodPlaceYear`, `awards` | Yandex "Good place" award and other awards |
| `status`, `isOpenNow`, `workingStatus`, `openingHours`, `openingHoursByDay`, `visitsHistogram` | **Hours**: open / closed, now, as shown, by day, busy hours |
| `legalName`, `taxId`, `isAdvert`, `isVerifiedOwner`, `promo`, `chainId`, `chainName` | **Company**: legal entity and INN (promoted places), paid listing, verified owner, promotion, chain |
| `features`, `featureList`, `priceRange`, `menu` | **Menu and prices**: features (id → value, and with labels), average bill, menu / price list |
| `reviews`, `reviewsScraped` | **Reviews** (with `includeReviews`) and how many were added |
| `imageUrl`, `logo`, `photoCount`, `photos`, `videos`, `panoramaUrl` | **Media**: cover photo, logo, photo count and gallery, videos, street panorama |
| `postCount`, `latestPost`, `posts` | business posts: count, latest one, all of them (with `includePosts`) |
| `bookingLinks`, `bookingPartner`, `sources`, `summary`, `similarPlaces`, `collections` | **More**: booking links and partner, data sources, Yandex's description, similar places, collections (Yandex gives them with `language` ru, uk or kk only, titles in Russian) |
| `searchQuery`, `searchLocation`, `searchUrl`, `position` | the search that found the place, its Yandex Maps page, rank in its map tile |
| `language`, `scrapedAt` | language of the texts, ISO timestamp of the extraction |

### 💡 Tips

#### How to get more results

Keep **Split big areas automatically** on and type a broad keyword with a city: a search that fills its 40 pages is cut into 4 tiles, and so on, until every tile shows less than a full search. For a very dense area, set `tileGrid` to `4` or more to start with smaller tiles. Several keywords (`стоматология`, `стоматологическая клиника`) find places a single one misses.

#### How to reduce costs

The price is per place and per option: leave off what you do not need (reviews, photos, posts, e-mails), turn **Place details** off if search result fields are enough, cap reviews with `maxReviewsPerPlace`, and prefer the filters Yandex applies itself (open now, categories, "Good place", `customFilters`): a place they drop is never downloaded, while a place the Actor's own filters drop is charged as a *Filter check*. For recurring runs, `onlyNew` and `onlyNewReviews` never charge twice for the same place or review.

#### Several searches in one run

Fill `searchQueries` and / or `locations`: the Actor runs one search per keyword × location (3 keywords × 4 cities = 12 searches, up to 500 per run). A place found by several searches or tiles is saved — and charged — once. Set `maxItemsPerQuery` to give every search its own cap: without it the first searches can use up the whole `maxItems` budget.

#### Monitoring: only the new places or reviews

Tick **Only new places** (`onlyNew`) and schedule the Actor: each run returns, and charges, only the places no previous run delivered under the same `stateKey`. **Only new reviews** (`onlyNewReviews`) returns every place with only its reviews not delivered before — with the newest first, the reviews written since: reading stops at the first known review, and older reviews a previous run left out (its `maxReviewsPerPlace`) are not returned either. The memory lives in named key-value stores of your account (`yandex-maps-places-scraper-seen` and `yandex-maps-places-scraper-seen-reviews`, up to 150,000 ids per key), updated only with what really reached the dataset. Give each schedule its own `stateKey`, and tick `resetState` once to start over.

#### Filter reviews by date

`postedAfter` and `postedBefore` apply to the reviews, never to the places: `2026-09-01` (the whole day is included, Moscow time) or a period before now (`7 days`, `2 weeks`, `1 month`; via the API also `24 hours` or a full ISO date-time). A review without a date is dropped as soon as a bound is set.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool; add `unwind=reviews` for one row per review.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Yandex Maps place, its reviews inside the item when asked. Actor id: `nice_dev/yandex-maps-places-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/yandex-maps-places-scraper`.

Smallest input, for a cheap first call:

```json
{
    "query": "dentist",
    "location": "Moscow",
    "maxItems": 10
}
```

Key output fields: `url`, `title`, `address`, `phone`, `website`, `rating`, `reviewCount` and `categories`.

Cost: $0.02 per 1,000 places, plus $0.67 to $0.70 per 1,000 places for the place details (on by default: $0.69 to $0.72 per 1,000 for the input above), plus $0.01 per run start. Reviews, photos, posts, e-mails and filter checks cost extra, see the pricing section above. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to scrape Yandex Maps?

The Actor only reads what Yandex Maps shows publicly to any anonymous visitor. It logs in to nothing and solves no captcha. Business contact details are published by the businesses themselves; reviews carry the names and photos of their authors, which are personal data protected by GDPR: do not store them without a legitimate reason. You are responsible for using the data in compliance with Yandex's Terms of Use and applicable law. This Actor is not affiliated with Yandex.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Why do some places have no legal name, tax number or menu?

Yandex shows the legal entity and INN only for promoted places (18 of the 24 dentists of a Moscow search), and a menu only for the places that published one. Those fields are `null` or empty otherwise — never guessed.

#### Is the data safe to open in Excel or to show on a web page?

Names, reviews and posts are the businesses' and authors' own words, copied as they are. A text can begin with `-`, `+`, `=` or `@` (a phone number, a review such as `+1 for the staff`): Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field holds an http(s) URL or `null`. On a web page, escape every field like any text written by a stranger.

#### Known limitations

- Yandex's AI summary of the reviews is not in the output: it never appeared in our tests run from outside Russia.
- Reviews beyond 600 come from Yandex's 4 sort orders merged (600 each, many in common): 1,283 of the 2,727 reviews of a very popular place in our test — not all of them.
- One Yandex search shows at most ~650 places; the automatic split covers more, at the price of more requests (still charged per place only).
- `onlyNew` remembers place ids, not their content: a place whose phone changed is not returned again.
- Two runs sharing the same `stateKey` at the same time may both return the same new place.

**A run the platform stops without warning** (out of memory, run timeout)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the places already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved once a minute: resurrect the stopped run and the places it had saved meanwhile join the memory; leave it stopped for good, and the next run may return up to a minute of them once more.

#### Something doesn't work?

The last line of the log counts the places saved, filtered out and no longer on Yandex Maps, the reviews, the map tiles searched and the requests that failed after every retry. Those requests are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A page of reviews, photos or posts lost for good leaves its place without it, counted in the log — the place is still saved. A run that saved nothing and had failed requests fails, and its last message gives the cause (a location Yandex does not know, a filter it ignored for the search).

If Yandex changes its data, you are told instead of paying for blank rows: if the first 20 places read all lack their name, category, address or coordinates, the run saves nothing more, stops and fails, and its last message names the missing field.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which requests failed and why.

# Actor input Schema

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

Yandex Maps URLs: search results (`https://yandex.com/maps/213/moscow/search/dentist/`, the map area and filters of the URL are kept), place pages (`https://yandex.ru/maps/org/<name>/<id>/`, also `/reviews/`) or short links (`https://yandex.ru/maps/-/CDabc123`). yandex.ru, .com, .com.tr, .kz, .by, .uz are accepted. When this list or **Place IDs** is not empty, the search fields below (keywords, locations, map area) are ignored; filters, caps, reviews and monitoring still apply. Max 1 000 URLs.

## `businessIds` (type: `array`):

Yandex Maps place IDs (the number at the end of a place URL, e.g. `1124715036`). One request per place. Added to **Start URLs**: the search fields below are then ignored.

## `query` (type: `string`):

What to look for, as typed on Yandex Maps, in any language (e.g. `dentist`, `стоматология`, `кафе`, `kuaför`).

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

Several keywords in one run: one search per keyword (times each location below). Added to **Search keyword**; places found by several searches are saved once.

## `location` (type: `string`):

City, district, street or country, as typed on Yandex Maps (e.g. `Moscow`, `Санкт-Петербург`, `Istanbul`, `Almaty`, `Kazan, Bauman street`). The whole area of the place is searched (split in tiles when needed). Empty = the map area below, or Moscow.

## `locations` (type: `array`):

Several locations in one run: every keyword is searched in every location (3 keywords × 4 locations = 12 searches, max 500). Added to **Location**.

## `coordinates` (type: `string`):

Search around this point instead of a named location: `longitude,latitude` in decimal degrees, longitude FIRST as in Yandex URLs (e.g. `37.6173,55.7558` = Moscow center). Used with **Map span** or **Radius**; ignored when a location is given.

## `viewportSpan` (type: `string`):

Size of the searched area around **Map center**, in degrees: `width,height` (e.g. `0.2,0.1` ≈ 12 × 11 km in Moscow). Default `0.2,0.1`.

## `radiusKm` (type: `integer`):

Search a square of this half-size around **Map center** instead of **Map span** (e.g. `5` = 10 × 10 km). 0 = use Map span.

## `boundingBox` (type: `string`):

Search this rectangle: `west,south,east,north` in decimal degrees (e.g. `37.35,55.57,37.85,55.92` = Moscow inside the ring road). Wins over Map center; ignored when a location is given.

## `splitArea` (type: `boolean`):

One Yandex search shows at most ~650 distinct places. When a search fills up, its area is cut into 4 tiles and each tile is searched again (and so on), so a whole city can be covered. Off = one search per keyword × location (faster, fewer places).

## `tileGrid` (type: `integer`):

Cut every searched area into N × N tiles from the start (e.g. `4` = 16 searches), before any automatic split. 1 = one search per area.

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

Maximum number of places to save for the whole run (after deduplication and filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Cap for EACH search (keyword × location, or search URL), so that the first search cannot use up the whole **Max places** budget. 0 = no per-search cap.

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

Language of names, addresses, categories, opening hours and feature labels (Yandex translates or transliterates them). Review texts stay as written; their Yandex translations are in `textTranslations`. Yandex collections (the collections field) come with Russian, Ukrainian or Kazakh only.

## `includeDetails` (type: `boolean`):

Open each place (1 extra request per place) for its full menu / price list. Charged as a separate event, see Pricing. Off = search-result fields only (they already carry the busy hours, rating, phones, features and a short menu).

## `minRating` (type: `string`):

Only places rated at least this (Yandex filter, then checked on each place by the Actor: a place it drops is charged as a *Filter check*).

## `openNow` (type: `boolean`):

Only places open at the time of the run (Yandex filter).

## `open24h` (type: `boolean`):

Only places open around the clock (Yandex filter).

## `goodPlaceOnly` (type: `boolean`):

Only places with the Yandex "Good place" award (Yandex filter).

## `hasPhotos` (type: `boolean`):

Only places that have photos (Yandex filter).

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

Only places of these Yandex categories (rubric IDs, e.g. `184106132` = dental clinic; the ID of each place's categories is in the output). Yandex filter.

## `chainIds` (type: `array`):

Only the branches of these chains (chain ID, in the `chainId` output field). Yandex filter.

## `customFilters` (type: `array`):

Any other filter shown by Yandex for the search, as `filterId:value` (e.g. `car_park:1`, `wheelchair_accessability:1`, `payment_by_credit_card:1`, `type_cuisine:georgian_cuisine`). Tick **Debug log** to see the filters Yandex offers for each search in the run log; they are also listed when a filter is refused. A filter Yandex does not know for the search is reported and the search stops, instead of returning unfiltered places.

## `requirePhone` (type: `boolean`):

Drop the places without a phone number.

## `requireWebsite` (type: `boolean`):

Drop the places without a website (the Yandex "has website" filter is sent too).

## `minReviewCount` (type: `integer`):

Drop the places with fewer reviews than this. 0 = no minimum.

## `excludeKeywords` (type: `array`):

Drop the places whose name or category contains one of these words (case and accents ignored).

## `excludeBusinessIds` (type: `array`):

Never save these places (e.g. your own branches, or places you already have).

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

Add the reviews of each place (50 per request), with author, rating, date, text, Yandex translations, likes, photos and the owner's answer.

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

Maximum number of reviews per place. Yandex shows 600 reviews per sort order; above 600 (or 0 = as many as possible) the 4 sort orders are merged, which roughly doubles what one order gives.

## `reviewSort` (type: `string`):

Order in which reviews are read (and cut by Max reviews per place).

## `postedAfter` (type: `string`):

Only reviews written (or last edited) on or after this date: `2026-09-01`, or a period before now such as `7 days`, `2 weeks`, `1 month` (API: `24 hours` and full ISO date-times work too). Places are never dropped by this filter.

## `postedBefore` (type: `string`):

Only reviews written on or before this date (the whole day is included), or older than a period such as `30 days`.

## `minReviewRating` (type: `integer`):

Only reviews rated at least this many stars (1-5). 0 = all.

## `maxReviewRating` (type: `integer`):

Only reviews rated at most this many stars (e.g. `2` = complaints only). 0 = all.

## `onlyWithText` (type: `boolean`):

Drop the ratings without any text.

## `onlyWithBusinessReply` (type: `boolean`):

Keep only the reviews the business answered.

## `reviewKeywords` (type: `array`):

Keep only the reviews whose text contains one of these words (case and accents ignored).

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

Add the photo gallery of each place (full-size URL, size, tags, author and date), up to **Max photos per place**. The cover photo and the photo count are always in the output.

## `maxPhotos` (type: `integer`):

Maximum number of photos per place. 0 = all.

## `includePosts` (type: `boolean`):

Add the news / posts published by the business on its Yandex page (text, date, photos), up to **Max posts per place**. The post count and the latest post preview are always in the output.

## `maxPosts` (type: `integer`):

Maximum number of posts per place. 0 = all.

## `enrichEmails` (type: `boolean`):

Yandex Maps shows no e-mail. On: open the place's own website (home page + contact / legal pages linked from it, 3 pages at most) and add the e-mail addresses found there to `emails`. Only for places with a website.

## `onlyNew` (type: `boolean`):

Skip the places that a previous run (same **Memory key**) already delivered: they are not saved and not charged. First run = everything is new.

## `onlyNewReviews` (type: `boolean`):

With **Include reviews**: return every place, but only the reviews a previous run (same **Memory key**) did not deliver (`reviews` then holds the new ones only). With Newest first: the reviews written since — reading stops at the first already-known review, and older reviews a previous run left out (its **Max reviews per place**) are not returned either.

## `stateKey` (type: `string`):

Name of the memory used by **Only new places** and **Only new reviews**. Give each schedule / task its own key (e.g. `moscow-dentists`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) everything again. Untick it afterwards.

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

Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of requests processed in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Most requests to Yandex Maps in any 60 seconds, all of them counted: search pages, places, pages of reviews, photos and posts, session tokens. A budget, not an even pace: up to this many can leave at once when the minute starts (spread them with the minimum delay below). E-mail lookups on the places' own websites are not counted.

## `minRequestIntervalMs` (type: `integer`):

Wait at least this long between two requests. 0 = no delay.

## `maxRequestRetries` (type: `integer`):

Retries per request before it is marked as failed. Behind a proxy, a request the site turns away is also retried on a new proxy session up to 10 times without using up these retries.

## `debugLog` (type: `boolean`):

Verbose log.

## Actor input object example

```json
{
  "startUrls": [],
  "businessIds": [],
  "query": "стоматология",
  "searchQueries": [],
  "location": "Москва",
  "locations": [],
  "radiusKm": 0,
  "splitArea": true,
  "tileGrid": 1,
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "language": "en",
  "includeDetails": true,
  "minRating": "",
  "openNow": false,
  "open24h": false,
  "goodPlaceOnly": false,
  "hasPhotos": false,
  "categoryIds": [],
  "chainIds": [],
  "customFilters": [],
  "requirePhone": false,
  "requireWebsite": false,
  "minReviewCount": 0,
  "excludeKeywords": [],
  "excludeBusinessIds": [],
  "includeReviews": false,
  "maxReviewsPerPlace": 100,
  "reviewSort": "newest",
  "minReviewRating": 0,
  "maxReviewRating": 0,
  "onlyWithText": false,
  "onlyWithBusinessReply": false,
  "reviewKeywords": [],
  "includePhotos": false,
  "maxPhotos": 50,
  "includePosts": false,
  "maxPosts": 20,
  "enrichEmails": false,
  "onlyNew": false,
  "onlyNewReviews": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 600,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "debugLog": 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 = {
    "query": "стоматология",
    "location": "Москва",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/yandex-maps-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 = {
    "query": "стоматология",
    "location": "Москва",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/yandex-maps-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 '{
  "query": "стоматология",
  "location": "Москва",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/yandex-maps-places-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/yandex-maps-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/bMJ9GjxaR3raMT6lo/builds/8BHyDUO6xjdqCQkdx/openapi.json
