# Yandex Realty Listings Scraper (`apt_marble/yandex-realty-listings-scraper`) Actor

Collect property listings for sale and rent across 42 Russian markets. Every row carries asking price, price per square metre, rooms, areas, floor, address, coordinates, nearest metro and travel time, building year and whether the seller is an owner, an agency or a developer.

- **URL**: https://apify.com/apt\_marble/yandex-realty-listings-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 property listing founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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 Realty Listings Scraper

Turn any property search on Russia's largest property portal into a clean,
ready-to-use table. Pick a city, choose whether you want properties for sale or
to rent, set the property type and your price, size, room and floor limits, and
this actor hands back every matching listing with its asking price, price per
square metre, room count, living and kitchen area, floor, full address,
coordinates, nearest metro station and travel time, building year and
construction type, and whether the property is offered by the owner, an agency
or a developer. It is built for analysts, agencies, investors and property-tech
teams who need real market data in a spreadsheet rather than in a browser tab.

### What you can do with it

- **Build a comparables table** for a valuation: same city, same room count,
  same area band, with price per square metre already worked out on every row.
- **Track a market over time** by scheduling the same search daily or weekly and
  comparing asking prices, price movements and how much new stock appears.
- **Find properties offered directly by their owners** — one switch keeps only
  the listings the source shows as owner-listed, which is the list estate
  agencies buy.
- **Measure agency market share** in a city by counting listings per agency name
  and comparing average asking prices between them.
- **Track new-build inventory** by collecting only newly built apartments and
  watching what developers add, and at what price per square metre.
- **Feed a property portal, a map or a valuation model** with structured rows
  that already carry coordinates and nearest-metro travel times.

### What you get

One row per property listing. An abridged real example:

```json
{
  "offerId": "3937530341846000586",
  "url": "https://realty.yandex.ru/offer/3937530341846000586",
  "dealType": "buy",
  "propertyType": "apartment",
  "price": 63000000,
  "currency": "RUB",
  "pricePeriod": "total",
  "pricePerMeter": 1235294,
  "previousPrice": 65000000,
  "priceTrend": "decreased",
  "estimatedPrice": 46402000,
  "estimatedPriceMin": 41762000,
  "estimatedPriceMax": 51042000,
  "rooms": 2,
  "isStudio": false,
  "areaTotal": 51,
  "areaUnit": "squareMetres",
  "areaLiving": 32,
  "areaKitchen": 8,
  "landArea": null,
  "floor": 8,
  "floorsTotal": 26,
  "ceilingHeight": 3,
  "address": "Нежинская улица, 5с1",
  "latitude": 55.714916,
  "longitude": 37.475018,
  "metroName": "Матвеевская",
  "metroMinutes": 17,
  "metroTransport": "walking",
  "buildingYear": 2021,
  "buildingType": "monolithic",
  "renovation": "renovated",
  "isNewBuilding": false,
  "sellerType": "agency",
  "agencyName": "Whitewill",
  "publishedAt": "2026-04-26T20:14:31.000Z",
  "updatedAt": "2026-08-17T07:02:00.000Z",
  "photoCount": 8,
  "regionName": "Moscow",
  "collectedAt": "2026-08-17T12:24:02.807Z"
}
```

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `region` | choice | `moskva` | The city or region whose market you want. 42 markets are available, from Moscow and Saint Petersburg to Vladivostok. |
| `additionalRegions` | list of choices | empty | Collect more cities in the same run, each with its own limit. Useful for comparing markets side by side. |
| `dealType` | choice | `buy` | `buy` for properties offered for sale, `rent` for properties offered to rent. |
| `propertyType` | choice | `apartment` | `apartment`, `room`, `house`, `land`, `garage` or `commercial`. |
| `rooms` | list of choices | empty | Keep only properties with these room counts: studio, 1, 2, 3, or 4 or more. Applies to apartments and rooms. The source does not filter houses, land, garages or commercial property by room count, so setting it there stops the run instead of returning every size. |
| `marketSegment` | choice | `any` | Separate newly built apartments from resale apartments. Available for apartments offered for sale. |
| `ownersOnly` | boolean | `false` | Keep only properties the source shows as offered by the owner rather than by an agency, an agent or a developer. |
| `priceMin` / `priceMax` | number | empty | Asking-price band in Russian roubles. For rentals this is the monthly rent. |
| `areaMin` / `areaMax` | number | empty | Total-area band. In **square metres** for apartments, rooms, houses, garages and commercial property — and in **ares** for land plots, because that is the unit this source measures ground in. One are is 100 m², so `6`–`12` on a land search means plots of 600–1,200 m². The unit in force is printed in the run log and recorded in the run summary. |
| `floorMin` / `floorMax` | number | empty | Floor band. Applies to apartments, rooms and commercial property. |
| `sortBy` | choice | `relevance` | Best match, cheapest first, most expensive first, newest first, or largest area first. This decides which properties you see first when your limit is smaller than the market. |
| `maxResultsPerCity` | number | `100` | How many listings to collect for each city, up to 500. |
| `parallelCities` | number | `3` | How many cities to work through side by side. |

If a setting cannot be satisfied — an unknown city, a minimum price above the
maximum, a room filter on a garage — the run stops immediately with a plain
sentence telling you what to change. It never quietly ignores a setting and
hands you a table that answers a different question.

### Output fields

| Field | Description |
| --- | --- |
| `offerId` | Stable identifier for the listing. |
| `url` | Address of the listing on the source site. |
| `dealType`, `propertyType` | What was collected: for sale or to rent, and which kind of property. |
| `price` | Asking price as published. |
| `currency` | Currency of the asking price, as published. |
| `pricePeriod` | `total` for a sale price, `perMonth` for a rent. |
| `pricePerMeter` | Price per square metre, where the source publishes the price that way. |
| `pricePerAre` | Price per are (100 m²), used for land. |
| `previousPrice`, `priceTrend` | The earlier asking price and whether it went up, down or stayed level, where published. |
| `estimatedPrice`, `estimatedPriceMin`, `estimatedPriceMax` | The source's own valuation range for the property, where published. |
| `rooms`, `isStudio` | Room count, and a flag for studios, which have no room count. |
| `areaTotal`, `areaUnit` | Total area and the unit it is published in — square metres for buildings, ares for land. |
| `areaLiving`, `areaKitchen` | Living and kitchen area in square metres, where published. |
| `landArea` | Plot size in ares, for houses and land. |
| `floor`, `floorsTotal` | Which floor the property is on, and how many the building has. |
| `ceilingHeight` | Ceiling height in metres, where published. |
| `address` | Street address as published. |
| `latitude`, `longitude` | Coordinates. |
| `metroName`, `metroMinutes`, `metroTransport` | Nearest metro station, travel time to it, and whether that time is on foot or by public transport. |
| `buildingYear`, `buildingType`, `buildingSeries` | When the building went up, what it is built of, and its series where published. |
| `renovation` | Condition or finish, where published. |
| `isNewBuilding` | Whether the source classes the property as a new build. |
| `sellerType` | `owner`, `agency`, `agent`, `privateAgent` or `developer`. |
| `agencyName` | Name of the agency or developer, where published. |
| `publishedAt`, `updatedAt` | When the listing first appeared and when it was last touched. |
| `photoCount`, `imageUrl` | How many photographs the listing has, and the first one. |
| `description` | The seller's own description text. |
| `region`, `regionName`, `regionId` | The market the listing belongs to, confirmed from the answer itself. |
| `page`, `position` | Where the listing sat in the source's own ordering. |
| `collectedAt` | When this row was collected. |

Any field the source does not publish for a given property comes back as
`null`. It is never filled with a zero, an empty string or a value borrowed from
another listing — so `null` always means "not published", and a number always
means a real number.

### Pricing

This actor is priced per result.

| What you pay for | Price |
| --- | --- |
| Each property listing added to your results | $0.004 (that is $4.00 per 1,000 listings) |

Nothing else is charged. A run that collects 500 listings costs $2.00. A run
across five cities at 200 listings each collects 1,000 listings and costs $4.00.
A search that matches nothing costs nothing at all, because you are only ever
charged for listings you receive.

### Limits & what this actor cannot do

- **Contact phone numbers are not included.** The source does not publish a
  seller's phone number as part of a listing, so no phone number appears in your
  results and none is guessed. What you do get is the seller type, the agency or
  developer name where published, and the address of the listing itself, which
  is where a contact can be made.
- **The source publishes a limited number of properties for any one search** —
  at most about 500, and often fewer. Big markets hold far more than that, and
  the source's own "found" figure is not what it will hand over. Two things cut
  the real number down: a search with a sort order applied is served in smaller
  pages, and a search without one repeats some of the same properties across
  pages, so a small market can finish at around 400 distinct listings. To go
  deeper, split one broad search into several narrow ones by price band, room
  count, area or property type; each narrow search gets its own allowance.
- **Results are a snapshot** taken at the moment of collection. Asking prices,
  availability and the properties on offer all change continuously, and a
  listing can be withdrawn minutes after it is collected.
- **The actor reports what the source publishes to the public.** It does not
  sign in, it sees nothing behind a login, and it cannot reveal a detail the
  source keeps private.
- **Some fields are legitimately missing.** Living and kitchen area, ceiling
  height, building year, the agency name and the source's own valuation are
  published on some listings and not others. Nearest-metro details only exist in
  cities that have a metro. Those come back empty rather than invented.
- **Asking prices are asking prices**, not sale prices. Nothing here is a record
  of what a property actually sold for.
- **Areas are published in different units by property type.** Buildings are
  measured in square metres; land plots — and the largest commercial plots — in
  ares (100 m²). Every row states which unit its area is in, and the per-unit
  price follows the same unit. The **area filter** follows the same rule: on a
  land search the numbers you type are ares, not square metres, and the unit in
  force is printed in the run log and recorded in the run summary.
- **Not every filter applies to every property type**, and the ones that do not
  are refused rather than accepted and ignored. Room count works on apartments
  and rooms; floor limits on apartments, rooms and commercial property; the
  newly-built / resale split on apartments offered for sale.
- **Newly built properties are matched by development, not by flat.** On a
  search with a price limit, the source can return a listing whose own asking
  price sits above the maximum you set: it matched the development — which does
  have flats inside your band — and then showed a different flat inside it.
  Measured on a Moscow search capped at 10 million roubles, 9 of the 23
  listings on the first page came back above the cap, every one of them a new
  build. Those listings are **left out of your results and not charged for**, so
  the table always answers the question you asked; the run summary reports how
  many were left out under `listingsOutsideYourLimits`. Adding "resale only", or
  sorting by price, avoids them at the source.
- **A search the source refuses to complete is reported as a failed search**,
  never as "no properties found". The run summary counts cities that produced
  listings, cities that genuinely matched nothing, cities where the source
  published listings but none met your limits, and cities that could not be read
  as four separate numbers, so an incomplete run is always visible.
- **Speed depends on the size of the job** and on how quickly the source
  answers. No fixed throughput is promised.
- **Personal data.** Some listings are placed by private individuals. This actor
  reports only what the source publishes openly, and never attempts to build a
  profile of a person. You are responsible for using the data lawfully and in
  line with the source's terms, including GDPR and Russian personal data law
  where they apply.

### FAQ

**Do I need an account on the source site?**
No. Nothing needs to be set up — pick a city and run it.

**Does it need my login or password?**
No. It never signs in anywhere and never asks you for credentials.

**Can I schedule it?**
Yes. Schedule it daily or weekly on Apify and each run appends a fresh snapshot,
which is how price-change tracking is normally done.

**Are phone numbers or seller emails included?**
No. The source does not publish them with a listing, so they are not in your
results and are never guessed. You get the seller type, the agency or developer
name where published, and the listing's own address.

**Why did I get fewer listings than the source says exist?**
Every large market shows a headline figure far bigger than the number of
individual properties it will hand over for a single search — about 500 is the
practical ceiling, and a smaller market can finish nearer 400 because the source
repeats some properties across pages. Split a broad search into narrower ones by
price band, room count or area and you can collect far more of the market.

**Can I collect several cities in one run?**
Yes. Choose your main city, then add as many more as you like under
`additionalRegions`; each one gets its own allowance and every row is labelled
with the city it came from.

**How do I know the results are really for the city I picked?**
Every row carries the market it belongs to, confirmed from the answer itself
rather than from what was asked for. If the source ever answers for a different
area, that city is reported as failed instead of silently handing you another
city's market.

# Actor input Schema

## `region` (type: `string`):

The property market to collect. Every choice here is a market the source publishes listings for.

## `additionalRegions` (type: `array`):

Optional. Collect these cities in the same run as well, each with its own limit. Leave empty to collect one city only.

## `dealType` (type: `string`):

Collect properties offered for sale, or properties offered to rent.

## `propertyType` (type: `string`):

The kind of property to collect.

## `rooms` (type: `array`):

Optional. Keep only properties with these room counts. Applies to apartments and rooms — the source ignores a room filter on houses, land, garages and commercial property, so choosing one there stops the run instead of quietly returning every size. Leave empty for every size. The source groups everything from four rooms upward together, which is why the largest choice is "4 or more".

## `marketSegment` (type: `string`):

Optional. Separate newly built apartments from resale apartments. Available for apartments offered for sale.

## `ownersOnly` (type: `boolean`):

Keep only properties the source shows as offered by the owner rather than by an agency, an agent or a developer.

## `priceMin` (type: `integer`):

Optional. Lowest asking price to include, in Russian roubles. For rentals this is the monthly rent.

## `priceMax` (type: `integer`):

Optional. Highest asking price to include, in Russian roubles. For rentals this is the monthly rent.

## `areaMin` (type: `integer`):

Optional. Smallest total area to include. In square metres for apartments, rooms, houses, garages and commercial property — but in ares for land plots, because that is the unit this source measures ground in. One are is 100 m², so "6" on a land search means a 600 m² plot.

## `areaMax` (type: `integer`):

Optional. Largest total area to include. In square metres for apartments, rooms, houses, garages and commercial property — but in ares for land plots, because that is the unit this source measures ground in. One are is 100 m², so "12" on a land search means a 1,200 m² plot.

## `floorMin` (type: `integer`):

Optional. Only include properties on this floor or above. Applies to apartments, rooms and commercial property.

## `floorMax` (type: `integer`):

Optional. Only include properties on this floor or below. Applies to apartments, rooms and commercial property.

## `sortBy` (type: `string`):

The order the source should return listings in. This changes which properties you see first when your limit is smaller than the market.

## `maxResultsPerCity` (type: `integer`):

How many listings to collect for each city. The source hands over at most about 500 properties for any one search, and smaller markets stop below that, so narrow the search with price, area or room filters when you need more.

## `parallelCities` (type: `integer`):

How many cities to work through side by side. Raise it for a faster run across many cities, lower it for a gentler one.

## Actor input object example

```json
{
  "region": "moskva",
  "additionalRegions": [],
  "dealType": "buy",
  "propertyType": "apartment",
  "rooms": [],
  "marketSegment": "any",
  "ownersOnly": false,
  "priceMax": 20000000,
  "sortBy": "relevance",
  "maxResultsPerCity": 100,
  "parallelCities": 3
}
```

# Actor output Schema

## `listings` (type: `string`):

Every property listing this run collected.

## `overview` (type: `string`):

The same listings in the compact overview layout.

## `spreadsheet` (type: `string`):

Every listing as a CSV file you can open in a spreadsheet.

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

What this run collected for each city, which searches matched nothing, and anything it could not read.

# 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 = {
    "region": "moskva",
    "dealType": "buy",
    "propertyType": "apartment",
    "priceMax": 20000000,
    "maxResultsPerCity": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/yandex-realty-listings-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 = {
    "region": "moskva",
    "dealType": "buy",
    "propertyType": "apartment",
    "priceMax": 20000000,
    "maxResultsPerCity": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/yandex-realty-listings-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 '{
  "region": "moskva",
  "dealType": "buy",
  "propertyType": "apartment",
  "priceMax": 20000000,
  "maxResultsPerCity": 100
}' |
apify call apt_marble/yandex-realty-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/yandex-realty-listings-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/pEl93Nf5IakuLMUcC/builds/LFYyOoKq45T9CPjws/openapi.json
