# AvtoPro.ua Competitor Price Checker (`climond/avtopro-ua-competitor-price-checker`) Actor

Know what every seller on avtopro.ua charges for the parts you sell. Give it a list of part numbers and get back the lowest price, the average, and every individual offer with the seller's name, rating, delivery time and the country the stock ships from.

- **URL**: https://apify.com/climond/avtopro-ua-competitor-price-checker.md
- **Developed by:** [Mark Slipenkyi](https://apify.com/climond) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 part price checkeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## AvtoPro Competitor Price Checker

Check what your competitors charge on [avtopro.ua](https://avtopro.ua), the Ukrainian auto parts marketplace. Give this Actor a list of part numbers and it returns the lowest price, the average price, how many sellers carry the part, and a full row for every individual offer on the page.

It is built for parts dealers and distributors who need to price a catalogue against the market, and for anyone tracking how competitor pricing moves over time. A run of 10 parts takes two to three minutes.

You do not need a browser, a scraping stack, or a proxy of your own. Paste part numbers, press Start, and export the results as JSON, CSV, or Excel.

### What you get for each part

Every part produces one dataset item containing the headline figures and a nested `listings` array with one entry per competitor offer:

- `lowest_price`, `average_price` and `seller_count` for the exact part code you searched
- `currency`, the unit those prices are quoted in, taken from the page rather than assumed
- `listings`, holding every priced offer on the page: price, brand, new or used, the city it ships from, delivery time in days, warehouse country, and rank in the results
- `boosted`, which flags sellers who paid to rank above where they placed organically
- `url`, a direct link to each individual offer
- `link`, the AvtoPro search page the data came from
- `truncated`, normally false, set true on the rare part with so many offers that the fetch hit its per-part budget before the page ran out of rows. The figures are then a floor rather than the whole market. The busiest part tested, with 633 offers, used under half the budget.

AvtoPro pools the part you searched together with its cross-referenced analogues under identical markup. A search for `03D906051` returns close to 200 rows spanning many part codes, of which 11 are that part. Every row carries an `exact_match` flag so you can tell them apart. The headline prices are calculated from the exact matches only, because averaging a Bosch coil against an NGK equivalent describes the category rather than your competition. The analogues stay in the output if you want to price against them too.

### How to use it

1. Open the Actor and press Start. The input comes prefilled with 10 real part numbers, so you can see the output shape before typing anything.
2. Replace the sample parts with your own codes. Add `maker` where you know it, which helps when a part number is ambiguous.
3. Press Start and wait. Results appear in the Output tab as they arrive.
4. Export as JSON, CSV, or Excel, or pull the dataset from the Apify API.

Runs can be scheduled, so a weekly price check needs no manual work after the first setup.

### Input

```json
{
  "items": [
    {"item_id": "620939134R", "maker": "Renault", "description": "Rear bumper absorber", "origin_price": 950},
    {"item_id": "03D906051", "maker": "VAG", "description": "Ignition coil", "origin_price": 260}
  ],
  "proxyConfiguration": {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}
}
```

`items` is the only required field. `item_id` is the part code as AvtoPro lists it. The other three fields are optional: `description` and `origin_price` pass straight through to the output so you can compare your own price against the market, and `maker` improves search accuracy when a code matches several brands.

`proxyConfiguration` needs a residential proxy. AvtoPro blocks datacenter addresses even at low request rates, so the default is Apify's residential pool. If you have your own provider, choose Custom proxies and paste your URLs instead. You do not need to pin a country, though see the currency note below if you care which one you get.

`maxConcurrency` controls how many parts are fetched at once and defaults to 8. Each part is fetched through its own proxy session, so the parts do not queue behind one address. Pushing it higher gets faster still but starts costing you parts to rate limiting, and lowering it to 2 is the safest setting if you would rather every part came back than have the run finish quickly.

`useBrowser` is off by default and should stay that way. It switches to a slower fallback that drives a real browser, useful only if AvtoPro changes its markup and the fast path starts under-reporting.

### Output

The Output tab opens on the All listings view, which gives one row per competitor offer with the searched part code repeated alongside it. Switch to the Overview view for one row per part with the summary figures. Both views read the same data, and JSON or CSV exports always contain everything regardless of which view you have selected.

A part that could not be fetched carries an `error` field instead of prices, so a single failure never breaks the rest of the run.

### Pricing

You are charged per part checked. Proxy traffic and compute are covered by that price rather than billed to you on top, so a run costs the number of parts you submit multiplied by the rate shown at the top of this page.

Parts that fail are not charged, so a blocked lookup or an unrecognised code costs you nothing.

#### Bigger baskets and repeat runs cost less per part

You pay the same flat rate per part however the run goes, but it is worth knowing what makes a run cheap, because the same 50 parts can cost noticeably less as one job than as fifty.

The first run on a new account registers a throwaway AvtoPro account through a real browser, which is the single most expensive thing this Actor does. That session is then stored and reused, so every later run skips it. On a one-part run it was more than half the total cost; by the second run it is gone entirely.

Beyond that, a bigger basket mostly helps by keeping the run busy. A 50-part basket measured 30% cheaper per part than a 10-part one, and almost all of that came from finishing 50 parts in the time the smaller run took to finish 10, rather than from the basket size itself. One run of 200 parts is meaningfully cheaper than 200 runs of one part; 200 versus 100 makes little difference.

What actually moves the cost is the part itself. A part with a dozen offers is roughly eight times cheaper to check than one with several hundred, because nearly all of the cost is proxy traffic and a busy part means more pages to read. Across 58 real parts the heaviest read 637 offers over 122 requests, comfortably inside the per-part budget, and none came back `truncated`.

### Which AvtoPro sites are supported

`avtopro.ua` is the tested and supported site. `avto.pro` is the same marketplace with a Russian language interface and the same Ukrainian seller inventory, and it works if you point `siteUrl` at it, though it returns the same offers rather than new ones.

The Polish and Spanish sites have their **own Actors**, because they serve a completely different page template, a card feed rather than the seller table this Actor reads. Look for the AvtoPro Poland and AvtoPro Spain Competitor Price Checkers. They return the same figures plus the seller's name and rating, which the Ukrainian site does not publish. `avtopro.pt` needs no Actor of its own: it sells the same stock as `avtopro.es`, from the same sellers, and the Spain Actor reaches it through `siteUrl`. Pointing this Actor's `siteUrl` at any of them will not work.

### Frequently asked questions

#### Is scraping AvtoPro legal?

This Actor reads listing pages that AvtoPro publishes openly. Nothing here sits behind a paywall and no private or personal data is collected, though the Actor does hold a free account so that AvtoPro shows the full seller list rather than the shortened anonymous one (see below). You are responsible for how you use the data, including copyright and database rights in your jurisdiction. If you intend to republish listings rather than use them for internal price analysis, take legal advice first.

#### Why do some parts return more sellers than others?

Because that is what the market looks like. A common Toyota oil filter came back with 204 sellers, while a Renault bumper absorber had nine. The Actor returns whatever the page holds.

#### Why does the Actor create an account on AvtoPro?

AvtoPro caps how many rows an anonymous visitor can see, which quietly hides some sellers. To return complete results, the Actor registers one throwaway account and reuses it across runs. Credentials are generated randomly, never logged, and never written to the dataset.

#### What happens if my proxy gets blocked?

Failed parts come back with a `Blocked` error rather than silently returning partial data. The Actor already retries with a backoff when AvtoPro rate limits it. If blocks persist, switch `proxyConfiguration` to Custom proxies and use your own residential provider.

#### Why is `currency` sometimes not hryvnia?

AvtoPro quotes prices by the visitor's country, so the same part comes back in hryvnia through a Ukrainian exit, dollars through an American one and euros through a German one. A residential proxy pool picks the exit, so the currency can differ between runs without you changing anything.

The Actor reads the currency off the page and reports it in `currency` rather than converting, since no exchange rate here would be the one AvtoPro used. Prices within a single part are always in one currency. If you are tracking a catalogue over time and want hryvnia every run, set `proxyConfiguration` to a Ukrainian residential exit; if you just want the market as AvtoPro shows it, leave the country unset and read `currency` alongside the price.

#### Can I run this from my own code?

Yes. Every Actor on Apify has a REST API and official clients for JavaScript and Python. Start a run, pass the same input, and read the dataset back. The Apify docs cover the call in a few lines.

#### How current is the data?

Every run fetches live pages. Prices reflect the moment the run happened. Sellers edit listings continuously, so two runs minutes apart can legitimately differ by a row or two.

# Actor input Schema

## `items` (type: `array`):

One entry per part: item\_id (AvtoPro's part code, required), description (free text, carried through to output), origin\_price (your own price, carried through for reference), maker (your catalog's brand/make for this part - the strongest signal for picking the right search suggestion when a part code is ambiguous). Example: \[{"item\_id": "620939134R", "description": "Rear bumper absorber", "origin\_price": 950, "maker": "Renault"}] The prefilled basket is 10 real parts, all verified live, deliberately spanning small result sets (15 rows) to large ones (611 rows) - cost per part scales with how many sellers a part has, so a mixed basket is the honest way to see what a run costs. 'origin\_price' is your own price for comparison and is passed through untouched; replace it with real figures.

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

A residential proxy is required: avtopro.ua blocks datacenter addresses even at low request rates. AvtoPro quotes prices in hryvnia, dollars or euros depending on the exit IP's country, and the Actor reports which currency each result came back in rather than assuming one, so any residential exit works. Set the country to UA if you want the figures in hryvnia - the same offers converted, comparable against your own 'origin\_price'. If Apify Proxy gets blocked, switch to Custom proxies and supply your own.

## `siteUrl` (type: `string`):

Defaults to https://avtopro.ua, the only domain this Actor has been proven against. AvtoPro also runs country-specific sites (avto.pro, avtopro.es, avtopro.pl, avtopro.pt) on what looks like the same platform, but their markup, WAF behavior, and login flow are UNTESTED here - pointing this elsewhere is a starting point, not a guarantee.

## `maxConcurrency` (type: `integer`):

How many parts are fetched at once, default 8. Each part gets its own proxy session, so this is I/O-bound rather than memory-bound, and a faster run is also a cheaper one because compute is billed on wall-clock time. Measured on a 50-part basket: concurrency 16 finished in 140s but lost 2 parts of 50 to rate limiting and a dropped connection, so raising this trades a few percent of parts for speed. Lower it to 2 if you would rather have every part than a fast run.

## `useBrowser` (type: `boolean`):

Off by default. The Actor normally fetches over plain HTTP with no browser, which returns identical prices and seller counts (verified against the browser path on four reference parts, same minute) while being ~3.5x faster and ~35% cheaper per part. Turn this on only if AvtoPro changes its markup and the fast path starts under-reporting: it runs the original Playwright fetcher, which renders the page and clicks the expand buttons like a real browser. Measured cost of doing so on a 20-part run at the default 1024MB: 295s and $0.0021/part, versus 86s and $0.0014/part on the fast path. It also drops to 1 concurrent browser at 1024MB, so raise the run's memory to 4096MB if you enable this for a large batch.

## Actor input object example

```json
{
  "items": [
    {
      "item_id": "3D0941295",
      "maker": "VAG",
      "description": "Headlight range control",
      "origin_price": 2600
    },
    {
      "item_id": "850901CA0A",
      "maker": "Nissan",
      "description": "Rear bumper absorber",
      "origin_price": 1300
    },
    {
      "item_id": "620939134R",
      "maker": "Renault",
      "description": "Rear bumper absorber",
      "origin_price": 950
    },
    {
      "item_id": "55593189",
      "maker": "Opel",
      "description": "Oil filter",
      "origin_price": 590
    },
    {
      "item_id": "03D906051",
      "maker": "VAG",
      "description": "Ignition coil",
      "origin_price": 260
    },
    {
      "item_id": "263203C100",
      "maker": "Hyundai",
      "description": "Oil filter",
      "origin_price": 170
    },
    {
      "item_id": "A2711800009",
      "maker": "Mercedes",
      "description": "Oil filter",
      "origin_price": 560
    },
    {
      "item_id": "11427566327",
      "maker": "BMW",
      "description": "Oil filter",
      "origin_price": 490
    },
    {
      "item_id": "04152YZZA1",
      "maker": "Toyota",
      "description": "Oil filter",
      "origin_price": 140
    },
    {
      "item_id": "8200768913",
      "maker": "Renault",
      "description": "Oil filter",
      "origin_price": 210
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "siteUrl": "https://avtopro.ua",
  "useBrowser": false
}
```

# Actor output Schema

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

One record per part: lowest\_price, average\_price and seller\_count for the exact part code, the currency those figures are quoted in, and a nested 'listings' array with one entry per competitor offer on the page (price, brand, new or used, delivery city and days, warehouse country, paid-placement flag, and a direct link to each offer). Analogues AvtoPro cross-references to the part ship in 'listings' too, marked exact\_match: false, and are excluded from the headline figures. A part that could not be fetched carries an 'error' field instead of prices.

# 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 = {
    "items": [
        {
            "item_id": "3D0941295",
            "maker": "VAG",
            "description": "Headlight range control",
            "origin_price": 2600
        },
        {
            "item_id": "850901CA0A",
            "maker": "Nissan",
            "description": "Rear bumper absorber",
            "origin_price": 1300
        },
        {
            "item_id": "620939134R",
            "maker": "Renault",
            "description": "Rear bumper absorber",
            "origin_price": 950
        },
        {
            "item_id": "55593189",
            "maker": "Opel",
            "description": "Oil filter",
            "origin_price": 590
        },
        {
            "item_id": "03D906051",
            "maker": "VAG",
            "description": "Ignition coil",
            "origin_price": 260
        },
        {
            "item_id": "263203C100",
            "maker": "Hyundai",
            "description": "Oil filter",
            "origin_price": 170
        },
        {
            "item_id": "A2711800009",
            "maker": "Mercedes",
            "description": "Oil filter",
            "origin_price": 560
        },
        {
            "item_id": "11427566327",
            "maker": "BMW",
            "description": "Oil filter",
            "origin_price": 490
        },
        {
            "item_id": "04152YZZA1",
            "maker": "Toyota",
            "description": "Oil filter",
            "origin_price": 140
        },
        {
            "item_id": "8200768913",
            "maker": "Renault",
            "description": "Oil filter",
            "origin_price": 210
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("climond/avtopro-ua-competitor-price-checker").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 = {
    "items": [
        {
            "item_id": "3D0941295",
            "maker": "VAG",
            "description": "Headlight range control",
            "origin_price": 2600,
        },
        {
            "item_id": "850901CA0A",
            "maker": "Nissan",
            "description": "Rear bumper absorber",
            "origin_price": 1300,
        },
        {
            "item_id": "620939134R",
            "maker": "Renault",
            "description": "Rear bumper absorber",
            "origin_price": 950,
        },
        {
            "item_id": "55593189",
            "maker": "Opel",
            "description": "Oil filter",
            "origin_price": 590,
        },
        {
            "item_id": "03D906051",
            "maker": "VAG",
            "description": "Ignition coil",
            "origin_price": 260,
        },
        {
            "item_id": "263203C100",
            "maker": "Hyundai",
            "description": "Oil filter",
            "origin_price": 170,
        },
        {
            "item_id": "A2711800009",
            "maker": "Mercedes",
            "description": "Oil filter",
            "origin_price": 560,
        },
        {
            "item_id": "11427566327",
            "maker": "BMW",
            "description": "Oil filter",
            "origin_price": 490,
        },
        {
            "item_id": "04152YZZA1",
            "maker": "Toyota",
            "description": "Oil filter",
            "origin_price": 140,
        },
        {
            "item_id": "8200768913",
            "maker": "Renault",
            "description": "Oil filter",
            "origin_price": 210,
        },
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("climond/avtopro-ua-competitor-price-checker").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 '{
  "items": [
    {
      "item_id": "3D0941295",
      "maker": "VAG",
      "description": "Headlight range control",
      "origin_price": 2600
    },
    {
      "item_id": "850901CA0A",
      "maker": "Nissan",
      "description": "Rear bumper absorber",
      "origin_price": 1300
    },
    {
      "item_id": "620939134R",
      "maker": "Renault",
      "description": "Rear bumper absorber",
      "origin_price": 950
    },
    {
      "item_id": "55593189",
      "maker": "Opel",
      "description": "Oil filter",
      "origin_price": 590
    },
    {
      "item_id": "03D906051",
      "maker": "VAG",
      "description": "Ignition coil",
      "origin_price": 260
    },
    {
      "item_id": "263203C100",
      "maker": "Hyundai",
      "description": "Oil filter",
      "origin_price": 170
    },
    {
      "item_id": "A2711800009",
      "maker": "Mercedes",
      "description": "Oil filter",
      "origin_price": 560
    },
    {
      "item_id": "11427566327",
      "maker": "BMW",
      "description": "Oil filter",
      "origin_price": 490
    },
    {
      "item_id": "04152YZZA1",
      "maker": "Toyota",
      "description": "Oil filter",
      "origin_price": 140
    },
    {
      "item_id": "8200768913",
      "maker": "Renault",
      "description": "Oil filter",
      "origin_price": 210
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call climond/avtopro-ua-competitor-price-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,climond/avtopro-ua-competitor-price-checker"
        }
    }
}

```

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/aDUCM1DIAMdx7dBeF/builds/m3RmbVQaNDFtlCsVz/openapi.json
