OLX.pl Scraper - Polish Classified Listings avatar

OLX.pl Scraper - Polish Classified Listings

Pricing

from $1.50 / 1,000 listings

Go to Apify Store
OLX.pl Scraper - Polish Classified Listings

OLX.pl Scraper - Polish Classified Listings

Collect verified OLX.pl listings from every category with search, price, location and category filters.

Pricing

from $1.50 / 1,000 listings

Rating

0.0

(0)

Developer

Amadeusz

Amadeusz

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

OLX.pl Scraper

Collect listings from OLX.pl, Poland's largest classifieds site, in every category. Give a phrase, a category and a place by name, add price, seller and category-specific filters, or paste a search URL copied from OLX. Every listing is checked against your filters, de-duplicated and returned as clean JSON, ready for CSV, Excel, the API or AI agents.

Run OLX.pl Scraper · Input schema · Output schema

What you get

  • All OLX.pl categories: electronics, cars, real estate, jobs, fashion, home and more, with the filters OLX offers for the chosen category.
  • Names instead of IDs: location takes a city or voivodeship (Kraków, Mazowieckie), category takes a category name or path (Elektronika, motoryzacja/samochody). No numeric IDs to look up.
  • Filters you can discover: a free run with listFilters lists every filter of a category with its allowed values and a ready-to-paste example.
  • Price range, private or business sellers, listings with photos only, listings with OLX delivery only, four sort orders, search URLs copied from OLX (startUrls), several searches in one run with shared de-duplication.
  • Verified results: filters are checked with OLX before the run and against every record. A filter that OLX would silently ignore stops the run with an explanation instead of returning wrong data.
  • No duplicates: the same listing is returned once per run, and you are charged once.
  • Optional details (enrichDetails): seller profile, extra price information and push-up times, with optional view counts (includeViews).
  • Monitoring (mode: monitor): each run returns only listings not reported by earlier runs, so you can schedule it and get new listings.
  • Free estimate (countOnly): how many listings match your search, without scraping or charges.
  • More than 1000 results per search: one OLX query exposes about 1050 listings, so the Actor splits large searches by region and price automatically.
  • One date format (UTC, YYYY-MM-DDTHH:mm:ssZ) in every field.
  • Phone numbers are never returned.

Quick start

  1. Type a Search phrase, or choose a Category and a Location.
  2. Add a price range, seller type or category filters if you need them.
  3. Set Max items (the limit of listings returned and charged).
  4. Click Start. The default input (query: rower, maxItems: 100) is a working example.
  5. Open the Overview table, export JSON, CSV or Excel, or read the data through the API.

Not sure how many listings match, or what a run would cost? Start with Count only: it is free and returns the number OLX reports.

Pricing

Pay per event, no start fee:

EventPriceWhen
listing$1.50 / 1000One per listing returned
listing-details$2.25 / 1000One per listing when enrichDetails is on and the details were fetched
listing-changenot charged yetOne per change record (trackViews); a price will be published here before it is charged

Duplicates, rejected cards, empty runs, countOnly and listFilters runs and runs that end with an input or filter error are not charged. maxItems and your maximum cost per run are hard limits: the run stops when either is reached. In tests the platform usage cost (proxy and compute) was about $0.01 to $0.07 per 1000 listings, depending on enrichDetails.

Cost of a run = listings returned × $0.0015 (plus $0.00225 per enriched listing). Run countOnly first to see how many listings match.

Ready-to-use recipes

1. Search by phrase and place

{
"query": "rower",
"location": "Kraków",
"priceTo": 1500,
"sortBy": "newest",
"maxItems": 100
}

location is a city or a voivodeship. The run log shows how many listings OLX reports for the search.

2. Browse a category

{
"category": "elektronika/telefony",
"location": "Warszawa",
"distance": 30,
"ownerType": "private",
"onlyWithPhotos": true,
"maxItems": 200
}

category takes the URL path of the category or its name. A name used by several categories (for example Telefony) is refused with the list of paths to choose from, so you never get the wrong category by accident. distance (km around the city) needs a city in location.

3. Filter by category filters (cars, flats, jobs)

Each category has its own filters. List them for free:

{
"category": "motoryzacja/samochody",
"listFilters": true
}

The run returns one filter record per filter: name, label, type, unit, allowed values and categoryFiltersExample. Paste the examples into categoryFilters (a bare number for a range filter means that exact value, "filter_float_year": 2018):

{
"category": "motoryzacja/samochody",
"categoryFilters": {
"filter_float_year": { "from": 2018 },
"filter_enum_petrol": ["diesel"]
},
"sortBy": "newest",
"maxItems": 200
}

A filter name or value the category does not have fails the run before anything is charged, and the status record lists what is wrong.

4. Real estate in a district

{
"category": "nieruchomosci/mieszkania/sprzedaz",
"location": "Warszawa",
"districtId": 359,
"priceTo": 900000,
"maxItems": 100
}

359 is Wola. Districts are not recognised by name: run any search in the city once and read the districtId and district fields of the results (Warsaw: 351 Śródmieście, 353 Mokotów, 359 Wola, 373 Ursynów).

5. Use one search copied from OLX

{
"startUrls": ["https://www.olx.pl/warszawa/q-rower/"],
"enrichDetails": true,
"includeViews": true,
"maxItems": 100
}

Plain strings and { "url": "..." } objects both work. Search URLs replace every search field. Several URLs in one run share de-duplication and maxItems.

6. Estimate before you collect

{
"query": "iphone 13",
"countOnly": true
}

Returns one estimate record with estimatedTotal. It is free.

7. New listings since the last run (schedule it)

{
"category": "elektronika",
"mode": "monitor",
"seenStoreName": "my-olx-monitor",
"maxItems": 500
}

Save this input as an Actor Task and attach an Apify Schedule. Details are in the monitoring section below.

8. Call the synchronous API

curl -X POST \
"https://api.apify.com/v2/acts/ziomixshot~olx-pl-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "rower",
"location": "Kraków",
"maxItems": 100
}'

The response is the list of dataset items. When the input is wrong, the list holds one status record with the reason instead of listings, so a script can tell an error from an empty result.

The Actor also works through the Apify MCP server, so agents can read the input and output schemas and call it.

Input

At least one of query, category, categoryId, location, regionId, cityId or startUrls is required. The full description of every field is in the input form. A field the Actor does not know (for example a typo) is rejected when the run starts.

FieldDescription
querySearch phrase, for example iphone 13.
categoryCategory name or URL path: Elektronika, elektronika/telefony, motoryzacja/samochody. A pasted OLX category URL also works.
locationCity or voivodeship: Kraków, Warszawa, Mazowieckie.
distanceRadius around the city in km (0, 2, 5, 10, 15, 30, 50, 75, 100); needs a city in location or cityId.
categoryFiltersFilters of the chosen category as a JSON object, for example {"filter_enum_petrol":["diesel"]}. List them with listFilters.
priceFrom, priceToPrice range in PLN, inclusive. Listings without a price are excluded when a limit is set.
ownerTypeany, private or business.
onlyWithPhotosOnly listings with at least one photo ('Tylko ze zdjęciem' on olx.pl).
onlyWithDeliveryOnly listings with OLX delivery ('Tylko z przesyłką' on olx.pl); verified per card against olxDelivery. Cannot be combined with location, regionId, cityId, districtId or distance: OLX then lists offers from all of Poland (local ones first), so the run stops with INVALID_INPUT.
sortByrelevance, newest, priceAsc or priceDesc.
maxItemsHard limit of returned listings and charges, shared by all startUrls (default 100).
includePromotedOLX appends promoted cards above the page limit; false skips them (default true).
enrichDetailsFetch the listing details; each listing also triggers the listing-details event.
includeViewsAdd the view count (needs enrichDetails). null when OLX does not return it.
includeRawDataAdd raw, the unchanged OLX payload of the listing.
mode, seenStoreName, seenIdsKey, stopMonitorOnAllSeenPages, trackViewsMonitoring, see below.
countOnlyReturn only the number of matching listings (free).
listFiltersReturn the filters of the category instead of listings (free). Needs category or categoryId.
startUrlsSearch URLs copied from OLX, as strings or {url} objects. They replace all search fields above, including ?courier=1 ('Tylko z przesyłką') and search[photos]=1. A URL OLX cannot fully resolve (for example an unknown district) is rejected.
categoryId, regionId, cityId, districtIdOLX numeric IDs, for when you already know them. category and location are easier. districtId needs a city.

category and categoryId cannot be combined, and neither can location with regionId or cityId; the run stops with an explanation instead of guessing.

Output

Every listing is one dataset item. The dataset has an Overview view, an Enriched details view (with enrichDetails) and a Category filters view (with listFilters). The Overview table also shows status and estimate records.

{
"recordType": "listing",
"id": 1096944000,
"url": "https://www.olx.pl/d/oferta/iphone-14-pro-max-128gb-bateria-100-gwarancja-12-miesiecy-CID99-ID1ceFfa.html",
"title": "iPhone 14 PRO MAX 128GB BATERIA 100% GWARANCJA 12 miesiecy !!!",
"description": "iPhone 14 PRO MAX 128GB ...",
"categoryId": 2298,
"categoryType": "electronics",
"price": 2099,
"currency": "PLN",
"priceLabel": "2 099 zł",
"createdAt": "2026-09-08T11:50:18Z",
"lastRefreshedAt": "2026-09-30T22:39:05Z",
"validTo": "2026-10-08T11:50:18Z",
"promoted": false,
"city": "Warszawa",
"region": "Mazowieckie",
"district": "Wola",
"latitude": 52.23725,
"longitude": 20.96608,
"coordinatesExact": false,
"seller": { "type": "business", "registeredAt": "2025-12-07T16:43:05Z" },
"photos": ["https://ireland.apollo.olxcdn.com:443/v1/files/nowebhf71bsy-PL/image;s=800x600"],
"params": [{ "key": "state", "name": "Stan", "value": "used", "label": "Używane" }],
"olxDelivery": true,
"scrapedAt": "2026-10-01T03:13:10Z"
}

The example is a real record, abbreviated (some fields, photos and parameters are left out).

Fields of every listing item: recordType, id, url, title, description (plain text), categoryId (the listing's own, most specific category), categoryType, price, currency, priceLabel, salary (jobs only: from, to, currency, period, gross, arranged), createdAt, lastRefreshedAt, validTo, promoted, highlighted, urgent, topAd, city, cityId, region, regionId, district, districtId, latitude, longitude, coordinatesRadius, coordinatesExact, seller (id, name, type, registeredAt, shopSubdomain), photos (800x600), params (key, name, value, label), olxDelivery, scrapedAt. A value OLX does not provide is null.

Added by enrichDetails: detailsFetched, pushedUpAt, omnibusPushedUpAt, keyParams, externalUrl, gpsrAvailable, priceNegotiable, priceArranged, previousPrice, in seller: companyName, about, logoUrl, lastSeenAt, isOnline, and with includeViews the field views. A listing OLX no longer serves (404 or not active) is skipped and not charged; the count is detailsUnavailable in the run status.

Other record types, always free:

  • status: the run ended because of your input and returned no listings. Fields: status (INVALID_INPUT, URL_NOT_FULLY_RESOLVED, FILTER_VERIFICATION_FAILED, SEEN_STATE_INVALID), message (what is wrong and how to fix it), details, scrapedAt.
  • estimate: result of countOnly: estimatedTotal, sources, note.
  • filter: result of listFilters: categoryId, name, label, type, unit, values, categoryFiltersExample, note.

Run status

The OUTPUT record of the key-value store describes the run: status (OK, PARTIAL, INVALID_INPUT, URL_NOT_FULLY_RESOLVED, FILTER_VERIFICATION_FAILED, SEEN_STATE_INVALID, UPSTREAM_ERROR), counters (cardsRead, emitted, duplicates, alreadySeen, promotedSkipped, rejected, predicateViolations, detailsUnavailable, detailsFailed, viewsMissing, chargeLimitReached) and jobs[] per search (criteria as sent to OLX, expectedTotal reported by OLX, coverage, partitions, truncatedPartitions, failedPages). Input and filter errors end the run without listings and without charges (message explains why). PARTIAL means some pages or details failed after all retries; the returned records are still valid. While a run is going, the status line in Console shows Collected N of M listings; at the end it shows the result, for example OLX reports 0 listings for this search.

Monitoring new listings

mode: monitor returns only listings whose ID was not reported by earlier runs with the same seenStoreName and seenIdsKey (a named key-value store in your account). The first run returns everything up to maxItems; later runs return only new IDs.

  • It always reads newest first and ignores sortBy, does not split the search and skips promoted cards.
  • It reads pages until stopMonitorOnAllSeenPages consecutive pages hold nothing new.
  • State is saved only for listings that were actually returned, also after a failed run. A corrupted state record ends the run with SEEN_STATE_INVALID instead of starting over. Up to 500000 newest IDs are kept.
  • It detects new IDs only, not price changes or expired listings. OLX sorts by refresh time, so an old listing that a seller has just refreshed is reported as new if its ID was never reported before; compare createdAt with scrapedAt to tell fresh listings apart.
  • One query exposes about 1050 listings. In busy categories more new listings can appear between two runs than that window holds (category 99 gets about 400 per hour), so schedule the run often enough.

Tracking page views (trackViews)

mode: monitor with trackViews: true also returns a change record for every offer whose page views changed since the previous run: recordType: "change", metric: "views", id, url, title, previous, current, delta and changedAt (when the run detected it). New listings are still returned as listing items.

  • It checks the offers on the pages the monitor reads (the newest ones, up to the first page without new IDs), not every offer ever seen. An offer that falls off those pages is not checked.
  • The first run (or the first run an offer is seen) only stores a baseline counter; a change needs a stored value to compare with.
  • Counters are stored next to the seen IDs, in the record named like seenIdsKey plus _VIEWS (up to 200000 newest offers). A corrupted record ends the run with SEEN_STATE_INVALID.
  • maxItems limits listings and change records together. A change beyond the limit is kept for the next run.
  • If the OLX views service fails, the run ends PARTIAL (viewsFailed in OUTPUT) and the counters stay as they were. OUTPUT also has viewsTracked and viewChanges.
  • The views endpoint is unofficial and anonymous; OLX can change it without notice.

Estimate (countOnly)

Returns one item with recordType: "estimate" and estimatedTotal, the count OLX reports (visible_total_count). Filters are still verified. With several startUrls the result is the sum of the searches (overlapping listings are counted once per search). It is not charged.

Limits and notes

  • One OLX query exposes about 1050 listings. For maxItems above 1000 the Actor splits by region and then by price (median). Sorting then applies only inside each part, listings without a price can be missed after a price split, and coverage (records against OLX's own count) can exceed 1. truncatedPartitions above 0 means more than 1000 listings with the same price that cannot be separated.
  • price is the amount OLX stores and priceLabel is how OLX shows it. price: 0 with the label Za darmo means free, with Zamienię a swap. Jobs have no price; the pay is in salary. Sorting by price puts symbolic prices (1 zł) first, so set priceFrom to skip them.
  • OLX matches search phrases loosely: a phrase with a typo or a made-up word still returns near matches. Check the count with countOnly before a large run. A phrase can have at most 150 characters.
  • Sorting applies to organic listings. OLX appends promoted cards (promoted: true) out of order; in tests all price-sorting violations involved a promoted card. Use includePromoted: false for a strictly sorted stream. newest is based on the refresh time, so a few older listings pushed up by their sellers can appear slightly out of lastRefreshedAt order.
  • location resolves a city or voivodeship name through OLX (Kraków and Kraków, Małopolskie both work). The run stops with INVALID_INPUT when OLX only knows a different place under that name, instead of searching there. Several places share some names (for example more than one town called Wola); the run log prints the region and city IDs that were used, and jobs[].criteria in OUTPUT has them too. Use startUrls or cityId when you need an exact place.
  • The category list is a snapshot of the OLX category tree; categoryId always works for a category added later.
  • A card that does not expose an attribute is skipped when that attribute is checked against your filters.
  • The Actor uses OLX's own web interface endpoints, which are unofficial and can change without notice. View counts come from such an endpoint and are optional.
  • Runs use Apify residential proxies in Poland (included in the platform usage cost).

This Actor collects data that OLX.pl shows publicly. OLX's Terms of Service restrict using the content of the service and aggregating its data for passing it on to third parties. You are responsible for using the data lawfully and in line with OLX's terms. Listings contain personal data of sellers (name, ID, approximate location), so GDPR rules apply to how you store and use them. Phone numbers are never returned. The Actor is not affiliated with OLX.

Support

Report problems or request fields through the Issues tab of the Actor.