Otodom.pl Property Listings Scraper (Poland)
Pricing
from $0.35 / 1,000 listings
Otodom.pl Property Listings Scraper (Poland)
Scrapes property listings from Otodom.pl, Poland's largest real-estate portal: price, price per m², area, rooms, floor, address with GPS, photos, description and the seller's phone. Search by city, by area drawn on a map or by Otodom URL, sale and rent. Export to JSON, CSV or Excel.
Pricing
from $0.35 / 1,000 listings
Rating
0.0
(0)
Developer
Nice Dev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
🏠 What is Otodom.pl Property Listings Scraper?
Otodom.pl Property Listings Scraper extracts property listings from Otodom.pl, Poland's largest real-estate portal — 107 fields per listing: price, price per m², area, rooms, floor, full address with GPS coordinates, building details, photos, description and the seller's contact. Sale and rent; apartments, houses, plots, commercial premises, warehouses, garages and rooms.
Type a city, district or voivodeship name (Kraków, Warszawa Mokotów, pomorskie), draw an area on a map or paste any Otodom search URL, click Start, and download the listings in JSON, CSV or Excel. No login, nothing to set up, and it is fast: about 1,000 listings with full details in 7 minutes.
Use it for price per m² market analysis, alerts on new listings, lead generation (agencies, developers and private sellers, with their phone numbers), or to feed a property database, a dashboard or an AI agent. It costs $0.50 per 1,000 listings, and a listing your filters drop is never charged.
📋 What data can you extract from Otodom?
One item per listing, 107 fields:
| Category | What you get |
|---|---|
| 💰 Price | price, currency, price per m² (numbers and formatted text), monthly charges, deposit, hidden-price flag |
| 📐 Property | sale or rent, property type, primary / secondary market, area, plot area, rooms, floor, floors of the building, build year |
| 🏢 Building | building type and material, heating, windows, ownership, construction status, available from, energy certificate |
| ✨ Features | extras, security, equipment and utilities (balcony, lift, basement, furniture, internet…) |
| 📍 Location | full address, street, city, district, sub-district, voivodeship, powiat and gmina, GPS coordinates and their precision |
| 🖼️ Media | every photo in full size, floor plans, video, 3D / virtual tour |
| 📞 Seller | seller type (agency, developer, private seller), agency name, licence number and office address, contact name, phone numbers |
| 🕒 Dates | first publication (true age of the listing), last publication, bump, last edit |
| 🏗️ New developments | parent development, state, planned delivery, units for sale, area and rooms range, price per m² from, developer's website, promotions |
| 📝 Text | title, short and full description (plain text and HTML), card tags, the seller's own reference |
Every field, with an example, is listed in the Output section below.
Fields marked detail in the Output tab (latitude, longitude, description, buildYear, building details, energyCertificate, agency licence and address, virtualTourUrl, developerWebsite, phones, all photos, floorPlans) are filled when Extract details is on (default). Turn it off for a listing-card-only scrape that is 2-3× faster — about 1 listing in 5 still comes with a phone number, the one Otodom prints on the results page.
✅ Why use Otodom.pl Property Listings Scraper?
- 🚀 Fast: about 1,000 listings with full details in 7 minutes, or 5,000 listing cards in under 2 minutes without the details; a whole-city search (20 000+ listings) takes 2 to 3 hours with details, a few minutes as a listing-card-only scrape.
- 🎯 Type the place, not a URL path:
Kraków,Łódź,Warszawa Śródmieście,Nowa Wieś, Michałowice,pomorskieorPolskaare resolved for you — 6 000+ cities, districts and voivodeships, plus housing estates and villages. An ambiguous or unknown name stops the run with the candidates instead of searching somewhere random. - 🧩 Nothing missed: developer units nested under a new-development card are extracted as individual listings; each listing is returned once.
- 🕒 Real listing age:
createdAtFirstgives the first publication date, not the last bump. - 📞 The seller's contact: contact name and phone numbers, plus the agency's licence number and office address.
- 📍 Full location hierarchy (voivodeship → county → municipality → city → district → sub-district) plus GPS.
- 🎛️ Every Otodom filter, and never a silent one: price per m², floor, building type and material, features, heating and utilities, plot area, photos / video / virtual tour / open day, seller type… Otodom silently drops a filter it does not have for a property type; this Actor refuses it before the run starts and checks on the first page that the site really applied what you asked — you never pay for unfiltered listings.
- 📌 Around a point, or inside an area you draw: GPS coordinates + a radius, a polygon of your own corners, or a Google Place ID for an address or a postal code. You pay for the listings inside the area and for nothing else.
- 🏗️ New developments in full: state, planned delivery, units for sale, price per m² from, and the developer's own website.
- 🗂️ Several cities in one run: one search per location, with a cap per search so that Warszawa cannot eat the whole budget.
- 🔔 Monitoring built in: tick Only new listings, schedule the Actor, and each run returns (and charges) only what it has never delivered before.
- 📅 Date filters on the true age:
postedAfter: "7 days"reads the first publication date, so a bumped old listing is not sold to you as new. Filtered-out listings are never charged. - 🛡️ No blank rows: if Otodom changes its pages, the run stops and fails with the reason instead of filling your dataset with empty listings.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.
🚀 How to scrape Otodom
- Create a free Apify account.
- Open Otodom.pl Property Listings Scraper, type a Location (e.g.
Warszawa), choose sale or rent and the property type, optionally add a radius and filters (price, price per m², area, rooms, build year, floor, building type, features, market, seller type, posted within, keyword…) — they sit in collapsed sections of the form. - Or paste your own Otodom URLs into Start URLs: any search results page (all filters set on the site are kept, pagination is automatic) or single listing pages.
- Set Max listings (100 by default, 0 = no limit) — and Max listings per search when you scrape several locations — then click Start.
- Download the dataset in JSON, CSV, Excel or via API.
💰 How much does it cost to scrape Otodom?
This Actor uses pay per event pricing — a launch price, details included:
| Apify plan | Price per 1,000 listings |
|---|---|
| Free | $0.50 |
| Bronze | $0.45 |
| Silver | $0.40 |
| Gold | $0.35 |
Plus $0.001 per run start (10 cents per 100 runs). Platform usage (compute, proxy) is included in the price.
- A whole-city scrape of 20,000 apartments ≈ $10.
- A daily monitor of 300 new listings ≈ $0.15 a day.
- The $5 of free credits every Apify account starts with already cover about 10,000 listings.
You never pay for a listing your filters drop, nor twice for the same listing (onlyNew).
⚙️ Input
Everything can be set in the form. The same input as JSON, for the API:
{"location": "Kraków","searchType": "wynajem","propertyType": "mieszkanie","priceMax": 4000,"roomsMin": 2,"sortBy": "LATEST","maxItems": 200,"extractDetails": true}
| Field | Notes |
|---|---|
location, locations | City / district / voivodeship name, Polska, or an Otodom path such as mazowieckie/warszawa/warszawa/warszawa. locations adds more places: one search per location (max 100), same filters. Ignored when startUrls is set. |
latitude, longitude, polygon | Search around GPS coordinates (+ radius) or inside an area of your own: see “Search around a point, or inside an area you draw” in the Tips. |
radius, placeId | radius: kilometres around each location (0-100). placeId: search around a Google Place ID (address, street, postal code) instead of a location, with radius as the distance (about 300 m when empty). |
startUrls | Your own Otodom URLs: search results pages (filters kept, pagination automatic) or single listing pages. |
searchType, propertyType | sprzedaz / wynajem; mieszkanie, kawalerka, dom, dzialka, lokal, haleimagazyny, garaz, pokoj (rent only). |
priceMin/Max, pricePerM2Min/Max, areaMin/Max, roomsMin/Max, buildYearMin/Max, terrainAreaMin/Max | Numeric filters (PLN, PLN/m², m², 1-6 rooms where 6 = six or more; terrainArea = plot of a house). |
market, ownerType, daysSinceCreated, sortBy, keyword | Primary/secondary market (sales), PRIVATE / AGENCY / DEVELOPER sellers, posted within 1-30 days, sort order, full-text word in descriptions. |
floors, buildingType, buildingMaterial, extras, heating, media | Lists of Otodom values (GROUND, BLOCK, BRICK, BALCONY, GAS, INTERNET…). extras and media: ALL of them are required; the others: any of them. heating and media exist for rentals only. A value Otodom does not have for the property type stops the run with a clear message. |
hasPhotos, hasVideo, has3DView, hasOpenDay | Only listings with photos / a video / a virtual tour / an open day. |
extractDetails | Open each listing page for GPS, description, building details, photos and phone numbers (default on). |
privateSellerContacts | Include the name and phone of private (non-professional) sellers (default on; agencies and developers are always included). |
maxItems | Stop after this many listings for the whole run (0 = unlimited). |
maxItemsPerQuery | Cap for EACH search (each location, or each search URL). 0 = no per-search cap. |
postedAfter, postedBefore | First-publication date range: 2026-09-01, or a period before now (7 days, 2 weeks, 1 month, 24 hours). |
excludeKeywords, excludeListings | Drop the listings whose title contains one of these words (case and accents ignored: udzial matches Udział), or that you already have (ids, slugs or listing URLs): not charged, their page is not opened (a listing URL pasted into startUrls is still opened, then skipped). |
onlyNew, stateKey, resetState | Monitoring: only the listings never delivered under this memory key; resetState forgets the memory. |
| Advanced | proxyConfiguration (Apify proxy by default, included in the price; the residential proxy is not available), maxConcurrency, maxRequestsPerMinute, maxRequestRetries, debugLog. |
More input examples
Inside an area drawn on a map (only the listings whose pin falls in the polygon):
{"polygon": ["52.2450, 20.9800", "52.2450, 21.0300", "52.2100, 21.0300", "52.2100, 20.9800"],"searchType": "sprzedaz","propertyType": "mieszkanie","priceMax": 900000,"maxItems": 200}
Around GPS coordinates (2 km around the centre of Warsaw):
{"latitude": 52.2297,"longitude": 21.0122,"radius": 2,"searchType": "sprzedaz","propertyType": "mieszkanie","maxItems": 100}
Around a city, with Otodom's own filters (apartments with balcony and lift, 1st to 3rd floor, 12-20 000 PLN/m², with a virtual tour, sold by a developer):
{"location": "Sopot","radius": 10,"searchType": "sprzedaz","propertyType": "mieszkanie","extras": ["BALCONY", "LIFT"],"floors": ["FIRST", "SECOND", "THIRD"],"pricePerM2Min": 12000,"pricePerM2Max": 20000,"has3DView": true,"ownerType": "DEVELOPER","maxItems": 300}
Several cities, a cap per city, only recent listings, only the ones not delivered before:
{"location": "Kraków","locations": ["Gdańsk", "Wrocław", "Warszawa Mokotów"],"searchType": "wynajem","maxItems": 0,"maxItemsPerQuery": 200,"postedAfter": "7 days","onlyNew": true,"stateKey": "rentals-4-cities"}
Your own URLs (a search results page and a single listing):
{"startUrls": [{"url": "https://www.otodom.pl/pl/wyniki/sprzedaz/dom/mazowieckie/warszawa/warszawa/warszawa?priceMax=2000000"},{ "url": "https://www.otodom.pl/pl/oferta/3-pokojowe-mieszkanie-72m2-balkon-ID4zWnj" }],"maxItems": 500}
📦 Output
One item, shortened to its main fields (the table above names all 107):
{"id": 68422279,"url": "https://www.otodom.pl/pl/oferta/funkcjonalna-kawalerka-30-m2-z-osobna-kuchnia-balkon-kliny-zacisze-ID4D5L9","title": "Funkcjonalna kawalerka 30 m2 z osobną kuchnią, balkon, Kliny – Zacisze","transaction": "sale","estate": "flat","market": "secondary","price": 480000,"currency": "PLN","priceFormatted": "480 000 PLN","pricePerM2": 15645.37,"rentPrice": 900,"area": 30.68,"rooms": 1,"floor": 1,"buildingFloors": 3,"buildYear": 2008,"buildingType": "block","heating": "gas","extras": ["balcony", "basement", "separate_kitchen"],"location": "Kliny Zachód, Swoszowice, Kraków, małopolskie","street": "ul. Komuny Paryskiej","city": "Kraków","district": "Swoszowice","province": "małopolskie","latitude": 50.00244,"longitude": 19.895296,"mainImage": "https://ireland.apollo.olxcdn.com/v1/files/.../image;s=2048x1536;q=80","imageCount": 16,"sellerType": "agency","agencyName": "Linx Investment Nieruchomości","agencyLicenseNumber": "26058","agencyAddress": "ul. Zakopiańska 9, 30-418, Kraków, małopolskie","phones": ["+48570130880", "+48505802557"],"isPrivateOwner": false,"dateCreated": "2026-09-15T12:27:05.000Z","createdAtFirst": "2026-09-15T12:26:42.000Z","description": "Linx Investment prezentuje na sprzedaż funkcjonalną i jasną kawalerkę ...","scrapedAt": "2026-09-15T12:36:20.939Z"}
You can download the dataset in various formats such as JSON, HTML, CSV or Excel.
The run also writes a SEARCH_STATS record (key-value store): total listings, pages and price min / max / mean of each search, as Otodom reports them.
All 107 fields
| Fields | What you get |
|---|---|
id, url, slug, title | Identity — 68422279, https://www.otodom.pl/pl/oferta/..., funkcjonalna-kawalerka-...-ID4D5L9 (last part of url), Funkcjonalna kawalerka 30 m2... |
transaction, estate, market | Type — sale, flat, secondary |
price, currency, pricePerM2 | Price — 480000, PLN, 15645.37 |
priceFormatted, pricePerM2Formatted | 480 000 PLN, 15 645 PLN/m² |
rentPrice, deposit | Charges — 900 (monthly charges, sales and rentals alike), 3000 (rentals) |
area, terrainArea, rooms, floor, floorRaw, buildingFloors, buildYear | Size — 30.68, null (plot of a house, or the plot itself), 1, 1, FIRST (the floor as Otodom writes it; GARRET = attic, where floor is null), 3, 2008 |
buildingType, buildingMaterial, heating, windowsType, ownership, constructionStatus, freeFrom | Building — block, brick, gas, plastic, full_ownership, ready_to_use, 2026-09-15 |
energyCertificate, houseFloors, atticType | b (about 1 listing in 8); houses: one_floor, usable |
extras, security, equipment, media | Features — ["balcony","basement"], ["entryphone","monitoring"], ["furniture","dishwasher"], ["internet"] |
plotType, useTypes | Plots, commercial premises — plot type building (budowlana) or commercial (pod inwestycję); intended use ["office","retail"] |
locationType, peoplePerRoom | houses: city, suburban or country; rooms to rent: 1 (people the room is for, 1 to 3) |
aiFilledFields | ["buildingType","extras"] — the fields Otodom's own AI read in the description because the seller left them empty (purple star on the listing page, about 1 listing in 3) |
location, street, city, district, subdistrict, province, locationPath | Address — Kliny Zachód, Swoszowice, Kraków, małopolskie, ul. Komuny Paryskiej, Kraków, Swoszowice, Kliny Zachód, małopolskie, malopolskie/krakow/krakow/krakow/swoszowice/kliny-zachod |
county, municipality, countyId, municipalityId | Powiat, gmina — names where Otodom gives them (piaseczyński near Warsaw, null in Kraków); the two *Id keys (krakow, krakow) are filled on every listing, to group rows by powiat / gmina |
latitude, longitude | GPS — 50.00244, 19.895296 |
gpsRadius | 0 = exact pin; 500 = the seller hid the address and the coordinates are the centre of a 500 m circle (about 1 listing in 6) |
mainImage, images, imageCount, floorPlans | Photos — full-size photo URLs, their count, the floor plans |
virtualTourUrl, videoUrl, descriptionHtml | Media — 3D / virtual tour (1 listing in 3 in Warsaw, 1 in 10 across Poland), video, the description with its HTML tags |
sellerType, agencyId, agencyName, agencyUrl, contactName, phones | Seller — agency, Otodom's id of the agency or developer, Linx Investment Nieruchomości, https://www.otodom.pl/pl/firmy/..., Anna Nowak (the agent the listing page shows), ["+48570130880"] |
agencyLicenseNumber, agencyAddress, agencyLogo, contactPhoto | 7448, ul. Chmielna 69, 00-801, Warszawa, mazowieckie (office address with postal code), image URLs |
isPromoted, isPremium, isPrivateOwner, isExclusiveOffer, hasOpenDay, hidePrice | Flags — true / false |
dateCreated, createdAtFirst, pushedUpAt, dateModified | Dates — ISO 8601: last publication, first publication (true age of the listing), bump, last edit |
developmentId, developmentTitle, developmentUrl | New developments — the parent development of a developer unit |
investmentState, investmentEstimatedDelivery, investmentUnitsNumber, investmentUnitsAreaMin/Max, investmentUnitsRoomsMin/Max, investmentPricePerM2From | in_building, 2027-Q2, 46 units for sale, 31-98 m², 1-4 rooms, from 12100 PLN/m² |
specialOfferType, specialOfferStartDate, specialOfferEndDate, specialOfferDiscount, specialOfferMinPrice30Days, specialOfferAllUnits | Promotions on new-development units (rare: 1 in 100 across Poland, up to 1 in 10 among new flats in Warszawa) — price_discount (or last_minute, attractive_payment_schedule), 2026-09-03, 2026-09-30, 12 (%, when the developer states one), 603600 (lowest price of the 30 days before the promotion), true (every unit of the development) |
developerWebsite | the developer's own page about the project, https://www.victoriadom.pl/krakow/mista-krakow |
shortDescription, description, tags, source, advertType, referenceId | Text — short and full description, card tags, CRM the listing came from, the seller's own reference |
searchUrl, scrapedAt | Run — the search the listing was found by (its first results page), ISO timestamp |
💡 Tips
How to get more results
Set maxItems to 0 and use a broad location (Polska, or a voivodeship) — Otodom exposes every matching listing, there is no 1,000-result cap. For monitoring, use Only new listings (below) rather than daysSinceCreated: no duplicates from one run to the next, and no gap if a run is skipped.
How to reduce costs
The price is per listing, so the levers are maxItems, maxItemsPerQuery, the filters (a filtered-out listing is free) and onlyNew for recurring runs (you never pay twice for the same listing). Turning extractDetails off makes runs faster but does not change the price.
Lots of new builds in the default results
Otodom's default sort pushes new developments up: on whole-Poland runs, 10 % to 55 % of the first 100 rows were developer units (developmentId filled, sellerType: developer) and 38 % to 65 % were market: primary — the share moves a lot from one run to the next. That is the site ranking its own results, not a bias of the Actor. For resale flats only, set market to SECONDARY; for private sellers only, set ownerType to PRIVATE. Both are applied by Otodom itself, so the listings they drop are never charged.
Whole-Poland or multi-city searches
location: "Polska" scrapes the whole country (about 150,000 apartments for sale). For several specific cities, fill locations: the Actor runs one search per location with the same filters (up to 100 locations; every name is checked before the run starts, an unknown one stops it with a clear message).
- A listing found by two searches (a city and one of its districts) is saved — and charged — once.
- Set
maxItemsPerQueryto give every location its own cap: without it the first cities can use up the wholemaxItemsbudget. searchUrltells which search each listing came from.- Several search URLs in
startUrlswork the same way, each with the same cap.
Filters that depend on the property type
Otodom does not offer the same filters everywhere:
| Filter | Where it exists |
|---|---|
heating, media | rentals only |
buildingMaterial, market | sales only |
extras | a different list for apartments for sale, for rent, studios and commercial premises; none for houses |
terrainAreaMin/Max | houses only |
| rooms, build year | apartments and houses |
ownerType | PRIVATE and AGENCY everywhere; DEVELOPER for sales only, plots excepted |
Sent to a category that does not have it, a filter is silently ignored by the site — you would get, and pay for, unfiltered listings. The Actor knows the measured list for each property type: an impossible combination stops the run before the first request, with the categories where the filter exists. For rentals and plots, PRIVATE uses the site's “private owner” box and AGENCY keeps the professional sellers among the extracted listings (the others are not charged).
Search around a point, or inside an area you draw
Four ways to say where, one at a time:
| You have | Fill in | What happens |
|---|---|---|
| A place name | location / locations (+ radius) | Cities, districts, voivodeships, housing estates and villages are all resolved. A name several places share: the city if there is one (Tarnów, Olsztyn, Piła), otherwise add the city or municipality after a comma (Wola, Warszawa). |
| GPS coordinates | latitude + longitude (+ radius, 1 km by default) | A circle around the point, filtered by Otodom's map search. |
| An area on a map | polygon (one latitude, longitude per corner, at least 3) | Only the listings whose pin falls inside the area. A GeoJSON Polygon, Feature or one-area FeatureCollection (geojson.io) pasted as one entry works too; a hole is refused. |
| An address or a postal code | placeId + radius | Look the address up in Google's Place ID Finder and paste the id (empty radius = about 300 m around it). |
Coordinates and polygons cover the whole country, so leave location, locations and placeId empty with them; their results carry GPS even without extractDetails. radius is the radius of the circle for coordinates; a polygon already says how far to look, so radius is refused with it. For a whole city plus its surroundings, location + radius stays the simplest.
Monitoring: only the new listings
Tick Only new listings (onlyNew) and schedule the Actor. The first run returns everything; each later run skips the listings already delivered: they are not saved, not charged, and their page is not even opened (except a listing URL pasted into startUrls: opened, then skipped).
- The memory lives in a named key-value store of your account (
otodom-listings-scraper-seen, up to 150,000 listings per key) and is only updated with listings that really reached the dataset, so a failed run never hides anything. - Give each schedule its own
stateKey(two schedules sharing a key would hide each other's listings), and tickresetStateonce to start over. - Unless you chose a sort order, searches are sorted by newest and a search stops once it meets 72 listings in a row that you already have (one full page), or
maxItemsPerQuery/maxItemsin a row when they are smaller — a typical "nothing new" run costs one request per location and saves nothing.
Filter by publication date
postedAfter and postedBefore take a date (2026-09-01, the whole day is included, Polish time) or a period before now (7 days, 2 weeks, 1 month; via the API also 24 hours or a full ISO date-time).
- The filter reads
createdAtFirst, the first publication date — the true age of the listing, and the date Otodom's newest-first sort follows — notdateCreated, which moves every time a listing is bumped. - It is finer than
daysSinceCreated(any date, not five fixed periods). - Filtered-out listings are never charged and do not count in
maxItems; the run summary tells how many were filtered. - With
postedAfter(and no explicitsortBy), searches are sorted by newest and stop at the first page that is entirely too old.
🔌 Integrations and API
Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). AI assistants and agents can run it through the Apify MCP server. The dataset can be fetched as JSON or CSV from any tool.
❓ FAQ
Is it legal to scrape Otodom?
The Actor only reads what Otodom shows publicly to any anonymous visitor: listings, agency details and the seller's public contact. It logs in to nothing and solves no captcha. Listings posted by private sellers contain a natural person's name and phone number, which is personal data protected by GDPR: turn privateSellerContacts off if you have no legitimate reason to store it. You are responsible for using the data in compliance with Otodom's Terms of Use and applicable law; check them against your own use before running it at scale. This Actor is not affiliated with Otodom or OLX Group.
Does it need a login or a proxy?
No login. The proxy is included in the price: leave the default setting.
Is the data safe to open in Excel or to show on a web page?
Titles, descriptions and names are the sellers' own words, copied as they are.
- Spreadsheets. A text can begin with
-,+,=or@: every phone number does (+48…), and about 1 title in 150 (-1300zł/m2! 3pok…). Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. - Web pages. Every URL field holds an
http://orhttps://URL, ornull— neverjavascript:nordata:.descriptionHtmlis the seller's HTML: Otodom itself keeps simple tags only (paragraphs, lists, bold — no attribute and no script in about 190 descriptions checked), but the Actor does not sanitize it: clean it before inserting it into a page, and escape every other field like any text.
Known limitations
Filters and search
- The few Otodom filters that are not in the input (plot type, commercial use, number of storeys, available from…) can still be used by pasting a filtered search URL into
startUrls; for a pasted URL a filter the site ignored is only reported as a warning in the log. - No search by postal code text: Otodom itself has no postal-code search, and the listings carry no postal code (
agencyAddressgives the agency's). Search the area instead (latitude/longitude/polygon), or give the Google Place ID of the postal code.
Fields
- Some sellers hide the total price on new-development units (6 to 16 rows in 100 on whole-Poland runs):
priceandpriceFormattedarenullandhidePriceistrue. WithextractDetailson,pricePerM2andareaare still filled, so the total is one multiplication away. market,buildYear, building details and GPS come from the listing page: they arenullwhenextractDetailsis off (exceptmarketwhen it is part of the search, and GPS on a drawn-area search). So do most phone numbers: without detailsphonesonly holds the agent's mobile that about 1 results card in 5 carries, and is empty otherwise.- Otodom only names the powiat (
county) outside the big cities, about 1 listing in 7 on a whole-Poland search, and almost never names the gmina (municipality).countyIdandmunicipalityIdare filled on every listing, but they are technical keys (gdansk,ciechanowski), not display names. - The new-development figures (
investment…) come from the results page: they arenullfor a listing URL pasted intostartUrls. - Where the seller left a field empty, the item carries what Otodom's AI read in the description, as the listing page does:
aiFilledFieldslists those fields, to drop them when you need the seller's word only.
Limits and order
maxItemsgives the first listings of the sort order, as Otodom ranks them (units of a new development follow their development card, so a price-sorted list can show one out of place). WithextractDetailson, rows are written as the listing pages come back, not in that order: sort the table by price, area or date.- With several overlapping searches and
maxItemsPerQuery, a shared listing counts for the search that saw it first.
Monitoring
onlyNewremembers listing ids, not their content: a listing whose price changed is not returned again. With a newest-first search it looks for new listings at the top: what lies below 72 already-delivered listings in a row (or your cap, if smaller) is not read — so older listings that a cap left out of an earlier run are not fetched later.- Two runs sharing the same
stateKeyat the same time may both return the same new listing.
A run the platform kills without warning (out of memory, for instance)
- Resurrect it: it goes on from its last saved state, at most a minute old. The listings already saved are skipped and never charged twice.
- With
extractDetailson, the last listings accepted but not yet written at the moment of the kill (usually fewer than 50) are missing and not charged: the run fills their places with the next listings, up tomaxItems. - With
onlyNew, the memory is saved once a minute: resurrect the killed run and the listings it had saved meanwhile join the memory; leave it dead, and the next run may return up to a minute of them once more.
Something doesn't work?
The last line of the log counts the listings saved, filtered out and no longer on Otodom (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed listings are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. If a run fails or returns fewer listings than expected, open an issue in the Issues tab with a link to your run.
If Otodom changes its pages, you are told instead of paying for blank rows:
- A results page that counts listings but gives none the Actor can read is an error (listed in
FAILED_REQUESTS; a run that saved nothing fails with that reason), never a quiet "No listings found". - If the first 20 listings read all lack their title, price (unless the seller hid it), area, city, publication date or — with
extractDetails— description, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first listings are charged. - A listing that
postedAfter/postedBeforedrops because it has no date at all counts among those 20: a date filter never turns a site change into a green run with 0 listings.