# Yandex Maps Reviews Scraper | Отзывы Яндекс Карт (`hyperbach/yandex-maps-reviews-scraper`) Actor

Scrape Yandex Maps reviews by organization URL or id: rating, text, date, likes, dislikes, photos, owner reply, author name and level, review id, with the organization's name, rating and review count. Relevance, newest, highest or lowest first, a cap per organization, a free organization row.

- **URL**: https://apify.com/hyperbach/yandex-maps-reviews-scraper.md
- **Developed by:** [Hyperbach](https://apify.com/hyperbach) (community)
- **Categories:** Automation, SEO tools, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 reviews

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

## Yandex Maps Reviews Scraper | Отзывы Яндекс Карт

**Yandex Maps reviews by organization, logged out: Yandex Maps URLs or numeric ids in, one row per review out — the star rating, the text and its language, the date, likes and dislikes, the photos, the owner's reply with its date, the author's public name, avatar and level and the review id — with the organization's name, rating and review count on every row; most relevant, newest, highest or lowest rated first, several organizations in one run, a cap per organization.** One free `organization` row per input carries the organization's record and a completeness verdict: COMPLETE (the list's own end), CAPPED (your limit), TRUNCATED (Yandex Maps' 600 an order) or PARTIAL. An unknown id, an organization with no review: free typed rows. No login, no Yandex account, no API key, proxies handled for you.

### Why this Yandex Maps reviews scraper

- **Several organizations in one run.** Give Yandex Maps organization URLs from any Yandex Maps host (yandex.ru, yandex.com, yandex.com.tr, yandex.kz …) or the numeric ids: each organization gets its own cap (`maxReviewsPerPlace`), and the run's cap sits on top (`maxItems`).
- **Four orders.** `relevance` (Yandex Maps' own default), `newest`, `highest` (5 stars first) and `lowest` (1 star first): the same four orders the Yandex Maps page offers. Each row carries its `rank` in the order read.
- **Every field the review shows.** The star rating, the whole text and its language, the date (UTC), likes and dislikes, the photo links (full size), the owner's reply with its date, the author's public name, avatar and city-expert level, and Yandex's review id; every row carries the organization's id, name, rating, rating count and review count and the input it answers.
- **The organization's record.** The free `organization` row carries the name, the rating, the rating and review counts, the address, the categories and the coordinates from the organization's own page.
- **Honest depth.** The reviews come 50 a call in the order asked, page after page, to the end of the list. Yandex Maps lists at most 600 reviews of an organization in one order (our test: page 13 is refused whatever the count, 2026-10-29): a longer list ends TRUNCATED, and the row names the organization's own count. A smaller organization is read to the list's own end (COMPLETE).
- **Honest runs.** An id Yandex Maps does not know is a free `not_found` row (its page named no organization on two exits), an organization with no review a free `empty` row, a value that names no organization a free `invalid` row, a repeated organization a free `duplicate` row. Every input gets a row; a review is charged once a run.
- **Fast and light.** Plain HTTP on the call the Yandex Maps page makes itself: 50 reviews a call, 14-36 KB on the wire. 658 reviews of three organizations took 8 seconds on our test.

### Who it's for

- **Businesses and agencies on Yandex Maps** — every review of your own locations, newest first, with the owner's replies beside them, to answer the ones still open and to follow the rating.
- **Market and competitor researchers** — the reviews of a list of competitors in one run, lowest rated first to read the complaints, with each organization's rating and review count.
- **Data and analytics teams** — typed rows keyed by `organization_id` and `review_id`, a free row per organization with its record, status and verdict, and a run summary to check a pipeline against.

### Quick start

**The 100 most relevant reviews of an organization (the default)**

```json
{
  "startUrls": [
    "https://yandex.com/maps/org/tanuki/1036014863/reviews/"
  ]
}
```

**The newest reviews of two organizations, by URL and by id**

```json
{
  "startUrls": [
    "https://yandex.ru/maps/org/niki_dent/55558183898/reviews/",
    "1036014863"
  ],
  "reviewSort": "newest",
  "maxReviewsPerPlace": 200
}
```

**The lowest rated reviews first (the complaints)**

```json
{
  "startUrls": [
    "1036014863"
  ],
  "reviewSort": "lowest",
  "maxReviewsPerPlace": 100
}
```

### Output

One row per review (and one free organization row per input):

| field | meaning |
|---|---|
| `row_type` | `review` (one review, charged) or `organization` (the input's row with the organization's record and the walk's verdict; free). |
| `input_index` | The 1-based position in `startUrls` of the input this row answers. |
| `input_value` | The input as you gave it (the URL or id). |
| `sort` | The order read: `relevance`, `newest`, `highest` or `lowest`. |
| `status` | `ok` on a review row; on an organization row `ok`, `empty`, `not_found`, `invalid`, `duplicate`, `failed` or `not_read`. |
| `status_detail` | Why an organization row has a status other than `ok`, in words. |
| `scraped_at` | When the row was read (UTC). |
| `organization_id` | Yandex Maps' numeric organization id (`55558183898`). |
| `organization_name` | The organization's name as Yandex Maps shows it. |
| `organization_rating` | The organization's rating on Yandex Maps (1-5). |
| `organization_rating_count` | How many ratings the organization's rating rests on. |
| `organization_review_count` | How many reviews the organization's page counts. |
| `organization_url` | The organization's Yandex Maps link. |
| `review_id` | Yandex Maps' review id. |
| `rank` | The review's position in the order read (1 = first). |
| `rating` | The review's star rating (1-5). |
| `text` | The review's whole text. |
| `text_language` | The text's language as Yandex Maps detects it (`ru`, `en` …). |
| `published_at` | The review's date as Yandex Maps shows it (UTC). |
| `likes` | The review's likes. |
| `dislikes` | The review's dislikes. |
| `photos` | The links of the review's photos (full size); null when it has none. |
| `photo_count` | How many photos the review carries. |
| `video_count` | How many videos the review carries. |
| `reply_text` | The organization owner's reply; null when there is none. |
| `replied_at` | The owner reply's date (UTC). |
| `author_name` | The author's public name as Yandex Maps shows it. |
| `author_avatar_url` | The author's public avatar. |
| `author_level` | The author's city-expert level as Yandex Maps shows it (`Знаток города 7 уровня`). |
| `pinned` | True when the review is pinned at the top of the organization's list. |
| `organization_address` | The organization's address (organization row). |
| `organization_categories` | The organization's categories on Yandex Maps (organization row). |
| `organization_latitude` | The organization's latitude (organization row). |
| `organization_longitude` | The organization's longitude (organization row). |
| `reviews_listed` | Yandex Maps' own count of the organization's reviews in the order read (organization row). |
| `reviews_delivered` | Review rows delivered for this organization (organization row). |
| `pages_read` | Pages of Yandex Maps' review list read for this organization (organization row). |
| `verdict` | COMPLETE (the list's own end), CAPPED (your limit), TRUNCATED (Yandex Maps' 600 an order) or PARTIAL (a refusal or the time limit) (organization row). |
| `verdict_detail` | The verdict in words, with the numbers (organization row). |

Example record:

```json
{
  "row_type": "review",
  "input_index": 1,
  "input_value": "https://yandex.ru/maps/org/niki_dent/55558183898/reviews/",
  "sort": "newest",
  "status": "ok",
  "status_detail": null,
  "scraped_at": "2026-10-29T02:35:48Z",
  "organization_id": "55558183898",
  "organization_name": "Стоматология на Никитской",
  "organization_rating": 5,
  "organization_rating_count": 98,
  "organization_review_count": 85,
  "organization_url": "https://yandex.ru/maps/org/stomatologiya_na_nikitskoy/55558183898/",
  "review_id": "gUGrcRxWxxa_8IONCdukRvZbDonmG5W0P",
  "rank": 8,
  "rating": 5,
  "text": "Хочу порекомендовать эту клинику от всей души! Удобное расположение, эстетичное и уютное пространство, а главное - невероятно доброжелательный персонал. Я очень трепетно и щепетильно отношусь к выбору стоматологов, но здесь могу с уверенностью сказать, что ваши зубы в надёжных руках. Это именно то место, куда хочется возвращаться без страха🥰",
  "text_language": "ru",
  "published_at": "2026-08-06T11:58:08.230Z",
  "likes": 1,
  "dislikes": 0,
  "photos": [
    "https://avatars.mds.yandex.net/get-altay/19807214/2a0000019fd6ee0a05124181454b9c1070b6/XXXL"
  ],
  "photo_count": 1,
  "video_count": 0,
  "reply_text": "Спасибо за ваш тёплый отзыв и доверие! Нам очень приятно, что вы так внимательно подходите к выбору стоматологов и при этом почувствовали себя у нас спокойно и уверенно. Особенно ценно, что вы отметили не только профессионализм специалистов, но и доброжелательность персонала, уютную атмосферу и удобное расположение. Для нас важно, чтобы посещение стоматолога не вызывало тревоги, а лечение проходило в комфортной обстановке и с ощущением, что здоровье зубов действительно находится в надёжных руках.\n\nСреди других направлений в Стоматологии на Никитской доступны лечение дёсен, рентген зуба и костная пластика. Мы стремимся комплексно подходить к здоровью полости рта, уделяя внимание точной диагностике, качеству стоматологического лечения и комфорту пациента на каждом этапе.\n\nС уважением,\nСтоматология на Никитской",
  "replied_at": "2026-08-06T17:23:07.950Z",
  "author_name": "Reviewer A.",
  "author_avatar_url": "https://avatars.mds.yandex.net/get-yapic/0/avatar-redacted/islands-200",
  "author_level": "Знаток города 4 уровня",
  "pinned": false,
  "organization_address": null,
  "organization_categories": null,
  "organization_latitude": null,
  "organization_longitude": null,
  "reviews_listed": null,
  "reviews_delivered": null,
  "pages_read": null,
  "verdict": null,
  "verdict_detail": null
}
```

### Pricing

**Pay for the reviews a run delivers**, plus one run start; no platform usage is billed to you. The review price falls with your Apify plan.

| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
| Review (`review`) | per 1,000 | $3.00 | $2.55 | $2.10 | $1.50 |
| Run start (`start`) | per run | $0.0017 | $0.0017 | $0.0017 | $0.0017 |

A review is **$3.00 per 1,000** on the Free plan ($0.003 a review). Each run that delivers a charged review also pays the **run start, $0.0017 once**; a run that delivers no charged review pays nothing at all. So 100 reviews of one organization cost $0.3017 on the Free plan and $0.2567 on Starter, and 600 reviews $1.8017 / $1.5317; several organizations in one run share one start. The free `organization` row of every input, an unknown id (`not_found`), an organization with no review (`empty`), a value that names no organization (`invalid`), a repeated organization (`duplicate`), an organization left at the cap or the time limit (`not_read`) and a refusal the run could not pass (`failed`) are never charged. A review is charged once a run. A run that stops early (a timeout, an abort) is charged for the reviews it delivered. `maxItems` counts the charged rows; before the first request the log names the price of each row at your plan and the most the run can cost. Enterprise plans have their own rates: the Actor's Pricing tab shows the price for your plan.

### Usage patterns

- **Organizations** — `startUrls` takes Yandex Maps organization URLs — `https://yandex.ru/maps/org/<name>/<id>/`, with or without `/reviews/`, on any Yandex Maps host, a map URL with `oid=<id>` — or the numeric organization id (`55558183898`). A search URL, a category URL or a short share link (`/maps/-/…`) names no single organization: it gets a free `invalid` row; open the organization on Yandex Maps and copy its URL.
- **What a row is** — `row_type` = `review`: one review with Yandex Maps' record; `rank` is its position in the order read; `sort` the order; the organization's id, name, rating and counts are on every review row. `row_type` = `organization`: the free row of one input — the organization's record, `reviews_listed` (Yandex Maps' own count in that order), `reviews_delivered`, `pages_read`, the `verdict` with its `verdict_detail`, and the `status` with its reason.
- **How far an organization goes** — `maxReviewsPerPlace` = 100 (the default) is the first 100 in the order asked; 0 reads every review Yandex Maps lists in that order, at most 600. `maxItems` caps the charged rows of the whole run. The organization row's `verdict` says where the walk stopped and why.

### Input configuration

| field | type | default | what it does |
|---|---|---|---|
| `startUrls` | `array` |  | The organizations to read: Yandex Maps organization URLs (`https://yandex.ru/maps/org/niki_dent/55558183898/reviews/`, `yandex.com/maps/org/55558183898/`, any Yandex Maps host such as yandex.com.tr or yandex.kz) or numeric organization ids (`55558183898`). Up to 1,000 a run; a value that names no organization gets a free `invalid` row, an organization given twice a free `duplicate` row. |
| `reviewSort` | `relevance` / `newest` / `highest` / `lowest` | `"relevance"` | `relevance`: Yandex Maps' own default order. `newest`: the newest reviews first. `highest`: 5 stars first. `lowest`: 1 star first. Yandex Maps lists at most 600 reviews of an organization in each order. |
| `maxReviewsPerPlace` | `integer` | `100` | Stop each organization after this many review rows (0 = every review Yandex Maps lists in the order, at most 600). A larger value reads up to 600; the organization row then says TRUNCATED with the organization's own count. |
| `maxItems` | `integer` | `0` | Stop the run after this many review rows across every organization (0 = no limit). Organization rows are free and not counted; an organization left unread at the cap gets a free `not_read` row. |

### Errors

**A run does not fail because of your input.** When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends **Succeeded**, charges nothing, and says what to change:

- the status message starts with `INPUT REJECTED`;
- the dataset holds one row, `{"error": true, "code": "…", "message": "…"}`, and no results;
- the key-value store record `ERROR` holds the same object.

From code, check `error` on the first row before reading results.

An organization with no review is not an error: it gets one free `organization` row with `status` empty, and the run goes on with the others. A run that ends **Failed** is a fault on our side, never your input; it charges nothing, and we are alerted.

### FAQ

**Which status is which?**

An organization row's `status` is `ok` (reviews served), `empty` (the organization exists and has no review), `not_found` (Yandex Maps has no organization with that id; its page named none on two exits), `invalid` (a value that names no organization), `duplicate` (the same organization twice: read once), `failed` (a refusal or an error; free) or `not_read` (left at `maxItems`, the charge limit or the run's time limit). A review row's `status` is `ok`.

**Why at most 600 reviews of an organization?**

Yandex Maps lists 600 reviews of an organization in each order and refuses the pages after them, whatever the organization's count (our test, 2026-10-29). The organization row says TRUNCATED and names the count; for a different part of a long list, run the same organization in another order.

**Are yandex.ru and yandex.com the same reviews?**

Yes. On our test the same reviews came back, field for field and in the same order, from yandex.ru and yandex.com. The organization's URL on any Yandex Maps host works as input.

**Is the author's name on the row?**

The public name, the avatar and the city-expert level are on every review row as Yandex Maps shows them publicly; the author's profile id is not read. They are personal data: process them under your own lawful basis.

**Does it need a Yandex account or API key?**

No. Everything is read from Yandex Maps' public pages, logged out.

### Integration

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/yandex-maps-reviews-scraper').call({"startUrls": ["https://yandex.com/maps/org/tanuki/1036014863/reviews/"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/yandex-maps-reviews-scraper').call(run_input={'startUrls': ['https://yandex.com/maps/org/tanuki/1036014863/reviews/']})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### CLI

```bash
apify call hyperbach/yandex-maps-reviews-scraper --input '{"startUrls": ["https://yandex.com/maps/org/tanuki/1036014863/reviews/"]}'
```

#### REST

```bash
curl -X POST "https://api.apify.com/v2/acts/hyperbach~yandex-maps-reviews-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' -d '{"startUrls": ["https://yandex.com/maps/org/tanuki/1036014863/reviews/"]}'
```

### Support

**Disagree with a charge?** Write to apify@hyperbach.com with the run ID. We will ask Apify to compensate you, and the charge comes back to your Apify account as platform credit.

**Did it do the job?** A short [review on the Store](https://apify.com/hyperbach/yandex-maps-reviews-scraper/reviews), at any rating, helps the next buyer choose.

### See also

- **[Trustpilot Reviews Scraper](https://apify.com/hyperbach/trustpilot-reviews-scraper)** — every review of a business on Trustpilot, past the 200-review cap.
- **[App Store Reviews Scraper](https://apify.com/hyperbach/app-store-reviews-scraper)** — Apple App Store reviews by app and country, with the app version each reviewer used.
- **[Google Play Reviews Scraper](https://apify.com/hyperbach/google-play-reviews-scraper)** — Google Play reviews by app, language and country, with the app version each reviewer used.
- **[Goodreads Scraper](https://apify.com/hyperbach/goodreads-scraper)** — books by URL, ISBN or search, with the rating distribution and the readers' reviews.
- **[Yelp Reviews Scraper](https://apify.com/hyperbach/yelp-reviews-scraper)** — every review of a Yelp business, with the owner's reply, the photos and the reviewer's public counts, without an API key.

*This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.*

# Actor input Schema

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

The organizations to read: Yandex Maps organization URLs (`https://yandex.ru/maps/org/niki_dent/55558183898/reviews/`, `yandex.com/maps/org/55558183898/`, any Yandex Maps host such as yandex.com.tr or yandex.kz) or numeric organization ids (`55558183898`). Up to 1,000 a run; a value that names no organization gets a free `invalid` row, an organization given twice a free `duplicate` row.

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

`relevance`: Yandex Maps' own default order. `newest`: the newest reviews first. `highest`: 5 stars first. `lowest`: 1 star first. Yandex Maps lists at most 600 reviews of an organization in each order.

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

Stop each organization after this many review rows (0 = every review Yandex Maps lists in the order, at most 600). A larger value reads up to 600; the organization row then says TRUNCATED with the organization's own count.

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

Stop the run after this many review rows across every organization (0 = no limit). Organization rows are free and not counted; an organization left unread at the cap gets a free `not_read` row.

## Actor input object example

```json
{
  "startUrls": [
    "https://yandex.com/maps/org/tanuki/1036014863/reviews/"
  ],
  "reviewSort": "relevance",
  "maxReviewsPerPlace": 50,
  "maxItems": 50
}
```

# Actor output Schema

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

All scraped records in the default dataset. One row per review (and one free organization row per input):

## `runSummary` (type: `string`):

How the run went: review rows charged, free rows, organizations by status, the walk per organization (reviews listed and delivered, pages read, repeated reviews skipped, the verdict), the source counters (calls, served, refused, exits, rotations, bytes) and the memory watch.

# 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 = {
    "startUrls": [
        "https://yandex.com/maps/org/tanuki/1036014863/reviews/"
    ],
    "maxReviewsPerPlace": 50,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("hyperbach/yandex-maps-reviews-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 = {
    "startUrls": ["https://yandex.com/maps/org/tanuki/1036014863/reviews/"],
    "maxReviewsPerPlace": 50,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("hyperbach/yandex-maps-reviews-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 '{
  "startUrls": [
    "https://yandex.com/maps/org/tanuki/1036014863/reviews/"
  ],
  "maxReviewsPerPlace": 50,
  "maxItems": 50
}' |
apify call hyperbach/yandex-maps-reviews-scraper --silent --output-dataset

```

## MCP server setup

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