# Yandex Market Product & Offers Scraper (`apt_marble/yandex-market-product-offers-scraper`) Actor

See every seller offering a product on Yandex Market: price, discount, seller rating, delivery time and stock for each one, plus full product specifications when you want them. Built for price monitoring, buy-box tracking and undercut analysis. No account and no login needed.

- **URL**: https://apify.com/apt\_marble/yandex-market-product-offers-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Categories:** E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 offer collecteds

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 Market Product & Offers Scraper

Give it a product and get back everyone who is selling it. For each product you
name, this actor returns one row per seller offer — the price, what the price was
before the discount, the seller's name and star rating, the delivery promise, how
many units are left, and whether the item is pre-owned or shipped from abroad.
Turn on specifications and the product's full attribute list is attached to every
one of its rows. It is built for anyone who needs to know who is cheapest on a
product right now and by how much: repricing teams, brand owners policing their
resellers, marketplace sellers watching the competition, and analysts tracking
Russian e-commerce prices.

### What you can do with it

- **Watch the buy box.** Track who holds the lowest price on your products, day
  by day, and by what margin.
- **Find who is undercutting you.** Every row names the seller, links to their
  page and carries their rating, so an aggressive competitor is identifiable, not
  anonymous.
- **Monitor your own resellers.** Check whether anyone is breaking your minimum
  advertised price, and spot pre-owned listings sitting next to new ones.
- **Compare discount depth.** Each offer carries the price before the discount
  and the discount percentage, so you can see who is really cheap and who just
  looks cheap.
- **Build a product database.** Switch specifications on and every row carries
  the product's published attributes, ready for a catalogue or a comparison site.
- **Check availability and delivery.** Stock figures and delivery wording come
  through per seller, which is where availability problems show up first.

### What you get

One row per seller offer. Abridged real record:

```json
{
  "productId": "1912483624",
  "productTitle": "Смартфон Apple iPhone 15",
  "productUrl": "https://market.yandex.ru/product--x/1912483624",
  "offerId": "1bTehhnNjRtQ79x0Z0ULXw",
  "offerTitle": "Смартфон Apple iPhone 15 512 ГБ, Dual: eSIM + eSIM, Pink (розовый)",
  "offerUrl": "https://market.yandex.ru/product--x/1912483624?sku=102322320798&offerid=1bTehhnNjRtQ79x0Z0ULXw",
  "skuId": "102322320798",
  "sellerName": "БурмаТех",
  "sellerId": "216649410",
  "sellerRating": 4.8,
  "sellerRatingCount": 84,
  "sellerUrl": "https://market.yandex.ru/business--burmatekh/216649410",
  "price": 106325,
  "currency": "RUB",
  "oldPrice": 315284,
  "discountPercent": 66,
  "deliveryText": "1–2 часа",
  "inStock": true,
  "stockCount": 10,
  "isCrossborder": false,
  "isResale": false,
  "sellerRatingForThisProduct": 5,
  "sellerRatingCountForThisProduct": 3,
  "imageUrl": "https://avatars.mds.yandex.net/get-mpic/5289292/2a00000192d28cb92b7281bb045541e857e8/orig",
  "regionId": 213,
  "regionName": "Москва",
  "specs": {
    "Бренд": "Apple",
    "Встроенная память": "128 ГБ",
    "Ёмкость аккумулятора": "3279 мА·ч"
  },
  "specsForVariant": "Смартфон iPhone 15 128 ГБ Черный only eSIM",
  "collectedAt": "2026-08-17T09:41:12.004Z"
}
```

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `market` | choice | `ru` | The market whose published prices you get. This marketplace serves one market publicly, so there is one choice and it is fixed. |
| `productIds` | list of text | — | Product IDs to look up. The ID is the long number at the end of a product page address. |
| `productUrls` | list of text | — | Product page addresses, pasted straight from your browser. |
| `maxOffersPerProduct` | number | `32` | How many seller offers to collect per product, from 1 to 100. |
| `includeSpecs` | true/false | `false` | Attach the product's published specifications to every one of its rows. |
| `productsAtOnce` | number | `3` | How many products to work on simultaneously, from 1 to 8. Higher is faster, lower is gentler. |

Give at least one of `productIds` or `productUrls`. You can mix both; the same
product given twice is looked up once.

### Output fields

| Field | Meaning |
| --- | --- |
| `productId` | The product you asked for. |
| `productTitle` | The product's name on its page. |
| `productUrl` | Address of the product page. |
| `offerId` | The identifier the marketplace uses for this listing. |
| `offerTitle` | The seller's own title for their listing. |
| `offerUrl` | Address that opens this seller's offer. |
| `skuId` | The exact variant this offer is for. |
| `sellerName` | Who is selling it. |
| `sellerId` | The seller's identifier on the marketplace. |
| `sellerRating` | The seller's star rating, as published. |
| `sellerRatingCount` | How many ratings that average is built on. |
| `sellerUrl` | Address of the seller's storefront. |
| `price` | The current price of this offer. |
| `currency` | Currency code of the price. |
| `oldPrice` | The price before the discount, where one is shown. |
| `discountPercent` | The discount percentage, where one is shown. |
| `deliveryText` | The delivery promise shown with the offer, in the source's own wording. |
| `inStock` | Whether the offer has units available. |
| `stockCount` | How many units are shown as available. |
| `isCrossborder` | Whether the item ships from outside the country. |
| `isResale` | Whether the item is pre-owned or refurbished rather than new. |
| `sellerRatingForThisProduct` | The star rating of **this seller's listing of this product**, where published. It is not the product's own rating and not the seller's overall one — the same product listed by four sellers carries four different values, which is why it is named for what it is. |
| `sellerRatingCountForThisProduct` | How many ratings that figure is built on. |
| `imageUrl` | Picture of the item. |
| `regionId` | The market these prices are published for, as reported back by the source. |
| `regionName` | Name of that market. |
| `specs` | The published attributes of **one variant** of the product, when you switched specifications on. The marketplace publishes a single attribute sheet per product, and its sellers list many variants of that product, so the memory, colour and article number on the sheet may belong to a different variant than the offer on the row. |
| `specsForVariant` | Which variant those attributes describe, in the marketplace's own words, so you can always see whether they match the listing on the row. |
| `collectedAt` | When the row was collected. |

Any field the source does not publish for a given offer comes back empty rather
than guessed, so your columns stay stable.

### Pricing

Pay per event. You pay for results, not for run time.

| Event | When you are charged | Price |
| --- | --- | --- |
| Offer collected | For each seller offer written to your results | $0.003 |
| Product specifications added | Once per product, only when you switched specifications on **and** the source publishes them for that product | $0.01 |

**Worked example.** 100 products, up to 32 offers each. If the products average
30 sellers, that is about 3,000 rows — **$9.00**. Switch specifications on and
you add at most **$1.00** for those 100 products. A product that turns out to
have no sellers writes nothing and costs nothing.

### Limits & what this actor cannot do

- **The source publishes a limited number of offers for any one product.** On a
  heavily traded product around 100 distinct seller offers are available; most
  products publish far fewer, and some publish only one. You get what the source
  makes available, not an unlimited seller list, and a product with hundreds of
  sellers will not return all of them. Where the same offer is shown more than
  once, it is written to your results once.
- **Prices are the ones the marketplace publishes for its single public market.**
  There is one market and no city or delivery-area choice, because the source
  does not offer one to the public — asked for a different city, it answers with
  the same prices to the rouble. Every row is stamped with the market the answer
  actually came back for, so you can always see which prices you have.
- **Results are a snapshot at the moment of collection.** Marketplace prices,
  stock and sellers change continuously; two runs an hour apart can legitimately
  disagree.
- **There is no product-level star rating on this view, and none is invented.**
  What the marketplace publishes here is a rating of each seller's own listing
  of the product — the same product listed by four sellers carries four
  different values — so it is reported under a name that says so. For the
  product's own reviews, use the reviews actor.
- **Sellers list their own variants, and the attribute sheet covers one of
  them.** On a product sold in several colours or storage sizes the offers cover
  those variants — `offerTitle` and `skuId` name exactly what each seller is
  selling — but the marketplace publishes a single attribute sheet per product.
  `specsForVariant` names the variant that sheet describes, so you can tell at a
  glance when it is not the one on the row.
- **A specification read that does not complete is reported, not hidden.** The
  column is left empty and the run summary counts it separately from products
  that genuinely publish no attributes, so an empty column is never mistaken for
  an answer.
- **Catalogue-card addresses cannot be used.** They carry a different kind of
  identifier that the source will not resolve to a product. Use the product page
  address, or the product ID. Anything unusable is reported in the run log and
  skipped, never silently dropped.
- **Public information only.** The actor does not sign in, sees nothing behind a
  login, and cannot reveal anything the marketplace keeps private — including
  seller contact details, which are not published.
- **A lookup the source refuses to complete is reported as a failed lookup**,
  never as "no offers found". The run summary counts, separately: products
  collected, products with no sellers, product IDs the source does not recognise,
  products that could not be read, and products whose offer list was only read
  in part — those last ones return real rows, but fewer of them than the source
  holds, and the run says so instead of letting a short list pass for a
  complete one.
- **Speed depends on the size of the job and on how quickly the source answers.**
  No fixed throughput is promised.
- **The source's terms govern automated access.** You are responsible for using
  the data lawfully and in line with those terms, and for handling any personal
  data in line with applicable privacy law, including GDPR and Russian personal
  data law where they apply.

### FAQ

**Do I need an account on the source site?**
No. Nothing is signed in to and nothing is set up.

**Does it need my login or password?**
No. It never asks for credentials of any kind and there is nothing to configure.

**Can I schedule it?**
Yes. Schedule it daily or hourly on Apify and each run writes a fresh, dated set
of rows — which is exactly what you need to chart a competitor's price over time.

**Why do two sellers show different prices for what looks like the same product?**
Because they usually are selling slightly different things — a different colour,
a different storage size, new versus pre-owned, or shipped from abroad. Use
`offerTitle`, `skuId`, `isResale` and `isCrossborder` to tell them apart.

**Why did a product return fewer offers than the page seems to show?**
The marketplace publishes a limited number of offers per product, and its own
"total sellers" figure is an estimate that disagrees with what it will actually
show — in both directions. This actor reports what it genuinely collected and
never repeats that estimate to you.

**Can I get the reviews of a product too?**
Not from this actor. It answers "who sells it and for how much"; reviews are a
different job.

# Actor input Schema

## `market` (type: `string`):

The market whose published prices you get. This marketplace serves one market to the public, so this is fixed — it is shown here so the prices you receive are never in doubt. Every row is also stamped with the market the answer actually came back for.

## `productIds` (type: `array`):

Product IDs to look up, one per line. The ID is the long number at the end of a product page address.

## `productUrls` (type: `array`):

Product page addresses, one per line. Paste them straight from your browser. Catalogue-card addresses are not product pages and are skipped with a note in the log.

## `maxOffersPerProduct` (type: `integer`):

How many seller offers to collect for each product. The source publishes a limited number of offers for any one product, so a very popular product returns what it makes available rather than every seller in existence.

## `includeSpecs` (type: `boolean`):

Attach the product's published specifications to every offer row for that product. Adds a small extra charge per product, and only where the source actually publishes specifications.

## `productsAtOnce` (type: `integer`):

How many products to work on simultaneously. Higher is faster; lower is gentler on the source and more reliable for very large runs.

## Actor input object example

```json
{
  "market": "ru",
  "productIds": [
    "1912483624",
    "5237090406"
  ],
  "productUrls": [
    "https://market.yandex.ru/product--x/1912483624"
  ],
  "maxOffersPerProduct": 32,
  "includeSpecs": false,
  "productsAtOnce": 3
}
```

# Actor output Schema

## `offers` (type: `string`):

Every collected offer, one row per seller offer.

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

The columns a price comparison needs, in reading order.

## `csv` (type: `string`):

Every row, with every column, as a spreadsheet file.

## `summary` (type: `string`):

What was collected, what was empty and what could not be 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 = {
    "market": "ru",
    "productIds": [
        "1912483624"
    ],
    "maxOffersPerProduct": 32,
    "productsAtOnce": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/yandex-market-product-offers-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 = {
    "market": "ru",
    "productIds": ["1912483624"],
    "maxOffersPerProduct": 32,
    "productsAtOnce": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/yandex-market-product-offers-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 '{
  "market": "ru",
  "productIds": [
    "1912483624"
  ],
  "maxOffersPerProduct": 32,
  "productsAtOnce": 3
}' |
apify call apt_marble/yandex-market-product-offers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/yandex-market-product-offers-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/92xLsGWN4eacFOBUg/builds/qlnWkKfhAB2ce8c1D/openapi.json
