Otodom.pl Scraper — Polish Real Estate Data Extractor
Pricing
from $3.50 / 1,000 results
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
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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.
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
| Parameter | Type | Default | Description |
|---|---|---|---|
locationSlugs | string[] | required | URL location paths (each = one task) |
transaction | enum | sale | sale / rent |
propertyType | enum | apartment | apartment / house / plot / commercial / warehouse / garage / room |
priceMin / priceMax | int | 0 | PLN range (0 = no bound) |
areaMin / areaMax | int | 0 | m² range |
roomsMin / roomsMax | int (1-10) | 0 | Bedroom range |
market | enum | ALL | ALL / PRIMARY (new build) / SECONDARY (resale) |
ownerType | enum | ALL | ALL / PRIVATE / BUSINESS |
sort | enum | latest | latest / price_asc / price_desc / price_per_m_asc / price_per_m_desc / area_asc / area_desc |
distanceRadius | enum km | 0 | 0 / 5 / 10 / 15 / 25 / 50 / 75 |
limit | enum | 72 | 24 / 36 / 48 / 72 |
maxListings | int | 200 | Total cap across all locations (0 = unlimited) |
maxPagesPerTask | int | 5 | Pages per location (Otodom caps ~50 pages × 72) |
requestDelay | int (ms) | 800 | Delay between page fetches |
maxRetries | int | 3 | Retries on HTTP 403/429/503 (rotates proxy IP) |
proxyConfiguration | object | RESIDENTIAL+PL | RESIDENTIAL 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)
| Voivodeship | Slug |
|---|---|
| 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)
| City | Slug |
|---|---|
| Warszawa | mazowieckie/warszawa |
| Kraków | malopolskie/krakow/krakow/krakow |
| Wrocław | dolnoslaskie/wroclaw/wroclaw/wroclaw |
| Poznań | wielkopolskie/poznan/poznan/poznan |
| Gdańsk | pomorskie/gdansk/gdansk/gdansk |
| Łódź | lodzkie/lodz/lodz/lodz |
| Katowice | slaskie/katowice/katowice/katowice |
| Szczecin | zachodniopomorskie/szczecin/szczecin/szczecin |
| Lublin | lubelskie/lublin/lublin/lublin |
| Bydgoszcz | kujawsko-pomorskie/bydgoszcz/bydgoszcz/bydgoszcz |
| Białystok | podlaskie/bialystok/bialystok/bialystok |
| Gdynia | pomorskie/gdynia/gdynia/gdynia |
| Toruń | kujawsko-pomorskie/torun/torun/torun |
| Rzeszów | podkarpackie/rzeszow/rzeszow/rzeszow |
| Kielce | swietokrzyskie/kielce/kielce/kielce |
| Olsztyn | warminsko-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
adIdis Otodom's stable listing ID (numeric, stored as string).detailUrlbuilt fromslug(always present in API payload).floorcomes as enum strings (GROUND,FLOOR_1, ...,CELLAR,ATTIC) — left as raw values.pricePerSqmis taken from API when present, otherwise computed (price / areaSqm).rentPriceis the recurring monthly rent for rentals (separate fromprice).fullAddressis composed; for guaranteed accuracy use the originalprovince/city/district/streetfields.labelsare 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 generation —
ownerType: PRIVATEto find direct-owner listings; agency clusters viaagencyId - Price tracking — re-run periodically and diff against prior datasets (use
dateCreated+pushedUpAt) - Primary-market monitoring —
market: PRIMARYto track new developer offers - Cross-city comparison — multiple
locationSlugsin 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 afetchDetailsflag. - 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/Maxto reach deeper inventory. - Anti-bot — datacenter proxies frequently get 403. Residential PL is strongly recommended.
- Polish diacritics in slugs — Otodom expects ASCII slugs (
krakow, notkraków). The README table uses ASCII; the actor sends slugs as-is.
Changelog
| Version | Date | Notes |
|---|---|---|
| 1.0.0 | 2026-05-04 | Initial 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. |