Otodom Scraper & New-Listing Monitor - Poland Real Estate avatar

Otodom Scraper & New-Listing Monitor - Poland Real Estate

Pricing

from $1.46 / 1,000 property returneds

Go to Apify Store
Otodom Scraper & New-Listing Monitor - Poland Real Estate

Otodom Scraper & New-Listing Monitor - Poland Real Estate

Turn monitoring on and every later run returns only the listings it has not returned before, so you are never charged for the same property twice. Every Otodom.pl listing as clean JSON: price with its meaning, price per m2, rooms, area, floor, city and district, coordinates, agency. Unofficial.

Pricing

from $1.46 / 1,000 property returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 hours ago

Last modified

Share

Otodom Scraper - Real Estate Data for Poland, Price & Area

Pull property listings from Otodom.pl — Poland's largest property portal — as clean JSON: the price as a number, what that number means, the area in m², rooms, floor, the city and district, the features and the agency.

Unofficial. This Actor is not affiliated with, endorsed by, or sponsored by Otodom. All product names are trademarks of their respective owners.

No API key. Reads the same public pages a visitor sees.


Run it tomorrow and you only get what is new

Schedule this Actor with monitoringMode: true and each run returns only the listings it has not returned before. Not "here is everything again, please de-duplicate it yourself" — the Actor remembers what it already gave you, so a daily feed costs you the handful of new homes, not the whole board every morning. You are never charged for the same property twice.

Listings your filters removed are remembered too, so widening a filter later does not resurrect them as false "new" listings. Listings that did not fit under your limit are not remembered, so they are still waiting on the next run instead of being silently lost.


Why this one is different

The monthly service charge is not sold to you as rent

This is the trap in Otodom's data. Its listing objects carry a field literally called rentPrice — and 62 of the 104 sale listings measured have one. It is not a rent. It is the monthly administrative charge (czynsz): median 731 PLN, against a sale price whose median is 586,200 PLN.

Passing it through as "rent" would put a 731 next to a 586,200 in the same column, so this Actor splits them:

  • price + priceTypesale for a total, monthly-rent for a rent, taken from the listing's own transaction type
  • monthlyAdminCharge — the czynsz, in its own column, on sale and rent listings alike
  • pricePerSqm — Otodom's own figure, on the listings that publish it

A property whose price is hidden comes back with price: null and isPriceHidden: true — never a zero.

Rooms and floors are words, and they are only turned into numbers where that is safe

Otodom writes roomsNumber: "FOUR" and floorNumber: "THIRD". Both come back twice: the raw word (roomsRaw, floorRaw) and a number (rooms, floor).

ABOVE_TENTH is left as a word with floor: null — "above the tenth" is not a floor number, and inventing 11 would be a guess. Any value not seen in the sample is treated the same way: the word is kept, the number stays null.

No agent names, no phone numbers, no private sellers' names

Otodom's page data carries the assigned agent's first name, last name and mobile number on 33 of the 141 listings measured, and 31 listings are posted by private individuals under their own names.

This Actor returns the agency name only. Agent names, agent mobiles and private sellers' names are not collected, and email addresses and Polish phone numbers are removed from the description text as well. A private listing comes back as advertiserType: "private" with no name attached. Property data, not a contact list.

One request, 30 to 37 complete properties

Otodom ships the full listing — price, area, rooms, floor, location, features, agency — inside the search page itself. This Actor reads all of them from that single page and never opens individual property pages.

Promoted listings repeat across pages; those repeats are dropped before delivery, so you are never charged twice for the same property (4 of the 141 read were repeats).

Filters run here, not on Otodom

Every filter — keyword, price, price per m², rooms, floor, area, agency, advertiser type, date — is applied to rows that were already fetched. Nothing extra is requested from Otodom and nothing extra is charged. A property is never dropped for a value Otodom did not publish: an unknown price is not a low one, an unreadable date is not an old one.

An empty search is an answer, not a silent fallback

A search Otodom has nothing for returns one no-results row saying so, and it is not charged. A page whose embedded data is missing — or which states a total above zero while yielding no properties — is reported as unreadable, so a redesign on Otodom's side shows up as an error rather than as a quiet, permanent "there is nothing for sale". Filters that removed everything are a third kind of row (no-filter-match) which states how many properties were actually read.


Input

Either paste a search URL, or build one from three fields.

FieldTypeDefaultDescription
searchUrlstringe.g. https://www.otodom.pl/pl/wyniki/sprzedaz/dom/mazowieckie. Query parameters are stripped
transactionstringsprzedazsprzedaz (for sale) or wynajem (to rent)
estatestringmieszkaniemieszkanie, dom, dzialka, lokal, haleimagazyny, garaz, pokoj
locationstringcala-polskaThe whole country, a region (mazowieckie), or a city as its full path (mazowieckie/warszawa/warszawa/warszawa)
maxListingsinteger201-1000. One property = one row = one charged event
maxPagesinteger0Hard cap on requests; 0 = decide from maxListings
includeDescriptionbooleantrueThe teaser text. The keyword filter searches it either way
useProxybooleanfalseOff by default — Otodom answers Apify's network directly. Switches on by itself if blocked
keywords / keywordMatch / excludeKeywordsarray / string / arrayMatch on title, description, location, features and agency
agencyNamesarrayKeep only these agencies (partial match)
minPrice / maxPriceinteger0PLN. A property with no published price is kept
maxPricePerSqminteger0PLN per m²
requirePricebooleanfalseDrop properties whose price is hidden
minRooms / maxRoomsinteger-1-1 = off
minFloor / maxFloorinteger-10 is the ground floor. -1 = off
minAreaSqm / maxAreaSqminteger00 = off
advertiserTypestringanyagency or private
exclusiveOnlybooleanfalseListings an agency holds exclusively
listedWithinDaysinteger00 = no limit. An unreadable date is kept
monitoringModebooleanfalseReturn only properties not returned on a previous run
resetMonitoringStatebooleanfalseOne-shot: forget what was already returned
{ "transaction": "sprzedaz", "estate": "mieszkanie", "location": "warszawa", "maxListings": 100,
"minRooms": 2, "maxPrice": 900000, "maxPricePerSqm": 16000, "advertiserType": "private" }

Monitoring mode turns this into a daily feed

Schedule it and set monitoringMode: true: each run returns only the properties it has not returned before. Properties removed by your filters are remembered too, so changing a filter later does not resurrect them as false "new" listings — and properties that simply did not fit under maxListings are not remembered, so they are still waiting for you on the next run rather than being silently lost.

Measured on 2026-09-04: 149,738 flats for sale across Poland.


Output

One row per property:

{
"source": "otodom.pl",
"status": "ok",
"listingId": "68004190",
"title": "Balkon na lato. Wakacje każdego dnia.",
"url": "https://www.otodom.pl/pl/oferta/balkon-na-lato-wakacje-kazdego-dnia-ID4BkZM",
"transactionRaw": "SELL",
"transactionType": "sale",
"estateType": "FLAT",
"price": 675318,
"priceCurrency": "PLN",
"priceType": "sale",
"isPriceHidden": false,
"monthlyAdminCharge": null,
"monthlyAdminChargeCurrency": null,
"pricePerSqm": 9800,
"pricePerSqmCurrency": "PLN",
"areaSqm": 68.91,
"roomsRaw": "FOUR",
"rooms": 4,
"floorRaw": "THIRD",
"floor": 3,
"city": "Bielsko-Biała",
"province": "śląskie",
"street": "ul. Muszlowa",
"locationFullName": "Stare Bielsko, Bielsko-Biała, śląskie",
"features": ["AIR_CONDITIONING", "TERRACE", "STORAGE_ROOM", "TOP_FLOOR", "PARKING_SPOT", "SECURE_BUILDING"],
"advertiserType": "agency",
"agencyName": "Eko Develop",
"agencyUrl": "https://www.otodom.pl/pl/firma/eko-develop-ID433594",
"isExclusiveOffer": false,
"isPromoted": false,
"imagesCount": 15,
"listedAt": "2026-05-14T12:30:32Z",
"updatedAt": "2026-06-21T19:34:16+02:00",
"shortDescription": "…",
"scrapedAt": "2026-09-04T22:40:05.658Z"
}

Measured across 141 live listings on 2026-09-04: title, url, transaction type, property type, city, province and the first-listed date on 141 of 141; area on 137; rooms on 137; floor on 133; a published price on 129.

Rows that are never charged

statuswhen
no-resultsOtodom has no listings for this search. That is its answer, not a failure
no-such-searchOtodom has no page at that address - a mistyped location or property type. Not a claim that there is nothing there: warszawa on its own is a 404, while its full path holds 7,113 flats to rent
no-filter-matchListings were read, but your filters removed all of them. The row says how many were read
no-new-listingsMonitoring mode: nothing new since the previous run
unreadableThe page could not be read, its embedded data was missing, or it claimed a total above zero while yielding nothing

Pricing

Pay per property returned. Rows that report an empty search, a filter that matched nothing, or a page that could not be read are not charged. A property that appears twice across pages is dropped before delivery, so it is never charged twice.


Notes

  • robots.txt was read in full on 2026-09-04. The User-agent: * section disallows /ajax/, /api/query (except ?crawl=true), advertising-slot paths, /uk/* and /*?*map=1. This Actor requests only the public search paths plus ?page=N.
  • Only public pages are read. No login, no API key.