# Prom.ua Product Search Scraper (`xmolodtsov/prom-ua`) Actor

Scrape Prom.ua search results without a browser or proxy. Each product returns URL, title, regular and discounted price in UAH, image, seller name, seller store URL, stock status and search rank. Sort by price, filter by price range or review quality. $2.00 per 1,000 products.

- **URL**: https://apify.com/xmolodtsov/prom-ua.md
- **Developed by:** [Yevhenii Molodtsov](https://apify.com/xmolodtsov) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 prom.ua products

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/platform/actors/running/actors-in-store#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

## Prom.ua Product Search Scraper (Pay Per Result)

Search [Prom.ua](https://prom.ua) — Ukraine's largest e-commerce marketplace, 100M+ product
listings — and get every result back as a clean row: product URL, title, regular and
discounted price in UAH, image, seller name, seller store URL, stock status and search
position. No browser, no proxy, no login. You pay only per product returned.

**100 products in 31 seconds, $2.00 per 1,000 products.**

Built for Ukraine e-commerce data work: competitor price tracking, product price monitoring
across Ukrainian sellers, assortment and catalogue research, and marketplace stock checks.

### Why this scraper

| | This scraper | Other prom.ua actors on Apify Store |
| --- | --- | --- |
| Price per 1,000 products | **$2.00** | $2.00 – $15.00 |
| Input | Any keyword — no URLs needed | Category or product URLs you must already have |
| Search rank per product | Yes (`position` field) | No — they don't run searches |

- 💸 **$2.00 per 1,000 products, no monthly fee.** You pay for results, not for a
  subscription or for runtime.
- 🪶 **Plain HTTP, no browser.** The actor reads the search page's Apollo GraphQL cache
  instead of rendering it, which is why a 100-product run costs about $0.004 of Apify
  platform usage at the default 1 GB memory.
- 🔍 **29 products per search page** come out of the Apollo cache — roughly 3x what the page
  renders in the DOM — so fewer requests are needed per 1,000 products.
- 🌐 **No proxy required.** Verified working straight from Apify datacenter IPs with
  `use_apify_proxy` off. No login and no cookies either.
- 🇺🇦 **Ukrainian and English keywords** both work (`ноутбуки`, `жіночі сумки`, `smartphone`).
- ↕️ **Server-side sorting and price filters** — `price_asc`, `price_desc`, `min_price`,
  `max_price` are applied by Prom.ua across the whole result set, not sorted client-side
  after the fact.
- 🚨 **Fails loudly instead of returning nothing.** An unfiltered search that extracts 0
  products FAILS the run — a green run with an empty dataset can never quietly poison your
  pipeline.

### Quickstart

1. Open the actor in Apify Console and type your keyword into **Search term**
   (Ukrainian/Cyrillic or English).
2. Set **Maximum items** — how many products to collect (1–1000).
3. Click **Start**, then export the dataset as JSON, CSV, Excel, XML or JSONL.

```json
{
    "search_term": "ноутбуки",
    "max_items": 100
}
```

A price-tracking run — cheapest offers in a band, sorted by price:

```json
{
    "search_term": "ноутбуки",
    "max_items": 200,
    "sort_option": "price_asc",
    "min_price": 10000,
    "max_price": 50000
}
```

### Input parameters

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `search_term` | string | **required** | The keyword to search on Prom.ua. Ukrainian/Cyrillic or English, e.g. `ноутбуки`, `жіночі сумки`, `smartphone`. One search term per run. |
| `max_items` | integer | `10` | How many products to collect, `1`–`1000`. Pagination is automatic; `1000` is the per-run maximum. |
| `sort_option` | string | `"default"` | `default`, `price_asc` (cheapest first), `price_desc` (most expensive first), or `relevance`. Applied server-side by Prom.ua. |
| `min_price` | integer | — | Minimum price in UAH. Server-side filter. |
| `max_price` | integer | — | Maximum price in UAH. Server-side filter. |
| `use_apify_proxy` | boolean | `false` | Optional and normally unnecessary — scraping is verified working with no proxy. |
| `media_only` | boolean | `false` | Only products whose customer reviews include photos or videos. Narrow filter — can legitimately return few or zero products. |
| `good_ratings_only` | boolean | `false` | Only products rated 4★ and above. If `media_only` is also on, `media_only` wins. |
| `debug_mode` | boolean | `false` | Verbose logging for troubleshooting. Leave off for normal runs. |

### Output

One dataset item per product, with exactly these 10 fields — all of them always present:

```json
{
    "url": "https://prom.ua/ua/p3117734131-noutbuk-acer-nitro.html",
    "title": "Ноутбук Б/В Acer Nitro AN515-51:15.6 Full HD, Core i5-7300HQ,16GB DDR4,GTX 1050 2Gb,SSD 512Gb",
    "regular_price_uah": 14200.0,
    "discounted_price_uah": 13490.0,
    "currency": "UAH",
    "image_url": "https://images.prom.ua/7546062934_w400_h400_noutbuk-bv-acer.jpg",
    "seller_name": "IT Teh\"Nika\"",
    "seller_url": "https://prom.ua/ua/c3831977-tehnika.html",
    "in_stock": true,
    "position": 1
}
```

| Field | Type | Description |
| --- | --- | --- |
| `url` | string | Working product page URL (`https://prom.ua/ua/p{id}-{slug}.html`). |
| `title` | string | Product title as listed, in its original language. |
| `regular_price_uah` | float | List price in Ukrainian hryvnia. |
| `discounted_price_uah` | float | null | Sale price in UAH, or `null` when the product is not discounted. |
| `currency` | string | Always `"UAH"`. |
| `image_url` | string | Product image on the Prom.ua CDN (400x400). |
| `seller_name` | string | Seller / company name. |
| `seller_url` | string | Working seller store page URL. |
| `in_stock` | boolean | Availability as shown in the search results. |
| `position` | integer | 1-based rank in the search results — the field to diff between runs for ranking and share-of-shelf tracking. |

A product whose URL cannot be built is dropped from the dataset rather than emitted with an
empty `url`, so every row you are billed for links to a real page.

### What this scraper does not return

This is a **search-results** scraper. It reads what the Prom.ua search page carries and does
not open individual product pages, so:

- ❌ **No product descriptions and no specifications** — those live on the product page.
- ❌ **No review texts or review counts.** `media_only` and `good_ratings_only` filter *by*
  review properties, but review content itself is not returned.
- ❌ **No seller phone numbers or contact details.**
- ❌ **One `search_term` per run.** For several keywords, start several runs (that also keeps
  each dataset cleanly scoped to one term).
- ❌ **Maximum 1,000 products per search term** per run.
- ℹ️ Prices are exactly what the search page shows, in UAH.

Use `url` and `seller_url` from the output as input to a product-page scraper if you need the
deeper fields.

### Pricing: what counts as a result

**$0.002 per dataset item — $2.00 per 1,000 products.** Every product pushed to the dataset
is one paid result. No monthly fee.

| Run | Actor cost | Apify platform usage | Total |
| --- | --- | --- | --- |
| 100 products | $0.20 | ~$0.01 | ~$0.21 |
| 1,000 products | $2.00 | ~$0.02 | ~$2.02 |

Apify platform usage (compute, storage, transfer) is billed separately by Apify at their
standard rates. This actor is very light on it — a measured 100-product run used $0.004 and
finished in 31 seconds at the default 1 GB memory.

### Run status contract

- **SUCCEEDED** — items were delivered. With `media_only`, `good_ratings_only` or price
  bounds set, **0 results is a legitimate SUCCEEDED outcome**: the filter simply matched
  nothing.
- **FAILED**, with `0 products extracted` in the log — an *unfiltered* search returned
  nothing, which means Prom.ua changed its markup or blocked the request. The run never goes
  green with an empty dataset. Report it and we fix it fast.

Automated callers can treat SUCCEEDED as "the dataset is authoritative" and retry or alert on
FAILED.

### Integrations

Run via API with curl:

```bash
curl -X POST "https://api.apify.com/v2/acts/xmolodtsov~prom-ua/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"search_term": "ноутбуки", "max_items": 100, "sort_option": "price_asc"}'
```

With the Apify JavaScript client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('xmolodtsov/prom-ua').call({
    search_term: 'ноутбуки',
    max_items: 100,
    sort_option: 'price_asc',
    min_price: 10000,
    max_price: 50000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

With the Apify Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("xmolodtsov/prom-ua").call(run_input={
    "search_term": "жіночі сумки",
    "max_items": 200,
    "sort_option": "price_desc",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["position"], item["title"], item["regular_price_uah"])
```

Datasets export to **JSON, CSV, Excel, XML, JSONL, RSS and HTML** from Console or API. Use
[Apify Schedules](https://docs.apify.com/platform/schedules) to re-run the same keyword daily
for price monitoring, and webhooks to push each finished run into your own pipeline.

### FAQ

**Do I need a proxy?**
No. Runs are verified working from Apify datacenter IPs with `use_apify_proxy` off. The
option exists if you want it, but leaving it off is normal and cheaper.

**Can I scrape several keywords in one run?**
No — one `search_term` per run. Start one run per keyword (schedules and the API make this
trivial), which also keeps each dataset scoped to a single term.

**How do I track prices over time?**
Schedule the same input daily and diff on `url`: `regular_price_uah`, `discounted_price_uah`
and `in_stock` give you price and stock history, and `position` gives you ranking history for
competitor price tracking.

**Why did my run return 0 products and still succeed?**
You used a filter — `media_only`, `good_ratings_only`, `min_price` or `max_price`. Those can
legitimately match nothing, especially `media_only`, which requires customer reviews with
photos or videos. An *unfiltered* search that returns 0 products fails the run instead.

**Does sorting really sort the whole result set?**
Yes — sorting is applied server-side by Prom.ua. Verified: `price_asc` returned products
ascending from 4.65 UAH, `price_desc` descending from 20,746 UAH.

**Where are product descriptions and specs?**
Not included — this scraper reads search results only. See
[What this scraper does not return](#what-this-scraper-does-not-return).

**Is this legal?**
The actor collects only publicly available marketplace listings — no login, no private data.
You are responsible for using the data in compliance with Prom.ua's terms and applicable law.

# Actor input Schema

## `search_term` (type: `string`):

The keyword to search for on Prom.ua. Ukrainian/Cyrillic or English both work (e.g. 'ноутбуки', 'жіночі сумки', 'laptop', 'smartphone'). One search term per run — start a separate run for each additional keyword.

## `max_items` (type: `integer`):

How many products to collect for this search term. Pagination is automatic; 1000 is the maximum per run. You are billed per product returned.

## `sort_option` (type: `string`):

Sort order applied by Prom.ua across the whole result set before products are collected — not a client-side re-sort of one page.

## `min_price` (type: `integer`):

Minimum price in Ukrainian hryvnia. Applied by Prom.ua as a server-side filter; leave empty for no lower bound.

## `max_price` (type: `integer`):

Maximum price in Ukrainian hryvnia. Applied by Prom.ua as a server-side filter; leave empty for no upper bound.

## `use_apify_proxy` (type: `boolean`):

Optional and normally unnecessary — Prom.ua is scraped over plain HTTP and is verified working without a proxy. Enable only if you specifically want requests routed through Apify Proxy.

## `media_only` (type: `boolean`):

Only return products whose customer reviews include photos or videos. This is a narrow filter — it can legitimately return few or zero products.

## `good_ratings_only` (type: `boolean`):

Only return products rated 4 stars and above. If 'Products with Media Only' is also enabled, that filter takes priority.

## `debug_mode` (type: `boolean`):

Verbose logging for troubleshooting extraction and position validation. Leave off for normal runs.

## Actor input object example

```json
{
  "search_term": "ноутбуки",
  "max_items": 50,
  "sort_option": "default",
  "min_price": 1000,
  "max_price": 50000,
  "use_apify_proxy": false,
  "media_only": false,
  "good_ratings_only": false,
  "debug_mode": false
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("xmolodtsov/prom-ua").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("xmolodtsov/prom-ua").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 '{}' |
apify call xmolodtsov/prom-ua --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xmolodtsov/prom-ua"
        }
    }
}

```

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/YDMrrkSjAbocUS0FM/builds/iDQ2QkkntvCJahsnl/openapi.json
