Otodom Property Scraper (Poland) avatar

Otodom Property Scraper (Poland)

Pricing

from $0.0007 / actor start

Go to Apify Store
Otodom Property Scraper (Poland)

Otodom Property Scraper (Poland)

Scrapes apartments, houses, land and commercial property from Otodom — Poland's #1 real-estate portal, with 150,000+ apartments for sale. Filter by city, price, area and rooms; returns price, area, floor, full description, features, photos and agency. No pagination ceiling.

Pricing

from $0.0007 / actor start

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Categories

Share

Scrapes apartments, houses, land and commercial property from Otodom — Poland's #1 real-estate portal (OLX Group), with over 150,000 apartments listed for sale nationwide.

Public data only. No login, no cookies, no browser.

What you get

Two record types share one dataset, told apart by recordType.

PROPERTY — one row per listing

Search rows carry price, price per m², area, rooms, floor, location, agency and photos. With Fetch full property details on (the default), each row also gets a propertyDetails object:

  • the full description
  • featuresByCategory — every amenity grouped as Otodom groups them
  • floor plans and images
  • exact location with the full administrative hierarchy
  • characteristics — building year, market (primary/secondary), ownership form, heating, condition
  • agency, owner and developer details
  • additional costs (rent, utilities) where the advertiser supplied them

SEARCH_SUMMARY — one row per location searched

Upstream's match total and page count, how deep the run paged, the filters you requested, and Otodom's own echo of the filters it actually parsed.

Input

FieldWhat it does
For sale / for rentsprzedaz or wynajem
Property typeapartment, house, land, commercial premises, halls & warehouses, garage, room, new development
Locationsone search per entry: cala-polska, krakow, or a full path like mazowieckie/warszawa/warszawa/warszawa
Price / areamin–max ranges (PLN, m²)
Number of roomsmulti-select, unioned
Sort bynewest, price, area, price per m² — with direction
Offer URLsscrape specific listings directly, skipping search
Results per request24 / 36 / 48 / 72 (default — fewest requests)
Max properties per location0 = unlimited, and here that really means everything
Fetch full property detailsoff = fast listing-only crawl

Example

{
"transaction": "sprzedaz",
"estate": "mieszkanie",
"locations": ["malopolskie/krakow/krakow/krakow"],
"minPrice": 400000,
"maxPrice": 900000,
"rooms": ["TWO", "THREE"],
"sortField": "LATEST",
"maxItems": 500,
"includePropertyDetails": true
}

What makes this one different

No pagination ceiling. Most property portals cap how deep you can page — Immoweb stops at 9,990 rows, OnTheMarket at 1,020. Otodom does not: page 4,191 of 4,191 really does serve its final rows. maxItems: 0 genuinely means the whole result set, so set a bound unless you mean it.

It reports what Otodom actually understood. Otodom silently ignores filters it does not parse — roomsNumber=THREE is discarded (the right syntax is [THREE]), and an unknown room value just widens your search without saying so. Every run puts Otodom's own parse on the summary row:

"filtersRequested": {"priceMin": 400000, "priceMax": 900000, "roomsNumber": "[TWO,THREE]"},
"upstreamFilterEcho": {"priceMin": 400000, "priceMax": 900000,
"roomsNumber": ["TWO", "THREE"],
"locations": [{"name": "Kraków", "fullName": "Kraków, małopolskie"}]}

Property types, room values, sort fields and page sizes are all validated before the first request. That matters because an unrecognised property type is not an error on Otodom — it answers HTTP 200 with all 150,000 apartments, which would look like a successful run.

Notes on reliability

  • DataDome tag present, no challenge served. Otodom loads DataDome, but every cold request returned full data. The actor watches for genuine challenge markers and rotates IP + fingerprint if one ever appears.
  • Residential proxy by default on cloud runs — the likeliest place for a challenge to show up.
  • Runs unattended. No human-captured session, no expiring token.
  • Unknown locations fail cleanly as not_found.
  • Failures never vanish. An offer withdrawn mid-crawl degrades that one row (_detailError); every input maps to at least one output row.

Output envelope

Every record carries _input, _source and _scrapedAt. Upstream field names pass through verbatim — no renaming. _source is S1-nextdata-search for listing-only rows and S1-nextdata-search+S2-nextdata-ad once details are attached.

Note location on a property row is upstream's own object; the location you searched is locationQueried.

See CRAWLING_METHOD.md for the full reverse-engineering trail, including the obiekt baseline-echo trap and the DataDome marker that would have false-positived on every healthy page.