Otodom.pl Scraper — Polish Real Estate Data Extractor avatar

Otodom.pl Scraper — Polish Real Estate Data Extractor

Pricing

from $3.50 / 1,000 results

Go to Apify Store
Otodom.pl Scraper — Polish Real Estate Data Extractor

Otodom.pl Scraper — Polish Real Estate Data Extractor

Scrape real estate listings from Otodom.pl — Poland's #1 property portal. Extract apartments, houses, plots and commercial properties by location, price (PLN), area, rooms and market. Direct NEXT_DATA access (no browser): price, m², czynsz, GPS, address, agency and image gallery per ad.

Pricing

from $3.50 / 1,000 results

Rating

0.0

(0)

Developer

Logiover

Logiover

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Otodom.pl Real Estate Scraper

Extract property listings from Otodom.pl — Poland's #1 real estate portal (OLX Group, 200K+ active listings). Scrape apartments, houses, plots, commercial space, warehouses, garages and rooms by location, transaction type, price (PLN), area, rooms, market and owner type.

Apify Actor


How It Works

Otodom is a Next.js SSR site. Every search-results page embeds the full listing payload as JSON inside <script id="__NEXT_DATA__">. The actor fetches the HTML once per page via got-scraping, parses out the JSON blob, and walks props.pageProps.data.searchAds.items[]. No browser, no cheerio, no GraphQL token.

GET https://www.otodom.pl/pl/wyniki/{sprzedaz|wynajem}/{type}/{location-slug} ?priceMin=&priceMax= &areaMin=&areaMax= &roomsNumber=[ONE,TWO,...] &market=PRIMARY|SECONDARY|ALL &ownerTypeSingleSelect=ALL|PRIVATE|BUSINESS &distanceRadius=0|5|10|15|25|50|75 &by=LATEST|PRICE|PRICE_PER_M|AREA &direction=ASC|DESC &limit=24|36|48|72&page={N}

Otodom deploys mild bot defense (no full DataDome/Akamai). RESIDENTIAL Apify Proxy with country=PL is strongly recommended — datacenter often gets blocked. With residential PL the actor runs cleanly at ≥600ms request delay.


Input

{
"locationSlugs": ["mazowieckie/warszawa", "malopolskie/krakow"],
"transaction": "sale",
"propertyType": "apartment",
"priceMin": 500000,
"priceMax": 1500000,
"areaMin": 40,
"areaMax": 90,
"roomsMin": 2,
"roomsMax": 3,
"market": "SECONDARY",
"ownerType": "ALL",
"sort": "latest",
"distanceRadius": 0,
"limit": 72,
"maxListings": 500,
"maxPagesPerTask": 10,
"requestDelay": 800,
"maxRetries": 3,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "PL" }
}

Parameters

ParameterTypeDefaultDescription
locationSlugsstring[]requiredURL location paths (each = one task)
transactionenumsalesale / rent
propertyTypeenumapartmentapartment / house / plot / commercial / warehouse / garage / room
priceMin / priceMaxint0PLN range (0 = no bound)
areaMin / areaMaxint0m² range
roomsMin / roomsMaxint (1-10)0Bedroom range
marketenumALLALL / PRIMARY (new build) / SECONDARY (resale)
ownerTypeenumALLALL / PRIVATE / BUSINESS
sortenumlatestlatest / price_asc / price_desc / price_per_m_asc / price_per_m_desc / area_asc / area_desc
distanceRadiusenum km00 / 5 / 10 / 15 / 25 / 50 / 75
limitenum7224 / 36 / 48 / 72
maxListingsint200Total cap across all locations (0 = unlimited)
maxPagesPerTaskint5Pages per location (Otodom caps ~50 pages × 72)
requestDelayint (ms)800Delay between page fetches
maxRetriesint3Retries on HTTP 403/429/503 (rotates proxy IP)
proxyConfigurationobjectRESIDENTIAL+PLRESIDENTIAL strongly recommended

Location Slugs

Location slugs are URL paths Otodom uses internally. To find one: open otodom.pl, apply a location filter, and copy the path between /wyniki/{txn}/{type}/ and ? from the URL. Examples:

Voivodeships (16)

VoivodeshipSlug
Mazowieckie (Warsaw)mazowieckie
Małopolskie (Kraków)malopolskie
Dolnośląskie (Wrocław)dolnoslaskie
Pomorskie (Gdańsk)pomorskie
Wielkopolskie (Poznań)wielkopolskie
Śląskie (Katowice)slaskie
Łódzkie (Łódź)lodzkie
Lubelskie (Lublin)lubelskie
Podkarpackie (Rzeszów)podkarpackie
Kujawsko-pomorskie (Bydgoszcz)kujawsko-pomorskie
Zachodniopomorskie (Szczecin)zachodniopomorskie
Warmińsko-mazurskie (Olsztyn)warminsko-mazurskie
Świętokrzyskie (Kielce)swietokrzyskie
Podlaskie (Białystok)podlaskie
Lubuskie (Zielona Góra)lubuskie
Opolskie (Opole)opolskie

Major cities (drill in further)

CitySlug
Warszawamazowieckie/warszawa
Krakówmalopolskie/krakow/krakow/krakow
Wrocławdolnoslaskie/wroclaw/wroclaw/wroclaw
Poznańwielkopolskie/poznan/poznan/poznan
Gdańskpomorskie/gdansk/gdansk/gdansk
Łódźlodzkie/lodz/lodz/lodz
Katowiceslaskie/katowice/katowice/katowice
Szczecinzachodniopomorskie/szczecin/szczecin/szczecin
Lublinlubelskie/lublin/lublin/lublin
Bydgoszczkujawsko-pomorskie/bydgoszcz/bydgoszcz/bydgoszcz
Białystokpodlaskie/bialystok/bialystok/bialystok
Gdyniapomorskie/gdynia/gdynia/gdynia
Toruńkujawsko-pomorskie/torun/torun/torun
Rzeszówpodkarpackie/rzeszow/rzeszow/rzeszow
Kielceswietokrzyskie/kielce/kielce/kielce
Olsztynwarminsko-mazurskie/olsztyn/olsztyn/olsztyn
Wszystkie (all Poland)cala-polska

For sub-districts append more segments: mazowieckie/warszawa/warszawa/warszawa/mokotow, malopolskie/krakow/krakow/krakow/stare-miasto, etc.


Output

Example record:

{
"adId": "67890123",
"detailUrl": "https://www.otodom.pl/pl/oferta/sprzedam-3-pokojowe-mieszkanie-mokotow-warszawa-ID4abXY",
"slug": "sprzedam-3-pokojowe-mieszkanie-mokotow-warszawa-ID4abXY",
"title": "Przestronne 3-pokojowe mieszkanie na Mokotowie",
"shortDescription": "5 min od metra Wierzbno, balkon, miejsce postojowe.",
"transactionType": "sale",
"propertyType": "apartment",
"advertType": "AGENCY",
"isPrivate": false,
"market": "SECONDARY",
"price": 1250000,
"priceCurrency": "PLN",
"pricePerSqm": 17361,
"rentPrice": null,
"areaSqm": 72,
"terrainAreaSqm": null,
"rooms": 3,
"floor": "FLOOR_3",
"totalFloors": 5,
"province": "mazowieckie",
"city": "Warszawa",
"district": "Mokotów",
"subdistrict": "Stary Mokotów",
"street": "Puławska",
"postalCode": "02-595",
"fullAddress": "Puławska, Stary Mokotów, Mokotów, Warszawa, mazowieckie, 02-595",
"latitude": 52.1923,
"longitude": 21.0289,
"mainImageUrl": "https://ireland.apollo.olxcdn.com/v1/files/.../image.jpg",
"imageUrls": ["https://ireland.apollo.olxcdn.com/.../1.jpg", "..."],
"imageCount": 14,
"agencyId": "12345",
"agencyName": "Sample Real Estate Sp. z o.o.",
"agencySlug": "sample-real-estate-warszawa",
"agencyLogoUrl": "https://...",
"agencyType": "REGULAR",
"isExclusive": false,
"isFeatured": false,
"isPromoted": true,
"hasOpenDay": false,
"investmentName": null,
"investmentState": null,
"dateCreated": "2026-04-28T09:14:22+02:00",
"dateCreatedFirst": "2026-04-15T11:30:00+02:00",
"pushedUpAt": "2026-05-03T08:00:00+02:00",
"labels": ["Promowane"],
"searchTransaction": "sale",
"searchPropertyType": "apartment",
"searchLocation": "mazowieckie/warszawa",
"searchUrl": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa?limit=72&by=LATEST&direction=DESC&page=1",
"scrapedAt": "2026-05-04T13:00:00.000Z"
}

Notes

  • adId is Otodom's stable listing ID (numeric, stored as string).
  • detailUrl built from slug (always present in API payload).
  • floor comes as enum strings (GROUND, FLOOR_1, ..., CELLAR, ATTIC) — left as raw values.
  • pricePerSqm is taken from API when present, otherwise computed (price / areaSqm).
  • rentPrice is the recurring monthly rent for rentals (separate from price).
  • fullAddress is composed; for guaranteed accuracy use the original province/city/district/street fields.
  • labels are Polish badge texts (Promowane, Wyróżnione, Okazja, etc.).

Use Cases

  • Market research — PLN/m² heatmaps by voivodeship, city and district
  • Investment screening — yield = monthly rent / sale price per area
  • Lead generationownerType: PRIVATE to find direct-owner listings; agency clusters via agencyId
  • Price tracking — re-run periodically and diff against prior datasets (use dateCreated + pushedUpAt)
  • Primary-market monitoringmarket: PRIMARY to track new developer offers
  • Cross-city comparison — multiple locationSlugs in one run

Cost & Performance

  • Architecture: HTTP fetch + JSON-blob extraction. No browser, no DOM walking.
  • Throughput: 72 listings per page, ~1 page/sec at default requestDelay=800. ≈ 200 listings in 6-10s with residential proxy.
  • Memory: 256MB minimum.
  • Compute Units: ~0.004 CU per 100 listings.

Limitations

  • Listing-level data only in v1.0. Detail-only fields (full description, energy class, building material, heating, year built, parking spaces, all amenities, exact phone number) require a second per-item HTTP call to /pl/oferta/{slug} — planned for v1.1 behind a fetchDetails flag.
  • Pagination ceiling — Otodom caps results around page 50 (× 72 = ~3600 per filter set). The actor detects pagination loops (compares first ID across pages) and stops. Narrow with priceMin/Max + areaMin/Max to reach deeper inventory.
  • Anti-bot — datacenter proxies frequently get 403. Residential PL is strongly recommended.
  • Polish diacritics in slugs — Otodom expects ASCII slugs (krakow, not kraków). The README table uses ASCII; the actor sends slugs as-is.

Changelog

VersionDateNotes
1.0.02026-05-04Initial release — direct HTTP + __NEXT_DATA__ JSON extraction, 7 property types × sale/rent, all 16 voivodeships + drill-down, full filter set (price/area/rooms/market/ownerType/distance/sort), structured output with full Polish address breakdown, GPS, agency embedding, image gallery.