OLX Scraper at a glance
OLX Scraper is a ready-to-run Apify actor from abotapi for collecting lead generation data. Its documented output includes id, cc, title, price and cur., which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.00 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Lead Generation, Ecommerce, Automation
- Pricing
- $2.00 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 28 options
Fast OLX scraper across 9 countries, including Poland, Romania, Portugal, Ukraine, Bulgaria, Kazakhstan, Uzbekistan, India and Brazil. Search or paste OLX URLs to extract structured listing data with pagination and multi-market support.
What OLX Scraper can do
- Two ways to collect listings. Build a search from country, category, city, query and price filters, or paste OLX search-result URLs and the actor auto-paginates each one forward.
- Many country sites from one actor. Poland, Romania, Portugal, Ukraine, Bulgaria, Kazakhstan and Uzbekistan each run on their local OLX domain with the same output shape.
- 55+ named fields per listing. Price, category path, full location with latitude and longitude, seller profile, contact toggles, images, key attributes and posting dates, not just the search-result summary.
- Optional detail enrichment. Turn on "Fetch full details per listing" to fill in the complete description, full attribute list and any fields the search results leave empty, with one extra request per listing.
- Built for large catalogues. Resume a paused run without re-scraping listings you already have, or narrow with an advanced filter passthrough for site-specific query parameters.
- Built for schedules. Incremental mode returns only new, updated and reappeared listings on recurring runs, so a daily monitor does not re-bill what has not changed.
Choose what to collect
These inputs let you configure OLX Scraper - Listings Across 9 Countries. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Choose how to find listings. Only fields belonging to the chosen mode are used. |
urlsarray | OLX URLs to scrape, auto-paginating forward until Maximum Pages or Maximum Listings is reached. Supported shapes: category/subcategory pages, category + city pages, free-text /oferty/q-/ searches, filtered/sorted search URLs (search[...] parameters are honoured)?page=N (starts on that page), seller pages (/oferty/uzytkownik//), single listing pages (/d/oferta/...-ID.html), the m. mobile host, and olx.pl / .ro / .pt / .ua (incl. /uk/) / .kz / .bg / .uz. Country is auto-detected. Ignored in Search mode. Left untouched, the field scrapes one example of each shape. |
countrystring | Country to search. Each country runs on the local OLX site (olx.pl, olx.ro, etc.). India runs on a separate API endpoint with the same output schema. (Search mode only, ignored in URL mode.) |
querystring | Free-text search keyword (e.g. "BMW X5", "iPhone 15", "apartment Warsaw"). Combined with category and city filters when present. Leave empty to browse a category without keyword filtering. |
categoryIdinteger | OLX numeric category ID. Optional. Examples (Poland): 1605=Apartments, 5=Auto parts, 84 (India)=Cars. To find a category ID, browse OLX, open the category page, and look at the URL or the metadata. |
categoryNamestring | Plain category name or path as shown on the site, e.g. "Samochody osobowe" or "motoryzacja/samochody". Resolved through OLX's own category list; the run stops with a clear error if nothing matches. Ignored when Category ID is set. Poland, Romania, Portugal, Ukraine, Bulgaria, Kazakhstan, Uzbekistan. |
cityIdinteger | Numeric city ID for filtering by city (PL, RO, PT, UA, BG, KZ, UZ). Look up city IDs by inspecting an OLX search URL after picking a city. Ignored for India (use locationId instead). |
Show 21 more inputs
| Input | What it controls |
|---|---|
cityNamestring | Plain city name, e.g. "Warszawa" or "Kraków". Resolved through OLX's own city pages; the run stops with a clear error if the city is not found. Ignored when City ID is set. |
locationIdinteger | Numeric location ID for olx.in (state/city). Example: 2001173=Tamil Nadu. Ignored for non-India searches. |
priceMininteger | Lower bound for price (in the country's local currency). Optional. |
priceMaxinteger | Upper bound for price (in the country's local currency). Optional. |
sortBystring | How to order results. Default uses the country's relevance ranking. |
extraFiltersobject | Optional escape hatch for site-specific filters not exposed above. Keys are passed verbatim into the request URL. Examples (Pattern A countries): {"filter_enum_make": ["bmw"], "filter_enum_fuel": ["diesel"], "filter_float_year:from": 2018}. Use sparingly; keys are not validated. |
conditionstring | Only listings in this condition (Poland, Romania, Portugal, Ukraine, Bulgaria, Kazakhstan, Uzbekistan). Ignored for India and Brazil. Same as the site's own condition filter. |
sellerFilterstring | Only listings from private sellers or from businesses (same countries as Condition). Ignored for India and Brazil. |
fetchPhoneboolean | Also read the phone number the seller shows publicly on the listing (what any visitor sees after tapping show phone). Adds 1 HTTP call per listing and fills the phones field. Not available for India and Brazil; listings with a hidden phone stay empty. |
fetchDetailsboolean | Fetch each listing's detail endpoint for the freshest revision, complete description, and full attribute list. Adds 1 extra HTTP call per listing. Each delivered listing whose detail endpoint is read is charged as one detail-page event on top of the per-result charge; listings whose detail endpoint is refused, and listings incremental mode suppresses as unchanged, are not charged. |
maxListingsinteger | Stop after scraping this many listings across the whole run. 0 = unlimited (capped only by maxPages). |
maxPagesinteger | Per-search page cap. Each page returns ~10 (Pattern A) or ~40 (India) listings. Leave empty to walk every result page (stopped only by maximum listings, end of results, or the site's own last-page signal). Pattern A countries cap server-side at offset 1000, narrow your filters to see further. |
resumeFromRunIdstring | Paste a previous run ID (or its dataset ID) to continue a full-catalogue scrape without re-scraping listings already saved. Already-seen listings (by listing ID) are skipped; new ones are appended. Leave empty for a fresh run. For recurring daily/weekly monitoring of the same search, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or recurring monitoring of the same search. The first run returns every matching listing as NEW. Later runs return only NEW, UPDATED, and REAPPEARED listings by default. A listing is UPDATED when its content changed (title, price, description, seller, parameters, location, status and similar); the changed field names are listed in changedFields. These never trigger UPDATED, although they stay in the output: scrapedAt, displayDate, score, searchUrl, isPromoted, isHighlighted, isUrgent, isTopAd, promotionOptions, pushupTime, sellerIsOnline, sellerLastLogin, vasTags and image URLs (images). Add more with "Ignore fields when detecting changes" below. Turn on "Emit unchanged" or "Emit expired" below only when you also want those listings returned (and billed). State is kept separately per country/query/filters/URL and per fetchDetails setting - use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the country/query/filters/URL and fetchDetails settings, different searches then never mix state with each other. |
emitUnchangedboolean | Off by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want the full snapshot every run. |
emitExpiredboolean | Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, not when Maximum listings capped it, a page failed to load, or Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking. |
ignoreFieldsForChangesarray | Field names that must NOT make a listing count as UPDATED, in addition to the built-in volatile fields. Use a plain name (sellerName) or a dotted path to a nested value (params.value). The fields still appear in the output. Leave empty to use only the defaults. |
mcpConnectorsarray | Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
listingIdID (text)countryCC (text)titleTitle (text)pricePrice (number)priceCurrencyCur. (text)cityCity (text)categoryNameCategory (text)sellerTypeSeller (text)createdAtCreated (text)urlURL (link)changeTypeChange (text)changedFieldsChanged fields (array)Show 20 more fields
firstSeenAtFirst seen (text)lastSeenAtLast seen (text)detailFetcheddetailFetchedsellerNamesellerNamesellerTagsellerTagbusinessFlagbusinessFlagkycVerifiedkycVerifiedsellerCreatedAtsellerCreatedAtsellerLastLoginsellerLastLoginimageCountimageCountimagesimagesvideosvideosdescriptiondescriptionconditionconditionparamsparamskeyParamskeyParamsphonesphonessellerAboutsellerAboutsellerCompanysellerCompanyfullLocationfullLocationExample output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"listingId": "789456123",
"country": "pl",
"url": "https://www.olx.pl/d/oferta/iphone-13-pro-128gb-jak-nowy-CID123.html",
"title": "iPhone 13 Pro 128GB, jak nowy",
"description": "Sprzedam iPhone 13 Pro 128GB w kolorze grafitowym. Stan idealny, komplet akcesoriów w oryginalnym pudełku.",
"createdAt": "2026-09-20T08:15:00+02:00",
"lastRefreshTime": "2026-09-25T10:00:00+02:00",
"validToTime": "2026-10-25T08:15:00+02:00",
"price": 3200,
"priceCurrency": "PLN",
"priceDisplay": "3 200 zł do negocjacji",
"priceNegotiable": true,
"offerType": "offer",
"categoryId": "1518",
"categoryName": "Telefony i Akcesoria",
"categoryPath": "Elektronika / Telefony i Akcesoria",
"city": "Warszawa",
"region": "Mazowieckie",
"district": "Mokotów",
"fullLocation": "Mokotów, Warszawa, Mazowieckie",
"latitude": 52.1978,
"longitude": 21.0224,
"sellerId": "44556677",
"sellerName": "Kamil",
"sellerType": "private",
"businessFlag": false,
"hasPhone": true,
"hasChat": true,
"hasNegotiation": true,
"hasCourier": true,
"images": [
"https://ireland.apollo.olxcdn.com/v1/files/sample/image;s=1000x700"
],
"imageCount": 6,
"params": [
{
"key": "state",
"name": "Stan",
"value": "Używany",
"type": "select"
}
],
"keyParams": [
"Używany"
],
"status": "active",
"isPromoted": true,
"searchUrl": "https://www.olx.pl/api/v1/offers/?category_id=1518&offset=0&limit=40",
"scrapedAt": "2026-09-27T20:00:00.000Z"
}Ways to use this data
- Price and market monitoring: track asking prices for a model, category or city over time across one or more OLX countries.
- Vehicle listings aggregation: pull car, motorcycle or parts listings by make, model and filters into your own marketplace or comparison site.
- Real estate lead sourcing: collect apartment and rental listings by city and price range for agents or lead-generation tools.
- Resale and dropshipping research: watch a category or search for newly posted items to act on quickly.
- Business intelligence: compare seller types, tags and pricing across categories and countries for competitive analysis.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does OLX Scraper return?
The documented output for OLX Scraper includes id, cc, title, price, cur., city, category and seller. Availability of each field depends on the source page and the selected mode.
How much does OLX Scraper cost?
It costs $2.00 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Later runs then return only new, updated and reappeared listings by default, and unchanged ones are not billed unless you opt in.
Why are some of my filter fields being ignored?
Search fields (country, query, category, city, price, sort, extra filters) only apply in search mode, and the URLs field only applies in URL mode. Filling in fields from the other mode has no effect; check Mode first if a run isn't behaving as expected.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
