# Yandex Maps Quick Scraper (`kitcunemia/yandex-maps-places-scraper`) Actor

\[💰 $1.00 / 1K] Extract Yandex Maps businesses with phones, emails, websites, ratings, reviews, photos, opening hours, and 60+ more fields. Search by query + city, by 100+ categories, or by direct Yandex business ID. Optional contact-scraping from each place's website. Pay only for what you collect.

- **URL**: https://apify.com/kitcunemia/yandex-maps-places-scraper.md
- **Developed by:** [Kitcune Mia](https://apify.com/kitcunemia) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## 🗺 Yandex Maps Places Scraper

> **The fast, captcha-resilient way to extract every business on Yandex Maps.**
> Names, phones, emails, websites, ratings, reviews, photos, opening hours,
> menus — and 60+ more fields — straight into your Apify dataset.

[![pricing](https://img.shields.io/badge/from-%243.00%20%2F%201%2C000%20results-blue)]()
[![data](https://img.shields.io/badge/fields%20per%20place-60%2B-success)]()
[![regions](https://img.shields.io/badge/regions-RU%20%C2%B7%20BY%20%C2%B7%20KZ%20%C2%B7%20TR%20%C2%B7%20AZ%20%C2%B7%20EN-orange)]()

---

### Why this scraper?

| | This actor | Typical Yandex scraper |
|---|---|---|
| **Cost** | $3 / 1,000 places | $4–8 / 1,000 |
| **Engine** | Direct HTTP (`curl_cffi` + TLS impersonation) | Headless Chromium |
| **Speed** | ~150 places/min on a single run | ~30–60 places/min |
| **Captcha resilience** | Residential proxy + auto session rotation (5 retries) | Often blocks mid-run |
| **Coverage** | 60+ fields including emails / website phones / reviews / menus | 15–25 fields |
| **Regions** | 6: RU, BY, KZ, TR, AZ, EN | usually RU only |
| **Billing** | Pay-per-event — you control what you pay for | Flat rate, you pay for unused |

#### What makes it fast and reliable

- **No browser** — Yandex server-renders the entire app state into a single
  JSON payload on every search/place URL. We parse that directly.
  No Chromium boot, no JS execution, no rendering loop.
- **Chrome TLS fingerprint** — `curl_cffi` sends a TLS ClientHello byte-identical
  to real Chrome, defeating Yandex's JA3-based bot detection.
- **Auto proxy pairing** — your selected `Language` automatically picks the
  matching residential country (`RU → RU` IPs, `BY → BY`, `TR → TR`…).
  No more cross-region captcha loops.
- **Captcha-aware retry** — on 403 / `showcaptcha` / suspicious response we
  rotate the proxy session, recreate the curl context (clean cookie jar +
  new exit IP), and retry up to 5 times before giving up.
- **Parallel enrichment** — reviews and website-contact scrapes run
  concurrently per place, halving wall-time when you opt into both.
- **15s ceiling per request** — broken proxies fail fast, healthy ones
  return in well under 2s.

---

### What you can do with it

| Use case | Workflow |
|---|---|
| 🎯 **Lead generation** | `query="dentist", locations=[Moscow, SPB], emails=ON` → CSV with names, addresses, websites, **emails harvested from each place's website**, phones |
| 📊 **Local market research** | `categories=[Pizzeria], locations=[10 cities]` → per-city ratings, density, price tiers — perfect for franchise scouting |
| ⭐ **Reviews monitoring** | `organizationIds=[your shops], maxReviews=50, sort=newest` → JSON of customer feedback, sortable by date or rating |
| 📚 **Directory building** | `query="carwash", maxItems=2000` → bulk-extract every car wash with full metadata |
| 🕵 **Competitor intelligence** | one company's `placeId` → features, opening hours, photos, social links, menu sections, awards |

---

### Quick start

1. **Search queries** — type what you'd type in the Yandex Maps search bar
   (e.g. `coffee`, `auto repair`, `dentist`). One per line.
2. **Location** — pick one or more cities from the dropdown (~90 major
   Russian cities listed in English: *Moscow, Saint Petersburg,
   Novosibirsk*…) or type your own city name.
3. **Number of places to extract** — `20` is a good start.
4. **Language** — sets the Yandex regional domain. Defaults to Russian.
5. *(optional)* Filter by **rating**, **price tier**, **category**,
   or "good places only".
6. *(optional)* Enable **reviews**, extra **photos**, or **email/phone
   from each place's website**.
7. **Save & Start.**

> 💡 No `Search queries`? Pick a **category** — the actor will use
> category names as queries automatically (English + Russian for max
> coverage).

---

### Pricing — Pay only for what you collect

| Event | Cost | When it fires |
|---|---|---|
| **Result** | **$3.00 / 1,000** | Each place pushed to the dataset |
| **Review scraped** | **$0.50 / 1,000** | Each individual review extracted |
| **Image scraped** | **$0.50 / 1,000** | Each extra photo (the main image is free) |
| Actor start | $0.00005 | Once per run |
| Platform usage (compute, proxy, dataset) | **free** — included | — |

> 🛡 **You set the ceiling.** In Run Options set `maxTotalChargeUsd` (e.g. `5`)
> and the actor will stop before exceeding your budget. Reviews, extra
> photos, and contact-scraping are **off by default** — turn them on
> only if you need them.

#### Real-world budget examples

| Goal | Setup | Cost |
|---|---|---|
| 500 leads with phones + emails | 500 places + contact scraping | **$1.50** |
| 500 places + 10 reviews each | 500 + 5,000 reviews | **$4.00** |
| 200 restaurants with photos & reviews | 200 + 5 photos × 5 reviews | **$1.10** |
| 2,000 carwashes for a directory | 2,000 places, no extras | **$6.00** |

---

### Input

#### Top-level fields

| Field | Description |
|---|---|
| **🔎 Search queries** | List of search terms. Each query runs against every selected city. |
| **📍 Location** | Cities to limit the search. Pre-loaded with ~90 major Russian cities in English; type any custom city to add it. |
| **💯 Number of places to extract** | Max items per (query × city) pair. |
| **🟢 Language** | Yandex regional domain: `RU → yandex.ru`, `BY → yandex.by`, `EN → yandex.com`, `KK → yandex.kz`, `TR → yandex.com.tr`, `AZ → yandex.az`. Proxy country auto-paired. |

#### 🔧 Filters & categories *(optional)*

| Field | Effect |
|---|---|
| **Rating** | Minimum average rating threshold: *Any · 3.0+ · 3.5+ · 4.0+ · 4.5+ · 4.7+ · 4.9+*. |
| **Price categories** | Multi-select: *Low · Average · Above average · High*. |
| **Good place** | Only places with rating ≥ 4.5 **and** ≥ 50 reviews. |
| **Categories** | 100+ presets (Carwash, Pizzeria, Dental clinic, Driving school…). Bilingual matching — works with Yandex's Russian category names automatically. |
| **Append to global dataset** | Also append unique places to a persistent global dataset (cross-run dedupe). |

#### 🖼 Photos *(optional, paid)*

| Field | Effect |
|---|---|
| **Number of additional images per place** | Extra photo URLs collected. `0` disables. The main image is always free. |
| **Include image authors** | Add author metadata for each extra photo. |

#### ⭐ Reviews *(optional, paid)*

| Field | Effect |
|---|---|
| **Number of reviews per place** | Reviews fetched from each place's `/reviews/` page. `0` disables. |
| **Reviews sorting** | *By default · Newest first · Highest rating first · Lowest rating first.* |
| **Include reviewers' data** | Author profile fields (name, avatar, public ID) on each review. |
| **📧 Email & phones from website** | Visits each place's website, harvests `mailto:` / `tel:` links plus inline emails from `/contacts` and `/contact` pages → fills `emails` and `websitePhones` fields. |

#### 🍽 Collect menu *(optional)*

| Field | Effect |
|---|---|
| **Collect menu** | Pull menu sections and items where Yandex exposes them (mostly restaurants). |

#### 🏢 Scrape with place IDs *(optional)*

| Field | Effect |
|---|---|
| **Organization IDs** | Skip search entirely — open these Yandex business OIDs directly. Reviews / photos / contacts still apply per place. |

---

### Output

Each scraped place becomes one dataset record with **60+ fields**. The
high-value ones:

| Field | Example |
|---|---|
| `title` / `shortTitle` | `"PizzaFabrika"` |
| `categoryName` / `categories` | `"Pizzeria"` · `["Pizzeria", "Cafe"]` |
| `address` / `fullAddress` | `"Moscow, Mikhaylova Street, 30Ak2"` |
| `phone` / `phoneUnformatted` / `phones` | `"+7 800 550-06-00"` |
| `website` / `urls` | `"https://pizzafabrika.ru"` |
| `emails` *(opt-in)* | `["info@pizzafabrika.ru"]` |
| `websitePhones` *(opt-in)* | `["+78005500600"]` |
| `totalScore` / `ratingCount` / `reviewsCount` | `4.9` · `350` · `116` |
| `reviews` *(opt-in)* | `[{author, rating, text, updatedTime, businessReply, ...}]` |
| `location` | `{ "lat": 55.84, "lng": 37.62 }` |
| `mainPhotoUrl` | `"https://avatars.mds.yandex.net/.../XXL"` |
| `photos` / `photoDetails` *(opt-in)* | extra photo URLs + alt/id metadata |
| `workingHours` / `openingHoursText` / `isOpenNow` | day-by-day schedule + status |
| `featureDetails` | structured features (Wi-Fi, parking, kids-friendly…) |
| `metroDetails` / `stopDetails` | nearby metro / transit stops with distances |
| `socialLinks` | Instagram / VK / Telegram links |
| `menu` / `menuCategories` / `menuItemCount` | menu data (when Yandex exposes it) |
| `placeId` / `yandexUri` / `url` | Yandex business ID, internal URI, canonical URL |
| `chain` / `awards` / `parentRubrics` | brand info, awards, broader rubrics |
| `panorama` / `panoramaPreviewUrl` | nearby panorama |
| `bounds` / `entrances` | geometry corners and known entrances |
| `scrapedAt` | ISO timestamp of extraction |

The **Output** tab in Apify Console gives you pre-built table views:
*Overview · Contacts · Ratings · Features · Media · Menu · Reviews · All fields*.

---

### Tips & gotchas

- **Russian cities work in either spelling.** Type `Moscow` or `Москва` —
  Yandex resolves both.
- **Belarusian language** — pick `BY` when scraping Minsk / Gomel / Brest /
  Grodno to route through `yandex.by` + Belarusian residential IPs.
  Drastically lowers captcha rate vs running on `yandex.ru`.
- **Rating 4.9+ is strict.** Most popular places sit at 4.5–4.8. If you
  get 0 results, lower the threshold.
- **`maxItems × locations × queries`** is your upper bound on records.
  Need exactly 100? Use one query, one location, `maxItems: 100`.
- **Reviews & photos are opt-in extras.** Leave them at `0` if you only
  need names / addresses / phones / emails.
- **Captchas are rare** thanks to TLS impersonation + per-language
  residential proxies. When they do happen, the actor auto-rotates and
  retries up to 5 times.

---

### FAQ

**Do you support cities outside Russia?**
Yes. The dropdown is curated for Russian cities, but you can type any
city — Minsk, Almaty, Istanbul, Ankara, Baku — and it works. Pick the
matching `Language` for best results.

**Is the proxy configurable?**
Not needed — proxy country is auto-paired with `Language`
(RU → RU, BY → BY, KK → KZ, TR → TR, AZ → AZ, EN → US). This setup
minimizes captcha rate. If you have a special use case, contact me.

**What if a place has no website?**
The `emails` and `websitePhones` fields stay `null`. You still pay only
for the place itself ($3 / 1,000), not for the attempted contact scrape.

**What if a place has zero reviews?**
The actor sees `reviewsCount=0` from Yandex and skips the reviews
fetch entirely — you don't pay the review billing event for empty
results.

**Can I limit total spend per run?**
Yes — set `maxTotalChargeUsd` in Run Options. The actor honors it and
stops before exceeding.

**How fast is it?**
~150 places per minute on a single run with reviews + contacts off.
Add 0.5–1.5s per place when contacts are on (depends on the place's
website speed).

**My output is empty — why?**
Check the Log tab. Common causes:
- Empty `Search queries` + empty `Categories` + empty `Organization IDs`
  → nothing to do.
- Too-strict filters (Rating 4.9+ on a small city, Good place + niche
  category).
- Russian-language city while `Language=TR` → yandex.com.tr doesn't
  index Russian cities. Use `RU` instead.

**How do I run this from the API?**
Click the **API** button in Console — copy ready-to-paste cURL or SDK
snippets.

**What about reviews for non-Russian places?**
Pass the `Language` matching the region (`KK` for Kazakh, `TR` for
Turkish, etc.). Reviews are scraped from each place's `/reviews/`
page on the same Yandex regional domain.

---

### Author

Built and maintained by **[kitcunemia](https://apify.com/kitcunemia)**.

Open for **custom scraping projects** and **bulk one-off extractions**.
Need a different source covered (Google Maps, 2GIS, OpenStreetMap)?
Send a message via my Apify profile — typical turnaround is a few days.

---

### Changelog

- **v0.7** — Belarusian language support, parallel reviews+contacts,
  reviewsCount=0 short-circuit, slimmer contacts paths, faster timeouts.
- **v0.6** — Pay-per-event billing, email/phone scraping, bilingual
  categories, English UI.
- **v0.5** — Initial release: 60+ fields, Apify-proxy auto-rotation,
  TLS impersonation.

# Actor input Schema

## `query` (type: `array`):

One or more queries, just like you'd type into the Yandex Maps search bar.
## `locations` (type: `array`):

Pick one or more Russian cities, or type a custom city of your own. Each query is run for every selected city. Leave empty to search without a city scope.
## `maxItems` (type: `integer`):

Maximum number of places to collect per query / city pair.
## `language` (type: `string`):

Selects the Yandex Maps regional domain used for searching (RU → yandex.ru, BY → yandex.by, EN → yandex.com, KK → yandex.kz, TR → yandex.com.tr, AZ → yandex.az). The proxy exit-IP country is configured automatically to match — no manual proxy settings required. Use **Belarusian** when scraping places in Minsk / Gomel / Brest etc. to avoid captchas.
## `ratingFilter` (type: `string`):

Minimum average rating threshold.
## `priceCategories` (type: `array`):

Optional price-bucket filter. Multi-select.
## `goodPlaceOnly` (type: `boolean`):

Keep only places that look like a 'good place' — rating ≥ 4.5 with ≥ 50 reviews.
## `categoryIds` (type: `array`):

Optional list of business categories. Multi-select with bilingual labels.
## `enableGlobalDataset` (type: `boolean`):

When enabled, unique places are also appended to a persistent global dataset.
## `maxPhotos` (type: `integer`):

Max additional photo URLs per place (capped at ~10 by Yandex SSR). 0 disables additional photos.
## `includePhotoAuthors` (type: `boolean`):

Include author metadata for additional images when available.
## `maxReviews` (type: `integer`):

Max number of reviews to collect per place. 0 disables reviews.
## `reviewsSort` (type: `string`):

Sort order used while collecting reviews.
## `includeReviewerData` (type: `boolean`):

Include reviewer profile fields when available.
## `scrapeContactsFromWebsite` (type: `boolean`):

When enabled, the actor visits each place's website and extracts email addresses and phone numbers (mailto: / tel: / contact pages) into the `emails` and `websitePhones` fields.
## `includeMenu` (type: `boolean`):

Collect menu sections and menu items when available.
## `organizationIds` (type: `array`):

Optional list of Yandex business OIDs. When set, the actor opens each organization directly. Reviews are still collected per place when **Number of reviews to extract** is greater than zero.

## Actor input object example

```json
{
  "query": [
    "coffee in Moscow"
  ],
  "maxItems": 20,
  "language": "RU",
  "ratingFilter": "any",
  "goodPlaceOnly": false,
  "enableGlobalDataset": false,
  "maxPhotos": 0,
  "includePhotoAuthors": false,
  "maxReviews": 0,
  "reviewsSort": "by_relevance_org",
  "includeReviewerData": true,
  "scrapeContactsFromWebsite": false,
  "includeMenu": false
}
````

# Actor output Schema

## `dataset` (type: `string`):

All scraped places — every record carries the full 60+ field schema.

# 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": [
        "coffee in Moscow"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kitcunemia/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": ["coffee in Moscow"] }

# Run the Actor and wait for it to finish
run = client.actor("kitcunemia/yandex-maps-places-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "coffee in Moscow"
  ]
}' |
apify call kitcunemia/yandex-maps-places-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=kitcunemia/yandex-maps-places-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Yandex Maps Quick Scraper",
        "description": "[💰 $1.00 / 1K] Extract Yandex Maps businesses with phones, emails, websites, ratings, reviews, photos, opening hours, and 60+ more fields. Search by query + city, by 100+ categories, or by direct Yandex business ID. Optional contact-scraping from each place's website. Pay only for what you collect.",
        "version": "0.7",
        "x-build-id": "sGlrjyUffSz6GcjUf"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/kitcunemia~yandex-maps-places-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-kitcunemia-yandex-maps-places-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/kitcunemia~yandex-maps-places-scraper/runs": {
            "post": {
                "operationId": "runs-sync-kitcunemia-yandex-maps-places-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/kitcunemia~yandex-maps-places-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-kitcunemia-yandex-maps-places-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "query": {
                        "title": "🔎 Search queries",
                        "type": "array",
                        "description": "One or more queries, just like you'd type into the Yandex Maps search bar.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "📍 Location",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Pick one or more Russian cities, or type a custom city of your own. Each query is run for every selected city. Leave empty to search without a city scope.",
                        "items": {
                            "type": "string",
                            "enumSuggestedValues": [
                                "Moscow",
                                "Saint Petersburg",
                                "Novosibirsk",
                                "Yekaterinburg",
                                "Kazan",
                                "Nizhny Novgorod",
                                "Chelyabinsk",
                                "Samara",
                                "Omsk",
                                "Rostov-on-Don",
                                "Ufa",
                                "Krasnoyarsk",
                                "Voronezh",
                                "Perm",
                                "Volgograd",
                                "Krasnodar",
                                "Saratov",
                                "Tyumen",
                                "Tolyatti",
                                "Izhevsk",
                                "Barnaul",
                                "Ulyanovsk",
                                "Irkutsk",
                                "Khabarovsk",
                                "Yaroslavl",
                                "Vladivostok",
                                "Makhachkala",
                                "Tomsk",
                                "Orenburg",
                                "Kemerovo",
                                "Novokuznetsk",
                                "Ryazan",
                                "Astrakhan",
                                "Naberezhnye Chelny",
                                "Penza",
                                "Lipetsk",
                                "Kirov",
                                "Cheboksary",
                                "Tula",
                                "Kaliningrad",
                                "Balashikha",
                                "Kursk",
                                "Stavropol",
                                "Sevastopol",
                                "Sochi",
                                "Ulan-Ude",
                                "Tver",
                                "Magnitogorsk",
                                "Ivanovo",
                                "Bryansk",
                                "Surgut",
                                "Vladimir",
                                "Chita",
                                "Arkhangelsk",
                                "Kaluga",
                                "Smolensk",
                                "Volzhsky",
                                "Kurgan",
                                "Oryol",
                                "Cherepovets",
                                "Vologda",
                                "Yakutsk",
                                "Saransk",
                                "Podolsk",
                                "Tambov",
                                "Grozny",
                                "Sterlitamak",
                                "Petrozavodsk",
                                "Kostroma",
                                "Nizhnevartovsk",
                                "Yoshkar-Ola",
                                "Novorossiysk",
                                "Komsomolsk-on-Amur",
                                "Taganrog",
                                "Syktyvkar",
                                "Nalchik",
                                "Shakhty",
                                "Dzerzhinsk",
                                "Orsk",
                                "Bratsk",
                                "Blagoveshchensk",
                                "Engels",
                                "Angarsk",
                                "Veliky Novgorod",
                                "Stary Oskol",
                                "Pskov",
                                "Biysk",
                                "Prokopyevsk",
                                "Balakovo",
                                "Rybinsk",
                                "Armavir",
                                "Severodvinsk",
                                "Abakan"
                            ]
                        }
                    },
                    "maxItems": {
                        "title": "💯 Number of places to extract (per each search term)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of places to collect per query / city pair.",
                        "default": 20
                    },
                    "language": {
                        "title": "🟢 Language",
                        "enum": [
                            "EN",
                            "RU",
                            "BY",
                            "KK",
                            "TR",
                            "AZ"
                        ],
                        "type": "string",
                        "description": "Selects the Yandex Maps regional domain used for searching (RU → yandex.ru, BY → yandex.by, EN → yandex.com, KK → yandex.kz, TR → yandex.com.tr, AZ → yandex.az). The proxy exit-IP country is configured automatically to match — no manual proxy settings required. Use **Belarusian** when scraping places in Minsk / Gomel / Brest etc. to avoid captchas.",
                        "default": "RU"
                    },
                    "ratingFilter": {
                        "title": "Rating",
                        "enum": [
                            "any",
                            "4.9",
                            "4.7",
                            "4.5",
                            "4.0",
                            "3.5",
                            "3.0"
                        ],
                        "type": "string",
                        "description": "Minimum average rating threshold.",
                        "default": "any"
                    },
                    "priceCategories": {
                        "title": "Price categories",
                        "type": "array",
                        "description": "Optional price-bucket filter. Multi-select.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "price_cheap",
                                "price_average",
                                "price_expensive",
                                "price_very_expensive"
                            ],
                            "enumTitles": [
                                "Low",
                                "Average",
                                "Above average",
                                "High"
                            ]
                        }
                    },
                    "goodPlaceOnly": {
                        "title": "Good place",
                        "type": "boolean",
                        "description": "Keep only places that look like a 'good place' — rating ≥ 4.5 with ≥ 50 reviews.",
                        "default": false
                    },
                    "categoryIds": {
                        "title": "Categories",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional list of business categories. Multi-select with bilingual labels.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Auto studio / Автоателье",
                                "Carwash / Автомойка",
                                "Auto repair shop / Автосервис, автотехцентр",
                                "Car towing and servicing / Автотехпомощь, эвакуация автомобилей",
                                "Car tuning studio / Студия автотюнинга",
                                "Body repairs / Кузовной ремонт",
                                "Vehicle alterations / Переоборудование транспортных средств",
                                "Transmission repairs / Ремонт АКПП",
                                "Tire fitting / Шиномонтаж",
                                "Auto parts / Автозапчасти",
                                "Gas station / АЗС",
                                "Car dealership / Автосалон",
                                "Car wash self-service / Мойка самообслуживания",
                                "Car rental / Прокат автомобилей",
                                "Restaurant / Ресторан",
                                "Cafe / Кафе",
                                "Pizzeria / Пиццерия",
                                "Bar / Бар, паб",
                                "Coffee shop / Кофейня",
                                "Fast food / Быстрое питание",
                                "Bakery / Пекарня",
                                "Sushi bar / Суши-бар",
                                "Confectionery / Кондитерская",
                                "Canteen / Столовая",
                                "Food delivery / Доставка еды",
                                "Beauty salon / Салон красоты",
                                "Hairdresser / Парикмахерская",
                                "Nail salon / Маникюрный салон",
                                "Spa salon / Спа-салон",
                                "Massage parlor / Массажный салон",
                                "Tattoo studio / Тату-салон",
                                "Cosmetology / Косметология",
                                "Pharmacy / Аптека",
                                "Hospital / Больница",
                                "Clinic / Клиника",
                                "Dental clinic / Стоматология",
                                "Veterinary clinic / Ветклиника",
                                "Medical center / Медицинский центр",
                                "Diagnostic center / Диагностический центр",
                                "Shopping mall / Торговый центр",
                                "Supermarket / Супермаркет",
                                "Grocery store / Продуктовый магазин",
                                "Electronics store / Магазин электроники",
                                "Clothing store / Магазин одежды",
                                "Bookstore / Книжный магазин",
                                "Furniture store / Мебельный магазин",
                                "Hardware store / Хозтовары",
                                "Sporting goods / Спортивные товары",
                                "Pet shop / Зоомагазин",
                                "Toy store / Магазин игрушек",
                                "Jewelry store / Ювелирный магазин",
                                "Florist / Цветочный магазин",
                                "Hotel / Гостиница",
                                "Hostel / Хостел",
                                "Apartments / Апартаменты",
                                "Resort / Курорт",
                                "Cinema / Кинотеатр",
                                "Theater / Театр",
                                "Museum / Музей",
                                "Park / Парк",
                                "Nightclub / Ночной клуб",
                                "Bowling / Боулинг",
                                "Karaoke club / Караоке-клуб",
                                "Quest room / Квест-комната",
                                "Amusement park / Парк развлечений",
                                "Art gallery / Художественная галерея",
                                "School / Школа",
                                "Kindergarten / Детский сад",
                                "University / Университет",
                                "Language school / Языковая школа",
                                "Driving school / Автошкола",
                                "Tutoring / Репетитор",
                                "Library / Библиотека",
                                "Gym / Спортзал, тренажёрный зал",
                                "Fitness center / Фитнес-центр",
                                "Swimming pool / Бассейн",
                                "Yoga studio / Йога-студия",
                                "Stadium / Стадион",
                                "Martial arts / Боевые искусства",
                                "Dance studio / Танцевальная студия",
                                "Bank / Банк",
                                "ATM / Банкомат",
                                "Currency exchange / Обмен валют",
                                "Insurance / Страхование",
                                "Notary / Нотариус",
                                "Lawyer / Юридические услуги",
                                "Accountant / Бухгалтерские услуги",
                                "Real estate agency / Агентство недвижимости",
                                "Travel agency / Турагентство",
                                "Post office / Почта",
                                "Police / Полиция",
                                "Government office / Госучреждение",
                                "Embassy / Посольство",
                                "Church / Церковь",
                                "Mosque / Мечеть",
                                "Synagogue / Синагога",
                                "Cemetery / Кладбище",
                                "Construction company / Строительная компания",
                                "Repair service / Ремонтная мастерская",
                                "Cleaning service / Клининговая компания",
                                "Locksmith / Слесарная мастерская",
                                "Photo studio / Фотостудия",
                                "Print shop / Полиграфия",
                                "Coworking / Коворкинг"
                            ]
                        }
                    },
                    "enableGlobalDataset": {
                        "title": "Append to global dataset (global deduplication only)",
                        "type": "boolean",
                        "description": "When enabled, unique places are also appended to a persistent global dataset.",
                        "default": false
                    },
                    "maxPhotos": {
                        "title": "Number of additional images to extract ($)",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Max additional photo URLs per place (capped at ~10 by Yandex SSR). 0 disables additional photos.",
                        "default": 0
                    },
                    "includePhotoAuthors": {
                        "title": "🤓 👀 Include image authors",
                        "type": "boolean",
                        "description": "Include author metadata for additional images when available.",
                        "default": false
                    },
                    "maxReviews": {
                        "title": "Number of reviews to extract ($)",
                        "minimum": 0,
                        "maximum": 99999,
                        "type": "integer",
                        "description": "Max number of reviews to collect per place. 0 disables reviews.",
                        "default": 0
                    },
                    "reviewsSort": {
                        "title": "Reviews sorting",
                        "enum": [
                            "by_relevance_org",
                            "by_time",
                            "by_rating_desc",
                            "by_rating_asc"
                        ],
                        "type": "string",
                        "description": "Sort order used while collecting reviews.",
                        "default": "by_relevance_org"
                    },
                    "includeReviewerData": {
                        "title": "🙋 Include reviewers' data",
                        "type": "boolean",
                        "description": "Include reviewer profile fields when available.",
                        "default": true
                    },
                    "scrapeContactsFromWebsite": {
                        "title": "📧 Email & phones from website",
                        "type": "boolean",
                        "description": "When enabled, the actor visits each place's website and extracts email addresses and phone numbers (mailto: / tel: / contact pages) into the `emails` and `websitePhones` fields.",
                        "default": false
                    },
                    "includeMenu": {
                        "title": "🍽 Collect menu",
                        "type": "boolean",
                        "description": "Collect menu sections and menu items when available.",
                        "default": false
                    },
                    "organizationIds": {
                        "title": "🏢 Organization IDs",
                        "type": "array",
                        "description": "Optional list of Yandex business OIDs. When set, the actor opens each organization directly. Reviews are still collected per place when **Number of reviews to extract** is greater than zero.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
