# Yandex Maps Scraper API (`dami_studio/yandex-maps-scraper`) Actor

Scrape Yandex Maps places by search term, city or URL: name, address, GPS coordinates, category, rating, review count, phone, website and opening hours. $0.40 per 1,000 places - the lowest price on the market, flat on every plan. No Yandex API key needed.

- **URL**: https://apify.com/dami\_studio/yandex-maps-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 place returneds

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 Scraper API

Pulls business listings out of Yandex Maps — the map most people actually use in Russia, Belarus, Kazakhstan, Uzbekistan, Armenia, Azerbaijan and Turkey, where Google Maps coverage is thin or out of date.

Give it a search term and a city, or paste Yandex Maps URLs. You get back one row per place with the name, full address, GPS coordinates, category, star rating, review count, phone number, website and opening hours.

**$0.40 per 1,000 places.** No Yandex Maps scraper with a real user base charges less. The two established competitors charge $4.00 and $6.99 per 1,000 on their free tiers.

### What a row looks like

A real row from a "кафе" search in Moscow:

```json
{
  "placeId": "1207115252",
  "name": "Osteria Gini",
  "categoryPrimary": "Ресторан",
  "categories": ["Ресторан", "кафе"],
  "address": "Москва, 1-й Колобовский переулок, 11",
  "city": "Москва",
  "street": "1-й Колобовский переулок",
  "postalCode": "127051",
  "latitude": 55.769063,
  "longitude": 37.616219,
  "phone": "+79259816427",
  "phones": ["+79259816427"],
  "website": "https://ginirest.ru/",
  "rating": 4.8,
  "ratingCount": 1112,
  "reviewCount": 553,
  "openingHoursText": "Mon: 12:00-23:00; Tue: 12:00-23:00; Wed: 12:00-23:00; ...",
  "isOpenNow": false,
  "nearestMetro": { "name": "Трубная", "distanceMeters": 543 },
  "verifiedOwner": true,
  "url": "https://yandex.com/maps/org/osteria_gini/1207115252/"
}
```

Every field: `placeId`, `name`, `nameShort`, `chainName`, `categoryPrimary`, `categories`, `address`, `addressDetail`, `country`, `city`, `street`, `postalCode`, `latitude`, `longitude`, `phone`, `phones`, `website`, `websites`, `socialProfiles`, `rating`, `ratingCount`, `reviewCount`, `openingHoursText`, `openingHoursRaw`, `openingHours`, `isOpenNow`, `priceRange`, `nearestMetro`, `verifiedOwner`, `status`, `url`, `searchQuery`, `position`, `scrapedAt`.

### How complete is it

Measured on a real 250-place run (Moscow, "кафе", 61 seconds):

| Field | Filled |
|---|---|
| name, address, coordinates, category | 250 / 250 |
| rating, review count | 250 / 250 |
| phone | 250 / 250 |
| opening hours | 249 / 250 |
| website | 237 / 250 |
| postal code | 196 / 250 |

Phone coverage is unusually high because Yandex Maps is the primary business directory in these markets, so owners keep their cards current.

### Input

```json
{
  "searchQueries": ["кафе", "стоматология"],
  "city": "Moscow",
  "maxItems": 250
}
```

- **searchQueries** — one term per line. Russian terms return more than English ones, even in Turkey.
- **city** — "Moscow", "Москва", "Almaty", "Istanbul" and a numeric Yandex geo id all work.
- **startUrls** — paste search pages (`https://yandex.ru/maps/213/moscow/search/кафе/`) or single business pages (`https://yandex.ru/maps/org/osteria_mario/1769547913/`).
- **latitude / longitude / zoom** — search around a point instead of a whole city.
- **maxItems** — hard cap. Duplicates are removed *before* this cap, so asking for 250 gives you 250 distinct businesses.
- **language** — Russian, English, Turkish, Ukrainian, Kazakh, Uzbek or Azerbaijani.

### Pricing

| | |
|---|---|
| Per place returned | $0.0004 ($0.40 per 1,000) |
| Actor start | $0.001 per run |

You are charged per unique place. Duplicates, sample rows, error rows, captchas and empty runs cost nothing beyond the start fee. A 250-place run costs $0.101.

For comparison, on their free tiers: `m_mamaev/yandex-maps-places-scraper` charges $4.00 per 1,000, `zen-studio/yandex-maps-scraper` charges $6.99 per 1,000.

### What this does not do

Being straight about the limits:

- **No reviews.** You get the rating and the review *count*, not the review text. That is a different scraper.
- **No photos.** Yandex ships image URLs in its page data; this actor does not return them.
- **No email addresses.** Yandex Maps cards do not carry them. Anything claiming otherwise is guessing from the website domain.
- **Roughly 25 places per request.** Large jobs page through the result list, so 1,000 places means about 50 requests and a few minutes.
- **Yandex re-ranks between pages.** Consecutive pages overlap by around 25%. The actor removes duplicates for you, which is why a deep run makes more requests than `maxItems / 25` would suggest.
- **Result totals are estimates.** Yandex's own "about 94 matches" figure moves between requests. Treat it as a hint, not a count.
- **Some fields stay in Russian** whatever language you pick — Yandex localises names and categories, but street names in Russia usually stay Cyrillic.

### FAQ

**Do I need a Yandex API key?**
No. The official Yandex Places API requires a paid key and caps results. This actor reads the public map pages instead, so there is nothing to sign up for.

**How is this different from a Google Maps scraper?**
Different index. In Russia and most of the CIS, Yandex Maps has more businesses, more current phone numbers and far more reviews than Google Maps. In Turkey it is a strong second source. If you need Western Europe or the US, use a Google Maps scraper.

**Can I scrape a single business I already have the link for?**
Yes. Paste the `https://yandex.ru/maps/org/.../<id>/` URL into `startUrls`. One place, one row, one charge.

**Can I search by map area instead of by city?**
Yes. Set `latitude`, `longitude` and `zoom`. Zoom 15 is about a neighbourhood, zoom 11 about a city.

**How many places can I get for one search term?**
Yandex keeps serving deeper pages as you go; a Moscow "кафе" search comfortably passes 250. Very narrow terms in small towns run out sooner, and the actor stops when a page stops producing anything new.

**Why did my run return an error row instead of places?**
Error rows are free. `CAPTCHA` means Yandex challenged that exit address — re-run and it usually lands elsewhere. `NO_RESULTS` means the search genuinely matched nothing; try a broader or Russian-language term. `CITY_NOT_FOUND` means Yandex did not recognise the city name.

**Is the output ready for a CRM?**
Phone numbers come back normalised (`+79259816427`). Website links have Yandex's own tracking parameters stripped, so you get `https://ginirest.ru/` rather than a URL with `yclid` and `utm_source` glued on.

**What does an empty run cost?**
The $0.001 start fee and nothing else.

### Sample output with no input

Run it with no search terms and it returns a single clearly-labelled sample row, marked `_sample: true` and `charged: false`, so you can see the shape before spending anything.

# Actor input Schema

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

What to look for on Yandex Maps, for example "кафе", "стоматология", "coffee". One search per line. Yandex indexes Russian-language names most completely, so local-language terms return more results.

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

City to search in. English, Russian or local spelling all work ("Moscow", "Москва", "Almaty", "Istanbul"). You can also paste a numeric Yandex geo id such as 213. Leave empty to let Yandex pick the map view.

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

Optional. Paste Yandex Maps search pages (https://yandex.ru/maps/213/moscow/search/кафе/) or single organisation pages (https://yandex.ru/maps/org/osteria\_mario/1769547913/). Works alongside the fields above.

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

Hard cap on unique places returned across all searches (1-5000). Duplicates are removed before this cap is applied, so you get the number you asked for. You are charged per place returned.

## `latitude` (type: `string`):

Search around a point instead of a whole city. Example: 55.7558

## `longitude` (type: `string`):

Used together with latitude. Example: 37.6173

## `zoom` (type: `integer`):

Yandex map zoom level for coordinate search. Higher is tighter: 11 covers a city, 15 covers a neighbourhood. Ignored unless coordinates are set.

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

Language for names, categories and addresses. Yandex Maps is a Russian product: Russian is the most complete, and some fields stay in Russian whatever you pick.

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

Optional. The actor already uses its own egress; leave this alone unless you need to exit from a specific network.

## Actor input object example

```json
{
  "searchQueries": [
    "кафе"
  ],
  "city": "Moscow",
  "startUrls": [],
  "maxItems": 50,
  "zoom": 13,
  "language": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "кафе"
    ],
    "city": "Moscow",
    "startUrls": [],
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/yandex-maps-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["кафе"],
    "city": "Moscow",
    "startUrls": [],
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "кафе"
  ],
  "city": "Moscow",
  "startUrls": [],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dami_studio/yandex-maps-scraper --silent --output-dataset

```

## MCP server setup

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