# OLX Poland Scraper — Any Keyword (`reventadata/olx-pl-scraper`) Actor

Searches OLX.pl (Poland) for any keyword and returns listings with PLN price, description, location, condition, attributes, seller name and promoted-placement status. No proxy required, any category.

- **URL**: https://apify.com/reventadata/olx-pl-scraper.md
- **Developed by:** [reventadata](https://apify.com/reventadata) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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

## OLX Poland Scraper — Any Keyword (olx.pl)

> **Unofficial.** This Actor is not affiliated with, authorised by, endorsed by, or in any
> way officially connected to OLX, Grupa OLX sp. z o.o. or OLX Group. "OLX" is a trademark of
> its respective owner and is used here only to describe what this tool reads. It reads the
> same public pages a browser does.

Search **OLX.pl**, the Polish OLX classifieds site, by any keyword and get every
matching listing as a clean row: price in PLN, condition, location, the seller's public
profile fields, the ad's structured attributes and whether the placement is paid.

### What does it do?

- **Any category, any keyword.** Laptops, phones, bikes, furniture: one search term per
  run entry, same output shape for all of them.
- **Reads the site's own data, not the screen.** Each search page carries the listings as
  structured data; the Actor parses that, so prices, dates and attributes are exact, never
  guessed from text.
- **Condition and price filters are the site's own.** `condition` sends OLX.pl's
  `filter_enum_state` value; `minPrice`/`maxPrice` send its price range.
- **Keyword guard.** OLX.pl search is fuzzy: a `laptop` page carries chargers, bags, RAM
  modules and a laptop table. `requireKeywordMatch` (on by default) drops rows whose title is
  missing a word of the query. Matching ignores accents except `ł`: type `Łódź`, not `lodz`.
- **Promoted placements are labelled, not hidden.** `isFeatured` marks paid placements;
  `excludeFeatured` drops them if you want organic results only.
- **Zero-result searches return nothing.** When nothing matches, olx.pl fills the page with
  unrelated "last resort" ads; the Actor recognises that page and returns no rows for it.

### How to scrape OLX Poland (olx.pl)

1. Put one or more search terms in `searchQueries`.
2. Optionally narrow with `condition`, a price range in PLN, or `sortBy`.
3. Run it. Results land in the dataset.

#### Input

| Field | Type | Meaning |
|---|---|---|
| `searchQueries` | array | One search per term. Required. |
| `condition` | string | `any` | `new` | `used` | `damaged` | `refurbished` (OLX.pl's Nowe, Używane, Uszkodzone, Odnowione / Poleasingowe). Default `any`. |
| `minPrice` / `maxPrice` | integer | Optional, in PLN. Left out of the request when empty, never defaulted to 0. |
| `sortBy` | string | `relevance` | `priceAsc` | `priceDesc` | `newest`. Default `relevance`. `newest` is by the ad's last refresh, not its creation date; paid promoted listings ignore the sort, so treat it as best-effort ordering. |
| `excludeFeatured` | boolean | Drops paid promoted placements. Off by default. |
| `requireKeywordMatch` | boolean | Drops items whose title is missing any word of the query. Default on. |
| `maxItems` | integer | Cap on rows across all terms. Default 1000. |
| `maxPages` | integer | Pages per term. Default 25, which is also OLX.pl's ceiling. |
| `proxyConfiguration` | object | Off by default. Turn on only if you see request failures. |

```json
{
    "searchQueries": ["macbook pro"],
    "condition": "used",
    "maxPrice": 3000,
    "maxItems": 200
}
```

#### Output

One row, verbatim from the `laptop` run of 2026-10-22 (only the description is shortened):

```json
{
    "id": "978671624",
    "title": "BARDZO SZYBKI Laptop Apple Macbook Pro i5 16GB 512GB SSD",
    "description": "Sprzedam bardzo szybkiego laptopa: [...]",
    "url": "https://www.olx.pl/d/oferta/bardzo-szybki-laptop-apple-macbook-pro-i5-16gb-512gb-ssd-CID99-ID14epcc.html",
    "imageUrl": "https://ireland.apollo.olxcdn.com:443/v1/files/n970h8ym6vg43-PL/image;s=773x552",
    "price": 1299,
    "priceNegotiable": false,
    "currency": "PLN",
    "location": "Warszawa",
    "district": "Mokotów",
    "region": "Mazowieckie",
    "postedAt": "2025-02-01T12:04:49+01:00",
    "refreshedAt": "2026-10-20T23:17:50+02:00",
    "condition": "Używane",
    "attributes": {
        "state": "Używane",
        "screendiagonal_laptops": "13-13,9\"",
        "processorseries_laptops": "Intel Core i5",
        "ramsize_laptops": "16GB",
        "harddisktype_laptops": "SSD",
        "disksize_laptops": "513GB - 999GB"
    },
    "isFeatured": true,
    "isBusiness": false,
    "deliveryAvailable": false,
    "sellerName": "Radek",
    "sellerId": "66929504",
    "sellerCompanyName": null,
    "sellerMemberSince": "2017-05-13T11:09:45+02:00",
    "sellerPhoneAvailable": true,
    "latitude": 52.19282,
    "longitude": 21.03232,
    "locationRadiusKm": 7,
    "matchedKeyword": "laptop"
}
```

### Notes and limits

- **25 pages of 52 ads per search, about 1,300 rows at most** (fewer distinct, since promoted
  cards repeat across pages). That is OLX.pl's own ceiling. Narrow with `condition` or a price
  range to see more.
- **Seller name, id, member-since date and company name are returned; the phone number is
  not.** It is not part of the search data; the row carries `sellerPhoneAvailable` (whether the
  seller published one) and the ad `url`.
- **`latitude`/`longitude` are approximate**: the centre of the area OLX.pl shows on the ad
  map, within `locationRadiusKm`, never an exact address.
- **`price` and `condition` are `null`, never 0 or empty, when the ad states neither.**
- **Shell pages are retried.** OLX.pl sometimes answers with a page that carries no listings
  at all (its listing backend degraded). The Actor detects that shape, retries with a fresh
  connection, and logs how many it met. A page that still fails after four attempts is skipped
  and logged; the run continues with the next page.
- **A run that returns zero rows fails** instead of succeeding with an empty dataset, so a
  misconfigured search cannot look like an empty market.
- Reads the same public pages a browser does. See the disclaimer at the top.

### How much does it cost to scrape OLX Poland (olx.pl)?

Pay-per-event: **$0.001 per result** saved to the dataset (**$1.00 per 1,000 results**), plus
**$0.00005** charged once when the run starts. No subscription. Rows your filters drop are not
saved, so they are not charged.

### FAQ

**Is a proxy required?** Off by default. Turn `proxyConfiguration` on only if you see request
failures in the log.

**How many listings can one search return?** Up to 25 pages of 52 ads, about 1,300 rows,
which is OLX.pl's own limit per search.

**Does it cover other OLX countries?** This Actor is OLX.pl only. OLX Romania and OLX Portugal
have their own Actors, below.

### More second-hand marketplace scrapers

| Actor | What it scrapes |
|---|---|
| [OLX Romania Scraper](https://apify.com/reventadata/olx-ro-scraper) | OLX Romania (olx.ro) — any category |
| [OLX Portugal Scraper](https://apify.com/reventadata/olx-pt-scraper) | OLX Portugal (olx.pt) — any category |
| [OLX Brazil Scraper](https://apify.com/reventadata/olx-scraper) | OLX Brazil (olx.com.br) — any category, structured attributes from the site's own detail chips |
| [Kleinanzeigen Scraper](https://apify.com/reventadata/kleinanzeigen-scraper) | Kleinanzeigen, Germany — classifieds by keyword |
| [Vinted Spain Scraper](https://apify.com/reventadata/vinted-scraper) | Vinted Spain (vinted.es) — any keyword or category, no proxy required |

### Privacy & Compliance

This Actor reads only publicly accessible pages and returns the public data they show. It sends no login.

# Actor input Schema

## `searchQueries` (type: `array`):

One search per term. Required, with no default — the Actor never guesses what to look for. Works across any OLX.pl category.

## `condition` (type: `string`):

The site's own condition filter: Nowe (new), Używane (used), Uszkodzone (damaged) or Odnowione / Poleasingowe (refurbished, ex-lease). Any other condition the site shows (for example Powystawowe / Outlet) comes through only under Any.

## `sortBy` (type: `string`):

Order only; changes nothing about which ads exist. Paid promoted listings are interspersed regardless of sort order, so priceAsc/priceDesc/newest are best-effort, not an exact guarantee.

## `minPrice` (type: `integer`):

Optional. Omitted from the request entirely when empty — never defaulted to 0, which would drop every free listing.

## `maxPrice` (type: `integer`):

Optional. Omitted from the request entirely when empty.

## `excludeFeatured` (type: `boolean`):

Drops listings the site marks as promoted (isPromoted in its own data). Off by default, so they are returned and labelled with isFeatured.

## `requireKeywordMatch` (type: `boolean`):

Drop items whose title is missing any word of the query. OLX.pl search is fuzzy: a 'laptop' page carries chargers, bags, RAM modules and a laptop table.

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

Hard cap on rows pushed across all search terms.

## `maxPages` (type: `integer`):

OLX.pl serves at most 25 pages of 52 ads per search (about 1,300 rows). Clamped to that ceiling.

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

Optional. Off by default; see the README for what was measured. Turn on only if you see request failures.

## Actor input object example

```json
{
  "searchQueries": [
    "laptop"
  ],
  "condition": "any",
  "sortBy": "relevance",
  "excludeFeatured": false,
  "requireKeywordMatch": true,
  "maxItems": 10,
  "maxPages": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `matches` (type: `string`):

Matching listings: price, location, condition, promoted status, and a link to the ad.

# 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 = {
    "searchQueries": [
        "laptop"
    ],
    "maxItems": 10,
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("reventadata/olx-pl-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 = {
    "searchQueries": ["laptop"],
    "maxItems": 10,
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("reventadata/olx-pl-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 '{
  "searchQueries": [
    "laptop"
  ],
  "maxItems": 10,
  "maxPages": 1
}' |
apify call reventadata/olx-pl-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reventadata/olx-pl-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/o4MJH2GKqAmYaZLRL/builds/JgQO1MOiCvM05N5Gb/openapi.json
