Piotr VassevPiotr Vassev

How to Scrape OLX Listings and Track New Offers

A recently refreshed OLX listing is not necessarily a newly posted one. That distinction is easy to miss when you are monitoring fresh supply or comparing used-phone asking prices.

The OLX Listings Scraper collects listings from five European OLX markets, including prices, descriptions, seller context, photos, and category attributes. I maintain it. This guide searches Poland for recent iPhone 16 listings and separates comparable phones from misleading matches.

How to Scrape OLX Listings and Track New Offers

Search one market and one model

The supported country values are pl, bg, ro, pt, and ua. Price filters use the selected market's local currency, and category IDs are regional. Do not reuse a Polish category ID in another country without checking it.

Open the Actor on Apify, choose JSON under Input, and enter:

{
  "country": "pl",
  "mode": "search",
  "searchQuery": "iphone 16",
  "maxItems": 25,
  "sortBy": "created_at:desc",
  "postedAfter": "7 days"
}

The sort value created_at:desc is labeled “Recently updated first” by the Actor. The source can put bumped older listings near the top. postedAfter separately filters the original posting date, excluding older listings merely refreshed during the last week.

maxItems accepts 1 to 1,000, and OLX limits a single query to 1,000 results. This sample requests 25; it is a ceiling, not a promised yield. For direct observations of known ads, use mode: "urls" with listing URL objects in startUrls.

Click Start and inspect the dataset. Check country, currency, createdAt, and refreshedAt to understand the time and market represented by each row.

Match model, storage, and condition

A shortened historical example gives you more than a title:

{
  "id": 1061972724,
  "title": "Iphone 16! 93% kondycja baterii",
  "price": 1950,
  "currency": "PLN",
  "negotiable": true,
  "condition": "Używane",
  "city": "Katowice",
  "params": {
    "phonemodel": "iPhone 16",
    "builtinmemory_phones": "128GB",
    "coloriphone": "Czarny"
  }
}

The title mentions battery condition, the parameters identify 128GB storage, and negotiable qualifies the asking price. None of those fields establishes the final sale price. The historical PLN 1,950 observation should only be compared with the same model, storage, and reasonably similar condition.

OLX listing dataset with asking prices and product attributes

Historical OLX results illustrate the asking-price and condition data available for review.

Export JSON if you need all category-specific params and photos. For a spreadsheet, keep id, url, title, price, currency, condition, city, createdAt, refreshedAt, and scrapedAt, then flatten the model and storage attributes you actually use.

Exclude accessories, damaged-for-parts units, and mismatched generations after reviewing titles and descriptions. Keep a separate condition-notes column for battery health, missing parts, repairs, and included accessories. Do not infer those facts just because a field is absent.

Within each comparable group, calculate a median asking price and retain the sample count. Treat an unusually low price as a review candidate, not an automatic bargain; check the original listing and photos before using it as a benchmark.

Coordinates and seller details come with every row

Since September 12, 2026 each listing record carries lat and lon, plus a set of seller and ad fields: isBusiness and sellerCompany, phoneAvailable and chatAvailable, olxDelivery, the promotion package in promotionOptions, the ad status, and validTo. The older includeDetails switch is still accepted but no longer does anything.

Treat the coordinates as listing-location information rather than a pickup address. locationExact is false when the seller chose an approximate area, and lat and lon then mark the centre of a circle of locationRadiusKm. In a September 12 test on olx.pl, all five sampled iPhone listings were approximate, with radii from 1 to 6 km.

Pricing as of September 12, 2026: $0.001 per listing from a search or category. Listings fetched from URLs you supply in urls mode are $0.002 each. Twenty-five search records cost $0.025, plus $0.00005 per GB of allocated memory at Actor start, minimum one event. Check current pricing.

Keep a genuine new-listing log

For repeated searches, match by country and id. A rolling seven-day filter still overlaps yesterday's window, so your archive must remember previously seen IDs. Store first-seen time separately from createdAt, and update price or refresh observations without announcing the same ad as new again.

If results are empty, remove the date filter temporarily and check the query on the chosen OLX market. A broad query hitting the source ceiling may need separate verified category or price ranges, with deduplication across overlapping runs. Missing from a later limited search does not establish that an item sold.

The Node.js example shows how to run this Actor from code and retrieve its dataset.

Frequently asked questions

Does created_at:desc return only new listings?

No. That source sort can include bumped listings. Use postedAfter to filter original posting dates, then deduplicate IDs across repeated runs.

Do I need includeDetails for coordinates or seller details?

No. Since September 12, 2026 every listing carries coordinates, seller, delivery and promotion fields at the standard price. The switch remains for old saved inputs and has no effect.

Piotr Vassev

Piotr Vassev

Founder of FalconScrape. Building production-grade web scraping systems and data automation pipelines for businesses worldwide.

Connect on LinkedIn