# Avito Scraper - Avito.ru Listings, Prices, Sellers & Rentals (`s-r/avito-scraper`) Actor

Avito scraper for avito.ru: search by keyword, city, category or URL and get every ad as a row with title, price in roubles, private or business seller, location, coordinates and photos. For price research, dealer monitoring and rental tracking across Russia. No login or API key.

- **URL**: https://apify.com/s-r/avito-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** E-commerce, Real estate, Automation
- **Features:** Limited permissions
- **Stats:** 19 total users, 10 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.50 / 1,000 avito listings

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?

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

## Avito Scraper - listings, prices and sellers from Russia's biggest classifieds site

This Avito scraper exports listings from avito.ru by search term, category, city
or URL, and gives you the title, the asking price in roubles, the seller type,
the location with coordinates and the full photo set as clean rows in JSON, CSV
or Excel. It reads the same result pages a shopper sees, so an Avito price
tracker built on it sees what buyers see rather than what an API decides to
publish. Use it for price research, dealer monitoring and rental tracking across
Russia, without an account, cookies or an Avito API key.

### What you get

- Up to 50 listings per search page, paged automatically until your row limit
- Listing id, title and canonical URL with Avito's tracking query stripped off
- Asking price as a number in roubles plus the price exactly as printed, the
  struck-through price and the discount percentage when a seller is cutting
- City or region, the finer address line Avito prints, and latitude and
  longitude for every advert that carries them
- Private-seller versus business flag, verified flag and reserved flag
- Every photo at the widest size Avito serves, plus the photo count
- Category name and category slug, so a result row feeds straight back in as the
  input of a narrower run
- On rows read from a listing URL: the full advert text, the seller name,
  availability, new-or-used condition and the category breadcrumb path
- A run summary that separates "this search found nothing" from "the site did
  not serve us", because in a dataset those two look identical and mean
  completely different things

### Why scrape Avito with an Avito scraper

Avito is the default second-hand and small-business marketplace in Russia, and
for most categories it is the only price signal that exists at scale. There is
no public Avito API for listing data. The official developer programme is aimed
at sellers managing their own adverts, not at anyone who wants to see the market,
so pricing research, competitor monitoring and supply tracking all come down to
reading the site.

That matters more on classifieds than on a retail catalogue. A retailer publishes
one price per product. Avito publishes a distribution: the same phone model is
listed forty times at forty prices, by private sellers and by shops, in cities
with very different price levels. The useful number is not any single advert, it
is the spread and how it moves, and you only get that by collecting the whole
result page and paging through it.

The rental side works the same way. Avito carries a very large share of Russian
long-term and short-term rental supply, and category and city slugs let you pull
one neighbourhood's flats the same way you would pull one model of phone. Because
every row carries coordinates when the advert has them, rental and vehicle data
map directly without a geocoding step.

### Avito Scraper input

| Field | Type | Required | What it does |
|---|---|---|---|
| `query` | string | no | What to search for, Russian or Latin script |
| `location` | string | no | City or region slug from an Avito URL, `all` for the whole country |
| `category` | string | no | Category slug, for example `telefony`, `kvartiry`, `avtomobili` |
| `searchUrls` | array | no | Full Avito search URLs, used instead of the fields above |
| `listingUrls` | array | no | Individual advert URLs to read one at a time |
| `priceMin` | integer | no | Lowest price in roubles |
| `priceMax` | integer | no | Highest price in roubles |
| `sort` | select | no | Relevance, newest first, cheapest first, most expensive first |
| `sellerType` | select | no | Any seller, private only, or companies only |
| `onlyWithPhoto` | boolean | no | Skip adverts with no photograph |
| `maxItems` | integer | no | Stop after this many listings, default 50 |

The slugs are the ones in Avito's own URLs. If a browser shows you
`avito.ru/moskva/telefony`, then `moskva` is the location and `telefony` is the
category. If you would rather not think about slugs at all, paste the whole
search URL into `searchUrls` and every filter you set in the browser is kept.

### Output

The following is a real response fetched on 5 October 2026.

```json
{
  "id": "7924194781",
  "title": "iPhone 13, 256 ГБ, SIM + eSIM",
  "url": "https://www.avito.ru/moskva/telefony/iphone_13_256_gb_sim_esim_7924194781",
  "price": 28900,
  "price_text": "28 900 ₽",
  "price_without_discount": null,
  "discount_percent": null,
  "currency": "RUB",
  "category": "Телефоны",
  "category_slug": "telefony",
  "region": null,
  "address": "",
  "latitude": null,
  "longitude": null,
  "is_company": null,
  "is_verified": false,
  "is_reserved": false,
  "images": [
    "https://80.img.avito.st/image/1/1.E5ZfjraAv38RJEV0dfY_xmguvXvtObt_7V7ee-3VtIXgLbtlESRFdOk.Dj5UfLmGDvhCmTzUI0P_e1vij53ez4ZSxtP6YR-A_Fc",
    "https://b40.img.avito.st/image/1/1.KW_BLbaAhYaPh3-Nn1kmOvaNh4JzmoGGc_3kgnN2jnx-joGcj4d_jXc.2ACzlMb_hfDGXzaI1ttRpNa4Xt-rZckvtULGYAINPM0",
    "https://20.img.avito.st/image/1/1.FOQLgLaAuA1FKkIGL9g1tDwgugm5N7wNuVDZCbnbs_e0I7wXRSpCBr0.DCo7-MnjnjR3J-nn7kg4NsuHGvbIVU4lNG_w0_uQl6A?cqp=2.2LhnDdKx1gU5sZ7QAbwhSdJoeYt5K_KL9JwGcCXpGrDVbBxJ1yJf9Jn7hY3rGWaiHtSha9zz1w==",
    "https://90.img.avito.st/image/1/1.4wgzfraAT-F91LXqeRHlXQTeTeWByUvhga4u5YElRBuM3Uv7fdS16oU.LOJ0PaQGpA2LdivwOPFoxKjBAiwmyULoJAcUI_5GfY4",
    "https://90.img.avito.st/image/1/1.BFcBgLaAqL5PKlK1BfQNATYgqrqzN6y-s1DJurPbo0S-I6ykTypStbc.Gr7C25mzmHIXkWeQi9HDhTWyt0w7cp8KvLByZmraNOc"
  ],
  "image_count": 7,
  "attributes": [],
  "listed_at_ms": 1788937729000,
  "found": true,
  "blocked": false,
  "listing_id": "7924194781",
  "image_url": "https://80.img.avito.st/image/1/1.E5ZfjraAv38RJEV0dfY_xmguvXvtObt_7V7ee-3VtIXgLbtlESRFdOk.Dj5UfLmGDvhCmTzUI0P_e1vij53ez4ZSxtP6YR-A_Fc",
  "source": "avito-scraper",
  "country": "RU",
  "fetched_at": "2026-10-05T01:32:57.916Z",
  "position": 1
}
```

Rows read from `listingUrls` include `description`, `seller`, `availability`,
`condition` and `breadcrumbs`. Search-only fields such as coordinates are not
present on detail rows. `latitude` and `longitude` remain strings on search
rows; `price` is numeric and `id` remains a string or null. Each row also
includes `listing_id`, `source`, `country`, `fetched_at` and its `position`.

### Use cases for the Avito scraper

**Price research before you buy or list.** If you are pricing stock to sell on
Avito, the question is never "what is this worth" but "what is the tenth-cheapest
comparable advert asking today". Pull one category in one city sorted by price,
take the distribution, and you have a listing price that will actually move.
Run it weekly and you have the trend, which is the part a single lookup on the
site can never give you.

**Competitor and dealer monitoring.** The seller-type filter splits genuine
second-hand supply from business inventory in one input. Electronics resellers,
car dealers and furniture shops all list on Avito under business accounts, so
restricting a category to companies gives you a clean view of who is stocking
what, at what price, in which cities, without the noise of private adverts.

**Rental and property tracking.** Property analysts use Avito the way their
western counterparts use portals that publish an API. Category and city slugs
narrow a run to one neighbourhood, newest-first sorting turns it into a feed of
new supply, and the coordinates on each row drop straight onto a map. Because
listings disappear when they let, tracking the same search over time also tells
you how fast stock is moving.

**Sourcing and arbitrage.** Regional price gaps on Avito are real and large. The
same item is routinely cheaper several time zones away from Moscow. Running one
query across several city slugs and comparing the medians is a spread report you
can act on, and the rows carry everything you need to contact the seller.

### Avito Scraper vs. the Avito API and DIY parsers

There are three other ways to get Avito data, and each one stops short of a
market view.

| Option | What you get | Where it stops |
|---|---|---|
| Copying adverts by hand | Exactly what is on screen | A few dozen adverts before it becomes a job; no history |
| Avito's official API for sellers | Your own adverts, statistics and messages | No access to other sellers' listings, so no market prices |
| An open-source Avito parser from GitHub | Full control over the code | You maintain it every time the page changes, and you handle refused reads and paging yourself |
| This Avito scraper | Every listing of a search as a row, paged and de-duplicated, with a run summary | Russia only (avito.ru), and only what Avito shows publicly |

If you already run your own парсер Авито (Avito parser), the output here is a
drop-in replacement: one row per advert with stable field names, so the step from
"it broke again" to "it runs every morning" is an input form rather than a
rewrite. Because the actor runs on Apify, you can schedule it, call it through the
Apify API from Python or JavaScript, and push the results to Google Sheets,
a webhook or your own database with the integrations Apify already offers.

### How to scrape Avito in three steps

1. Open Avito in your browser and set up the search you want: city, category,
   price range, sort order. Copy the URL from the address bar.
2. Paste that URL into `searchUrls`, or fill in `query`, `location` and
   `category` instead, and set `maxItems` to the number of listings you need.
3. Start the run and download the dataset as JSON, CSV or Excel, or read it
   through the API. Schedule the same input daily to build a price history.

### Pricing

There is no start fee. Empty searches, refused reads and removed listings are
free. Only rows with `found: true` are billed.

Billing is pay-per-event at $0.0035 per listing delivered. A refused read costs
nothing: if the site does not serve us, you get a row saying so and no charge for
it. All pricing is pay-per-event — you only pay for results you receive. No
actor-start fee, no per-compute-unit charges.

### Limits and gotchas

- Avito serves Russia. Prices are in roubles and there is no other currency.
- One search page holds 50 listings. A `maxItems` of 500 is ten pages, and each
  page is a separate request, so a large run takes minutes rather than seconds.
- Avito's result ordering is not stable between requests. Two runs of the same
  search minutes apart can return the same listings in a different order, and a
  small number of adverts may appear on the boundary between two pages. Rows are
  de-duplicated by listing id within a run.
- `priceMin`, `priceMax`, `sort`, `sellerType` and `onlyWithPhoto` apply to the
  search-term path. If you paste a URL into `searchUrls`, whatever is in that URL
  wins, which is the point of pasting it.
- Advert text, seller name and condition are only on the listing page, so they
  appear on rows produced from `listingUrls`, not on search rows.
- Some adverts name no price at all. Those rows arrive with `price` empty rather
  than zero, so that a missing price is never mistaken for a free item.
- The site refuses some requests. The actor retries, and if every attempt is
  refused you get a row with `blocked` set and the run summary says
  `siteRefusedUs`. Treat that as "come back later", not as "no such listings".

### FAQ

**What happens when I provide only listing URLs?**
Only those adverts are read. The default location does not add an unrelated
recommendation feed. If you also provide a query or search URLs, search results
use the shared row budget first and listing URLs use the remainder.

**How do large searches work?**
Set `maxItems` between 1 and 2,000. The actor follows result pages automatically
and de-duplicates listing ids across them. Non-paying Apify users receive at
most ten rows per run. A genuinely empty search returns no dataset rows and
its run completes successfully. Removed listing URLs can return a free
diagnostic row with `found: false` and `blocked: false`.

**Can I scrape Avito without an API key?**
Yes. There is no public Avito API for listing data, and this actor needs no key,
no account and no cookies from you. You give it a search and it returns rows.

**How do I get Avito listings for a specific city?**
Put the city slug from an Avito URL into `location`, for example `moskva`,
`sankt-peterburg` or `novosibirsk`. Use `all` to search the whole country, which
is the default.

**Can I scrape Avito rental and property listings?**
Yes. Use the property category slug, for example `kvartiry`, together with a city
slug. Every row carries coordinates when the advert has them, so rental data maps
without a separate geocoding step.

**How do I filter Avito results by price?**
Set `priceMin` and `priceMax` in roubles. They are applied by Avito itself as
part of the search rather than after the fact, so paging stays efficient.

**Is there an official Avito API for listing data?**
Avito's developer portal serves sellers managing their own adverts: posting,
statistics, messages. It does not return other sellers' listings, so it cannot
answer "what does this item sell for". This Avito scraper fills that gap and is
itself an API: start a run over the Apify API and fetch the rows as JSON.

**Can I export Avito listings to CSV or Excel?**
Yes. Every run stores its rows in an Apify dataset that downloads as JSON, CSV,
Excel, XML or HTML, and the same data is available through the API.

**Does it work for Avito Morocco (avito.ma)?**
No. This actor reads avito.ru only. Prices are always in roubles.

**Why did my Avito run return no listings?**
Check the run summary. `emptySearch` true means the search genuinely matched
nothing, usually a typo in a slug. `siteRefusedUs` true means the site did not
serve the result set on that run and the same search is worth re-running.

### Related Actors

- [Kaufland Scraper](https://apify.com/s-r/kaufland-scraper)
- [eBay Scraper](https://apify.com/s-r/ebay-scraper)
- [Naver Map Scraper](https://apify.com/s-r/naver-map-scraper)

# Actor input Schema

## `query` (type: `string`):

What to search for on Avito, in Russian or in Latin letters. Combined with the city and category below into one search. Leave empty if you are pasting your own search URLs instead.

## `location` (type: `string`):

The city or region slug exactly as it appears in an Avito URL, for example 'moskva', 'sankt-peterburg' or 'kaliningrad'. Use 'all' to search the whole of Russia.

## `category` (type: `string`):

The category slug from an Avito URL, for example 'telefony' for phones, 'kvartiry' for flats or 'avtomobili' for cars. Leave empty to search every category.

## `searchUrls` (type: `array`):

Full Avito search or category URLs to read, pasted straight from the browser. Anything here is used instead of the search term, city and category above, so your own filters are kept exactly as you set them.

## `listingUrls` (type: `array`):

Individual Avito listing URLs to read one by one. Use this when you already know which adverts you want rather than searching for them.

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

Lowest price to include, in roubles. Applies to the search term path, not to search URLs you paste yourself.

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

Highest price to include, in roubles. Applies to the search term path, not to search URLs you paste yourself.

## `sort` (type: `string`):

How Avito should order the results before we read them. Newest first is the one to use for monitoring a category over time.

## `sellerType` (type: `string`):

Restrict the search to private adverts or to business adverts. Useful for separating genuine second-hand supply from dealer inventory.

## `onlyWithPhoto` (type: `boolean`):

Skip adverts that carry no photograph. Photoless adverts on classifieds sites are disproportionately stale or placeholder listings.

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

Stop after this many listings. Avito returns 50 per page, so 200 is four pages. Free-plan runs are capped at 10 rows regardless of this number.

## `cursor` (type: `string`):

Opaque continuation token returned as next_cursor. Keep all other input fields unchanged.

## Actor input object example

```json
{
  "query": "iphone",
  "location": "all",
  "sort": "relevance",
  "sellerType": "any",
  "onlyWithPhoto": false,
  "maxItems": 50
}
```

# Actor output Schema

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

One row per listing.

## `output` (type: `string`):

Counts, whether the search was genuinely empty or we were refused, and whether a proxy was configured.

## `errors` (type: `string`):

Refused reads and input problems.

# 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": "iphone"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/avito-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": "iphone" }

# Run the Actor and wait for it to finish
run = client.actor("s-r/avito-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 '{
  "query": "iphone"
}' |
apify call s-r/avito-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/avito-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/8dHI2sD0absTwREAp/builds/j8Sfb3EkIYB4YwlLt/openapi.json
