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

Scrape Prom.ua product search results for any keyword: product URL, title, regular and sale price in UAH, image, seller name and store URL, stock status and search rank. Sort by price, filter by price range or review quality. No browser, proxy or login. Pay only per product.

- **URL**: https://apify.com/xmolodtsov/prom-ua.md
- **Developed by:** [GoFetch](https://apify.com/xmolodtsov) (community)
- **Categories:** E-commerce, Automation
- **Features:** Limited permissions
- **Stats:** 11 total users, 6 monthly users, 97.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

![Prom.ua Product Search Scraper logo](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/prom-ua-avatar-128)

Prom.ua Product Search Scraper returns Prom.ua search results as clean product rows: **product URL, title,
regular and discounted price in UAH, image, seller name, seller store URL, stock status and search position**.
Type any keyword, in Ukrainian or English, and get up to 1,000 search results per run from one of
Ukraine's largest online marketplaces. No browser, no proxy, no login, and you pay only per product returned (see [Pricing](#pricing)).

Works from a plain keyword, so you don't need category or product URLs in advance. Sorting by price and
price-range filters are applied by Prom.ua itself across the whole result set.

### Use cases

- **Repricing for an online store:** a Ukrainian electronics shop runs its top keywords every morning with
  `sort_option: "price_asc"` and feeds the cheapest competing offers and their stock status into its repricing sheet.
- **Brand share of shelf:** a brand manager runs the category keyword weekly and tracks how many of the top 100
  `position`s carry the brand's products, and which sellers hold them.
- **Assortment research before a launch:** a seller entering a category pulls 1,000 results for the keyword, groups
  them by `seller_name` and price band, and sees who sells what at which price.
- **Price monitoring:** a market analyst schedules the same price-band search daily and matches items on `url` to
  build regular-price, sale-price and stock history.

### What data you get

One dataset item per product, with these 10 fields:

- **Product:** `url` (a working product page link), `title` (as listed, in its original language),
  `image_url` (400×400 image on the Prom.ua CDN).
- **Price:** `regular_price_uah`, `discounted_price_uah` (`null` when the product isn't on sale) and
  `currency` (always `"UAH"`).
- **Seller:** `seller_name` and `seller_url` (the seller's store page on Prom.ua).
- **Availability and rank:** `in_stock` and `position`, the 1-based rank in the search results.

#### Not included

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 or specifications; those live on the product page.
- No review texts or review counts. `media_only` and `good_ratings_only` filter by review properties, but
  the reviews themselves are not returned.
- No seller phone numbers or contact details.
- One `search_term` per run and at most 1,000 products per run.

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

### How to scrape Prom.ua

#### In the Apify Console

1. Type your keyword into **Search Term**, in Ukrainian/Cyrillic or English (`ноутбуки`, `жіночі сумки`,
   `smartphone`).
2. Set **Maximum Items**, the number of products to collect (1–1,000).
3. Optionally pick a **Sort Option** and a **Minimum/Maximum Price (UAH)**.
4. Click **Start**, then open the **Overview** table on the Output tab or export the dataset as JSON, CSV,
   Excel, XML or JSONL.

A price-tracking run, cheapest offers in a price band first:

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

#### Via API

With curl, get the products straight back in the response:

```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"])
```

#### With AI agents (MCP)

Add the actor to any MCP client (Claude, Cursor, VS Code and others) through Apify's MCP server:

```
https://mcp.apify.com?tools=xmolodtsov/prom-ua
```

Your agent can then call it with the same input, for example "find the 50 cheapest laptops on Prom.ua between
10,000 and 50,000 UAH".

### Pricing

Pay per product: you pay only for products saved to your dataset. Apify platform usage (compute, storage,
data transfer) is included, so nothing is billed on top, and there is no monthly fee.

Until **18 October 2026 (15:00 UTC)**, every Apify plan pays **$2.00 per 1,000 products** ($0.002 per
product). From then on, paid Apify plans get a lower price:

| Apify plan | Price per 1,000 products |
| --- | --- |
| Free | $2.00 |
| Starter (Bronze) | $1.90 |
| Scale (Silver) | $1.80 |
| Business (Gold) | $1.70 |
| Platinum and Diamond | $1.70 (Gold price) |

| Run size | Free plan | Business (Gold), from 18 October |
| --- | --- | --- |
| 100 products | $0.20 | $0.17 |
| 1,000 products (one full run) | $2.00 | $1.70 |
| 10,000 products (10 keywords × 1,000) | $20.00 | $17.00 |

Only products that reach the dataset are charged. A filtered search that matches nothing costs nothing for
results.

#### Is it free?

You can try it on Apify's Free plan, which includes monthly usage credit; the default input (10 laptops)
costs $0.02. The developer sets no extra free-plan limits: Free-plan users get the same inputs and the same
1,000-product maximum per run as paying users, at the Free price in the table above.

### Input

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `search_term` | string | **required** | The keyword to search on Prom.ua, in 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. |
| `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 works without a proxy. |
| `media_only` | boolean | `false` | Only products whose customer reviews include photos or videos. Narrow filter that can legitimately return few or zero products. |
| `good_ratings_only` | boolean | `false` | Only products rated 4 stars 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

The **Overview** table on the Output tab shows rank, image, title, prices, stock, seller and product URL.
Here it is for a real run with the default input (`ноутбуки`, laptops):

![Prom.ua scraper output: Overview table with product rank, image, title, UAH price, sale price, stock status, seller and product URL](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/prom-ua-output-table.png)

One item from the same run, as JSON:

```json
{
    "url": "https://prom.ua/ua/p3167979535-noutbuk-asus-tuf.html",
    "title": "Ноутбук Asus TUF Gaming FX505DT 15.6 дюйма 120 Гц IPS Ryzen 5 3550H 16 ГБ ОЗП 256 ГБ SSD + 1ТБ HDD Відеокарта GTX 1650",
    "regular_price_uah": 39798,
    "discounted_price_uah": 19899,
    "currency": "UAH",
    "image_url": "https://images.prom.ua/7653536145_w400_h400_noutbuk-asus-tuf.jpg",
    "seller_name": "HyperShop",
    "seller_url": "https://prom.ua/ua/c3885015-hypershop.html",
    "in_stock": true,
    "position": 3
}
```

| 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` | number | List price in Ukrainian hryvnia. |
| `discounted_price_uah` | number | 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 (400×400). |
| `seller_name` | string | Seller or 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. |

Every field is present on every item. A product whose URL cannot be built is dropped rather than saved with
an empty `url`, so every row you are charged for links to a real page.

### Guarantees and failure semantics

- **Unfiltered searches never go green with nothing.** If a search without filters extracts 0 products, the
  run ends **FAILED** with `0 products extracted` in the log. That means Prom.ua changed its page or blocked
  the request, so schedulers and API callers can retry or alert on it. The one exception: when Prom.ua's own
  page reports 0 results for the keyword, the run **SUCCEEDS** empty and its status message says so.
- **Filtered searches may legitimately be empty.** With `media_only`, `good_ratings_only`, `min_price` or
  `max_price` set, 0 products is a valid **SUCCEEDED** outcome: the filter matched nothing.
- **Pages served without content are retried.** Prom.ua occasionally serves a search page without its
  product data; the actor detects it and fetches the page again (up to 5 attempts) instead of reporting an
  empty result.
- **A page that keeps failing fails the run.** If a results page still errors after 5 attempts, the products
  from earlier pages are saved and the run ends **FAILED** with a status message naming the failed page,
  instead of returning a shortened list as SUCCEEDED.
- **Results stay in search order.** `position` keeps counting across result pages instead of restarting
  at 1 on each page.

Automated callers can treat SUCCEEDED as "the dataset is complete for this input" and retry on FAILED.

### Integrations

- **Export:** download any dataset as JSON, CSV, Excel, XML, JSONL, RSS or HTML from the Output tab or the
  API.
- **Google Sheets:** send results to a spreadsheet with Apify's Google Sheets integration.
- **Make, Zapier and n8n:** start runs and pass new products into your pricing sheet, CRM or database.
- **Schedules:** re-run the same keyword daily or weekly with
  [Apify Schedules](https://docs.apify.com/platform/schedules) to build price and stock history.
- **Webhooks:** get notified when a run succeeds or fails, and trigger your own pipeline.

### More scrapers from this developer

**TikTok:** [TikTok Search Scraper](https://apify.com/xmolodtsov/tiktok-search-scraper): videos and creators for any keyword, pay per result · [TikTok Profile Scraper (Pay Per Result)](https://apify.com/xmolodtsov/tiktok-profile-scraper): profiles, followers and latest posts by username · [TikTok Comments Scraper](https://apify.com/xmolodtsov/tiktok-comments-scraper): comments and full reply threads from any video · [TikTok Hashtag Scraper](https://apify.com/xmolodtsov/tiktok-hashtag-scraper): videos for any hashtag, with views, likes and music · [TikTok Sound & Music Scraper](https://apify.com/xmolodtsov/tiktok-sound-scraper): videos that use a sound or song · [TikTok Top Ads Scraper](https://apify.com/xmolodtsov/tiktok-top-ads-scraper): public Creative Center ad rankings, engagement, media and landing pages

**Social & news:** [Reddit Search Scraper](https://apify.com/xmolodtsov/reddit-scraper): posts by keyword, subreddit or author · [Google News Scraper](https://apify.com/xmolodtsov/google-news-scraper): Google News results as clean full-text articles · [Threads Replies Scraper](https://apify.com/xmolodtsov/threads-replies-scraper): public post replies, likes, authors and inline nested replies

**Instagram:** [Instagram Reel Scraper](https://apify.com/xmolodtsov/instagram-reel-scraper): public profile reels, plays, captions, music and media URLs · [Instagram Comment Scraper](https://apify.com/xmolodtsov/instagram-comment-scraper): public post and reel comments, likes, timestamps and usernames

**Maps & leads:** [Google Maps Scraper](https://apify.com/xmolodtsov/google-maps-scraper): places, leads and emails from Google Maps

**Ads:** [Facebook Ad Library Scraper (Meta Ads Library)](https://apify.com/xmolodtsov/facebook-ads-library-scraper): ads from the Meta Ad Library, with EU reach and payers · [Google Ads Transparency Scraper](https://apify.com/xmolodtsov/google-ads-transparency-scraper): Google ad creatives by advertiser or domain, with regional details

**Video:** [YouTube Transcript Scraper](https://apify.com/xmolodtsov/youtube-transcript-scraper): transcripts, subtitles and captions from YouTube videos · [YouTube Shorts Scraper](https://apify.com/xmolodtsov/youtube-shorts-scraper): Shorts of any channel with exact views, likes and duration · [YouTube Channel Scraper](https://apify.com/xmolodtsov/youtube-channel-scraper): every video of a channel, with channel stats · [YouTube Search Scraper](https://apify.com/xmolodtsov/youtube-search-scraper): search results and videos for any keyword · [YouTube Comments Scraper](https://apify.com/xmolodtsov/youtube-comments-scraper): comments, replies and likes from any video · [Bilibili Comments Scraper](https://apify.com/xmolodtsov/bilibili-comments-scraper): public hot comments and reply threads by video or keyword

**E-commerce:** [Amazon Product Search & Bestsellers Scraper](https://apify.com/xmolodtsov/amazon-search-scraper): search results, Best Sellers and product details from Amazon · [AliExpress Search Scraper](https://apify.com/xmolodtsov/aliexpress-search-scraper): aliExpress products by keyword with prices, orders and shipping · [AliExpress Product Reviews Scraper](https://apify.com/xmolodtsov/aliexpress-reviews-scraper): public product reviews, ratings, buyer photos and follow-up feedback

**Jobs:** [SEEK Job Listings Scraper](https://apify.com/xmolodtsov/seek-jobs-scraper): public AU/NZ job listings, salaries and redacted descriptions

### FAQ

#### Is it legal to scrape Prom.ua?

The actor collects only publicly listed marketplace data, the same product listings anyone sees on Prom.ua
without signing in. It doesn't log in and doesn't collect private data. Some sellers are individual
entrepreneurs, so a seller name can be personal data covered by laws such as the GDPR and CCPA. You are
responsible for having a lawful basis for collecting and using the data and for complying with Prom.ua's
terms. This is not legal advice; if in doubt, ask a lawyer.

#### Do I need a proxy?

No. Runs work straight from Apify's datacenter IPs with `use_apify_proxy` off. The option exists if you want
it, but leaving it off is normal.

#### Can I scrape several keywords in one run?

No, one `search_term` per run. Start one run per keyword (schedules, tasks and the API make this easy), which
also keeps each dataset scoped to a single term.

#### How do I track prices over time?

Schedule the same input daily and match items on `url`: `regular_price_uah`, `discounted_price_uah` and
`in_stock` give you price and stock history, and `position` gives you ranking history.

#### Does sorting really sort the whole result set?

Yes. Sorting and the price filters are applied server-side by Prom.ua before products are collected, not by
re-sorting one page. `price_asc` returns the cheapest matching offers first across all pages.

#### 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.

#### How fast is it?

It runs over plain HTTP, reading the product data embedded in each search page instead of rendering it in a
browser. A measured 100-product run took about 35 seconds at the default 256 MB memory, and each search page
yields about 29 products.

#### Where are product descriptions and specifications?

Not included; this scraper reads search results only. See [Not included](#not-included).

### Support

Found a bug or need a field that isn't here? Open an issue in the **Issues** tab on this actor's page and
include the run ID so the log can be checked.

# Changelog

This Actor's version history is a separate document: https://apify.com/xmolodtsov/prom-ua/changelog.md

# 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
}
```

# Actor output Schema

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

One item per product from the Prom.ua search results: URL, title, regular and discounted price in UAH, image, seller name and store URL, stock status and search position.

# 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/dZBRI9P4T80mqDnPc/openapi.json
