Otodom Poland Real Estate Scraper
Pricing
from $1.80 / 1,000 result row emitteds
Otodom Poland Real Estate Scraper
Scrape sale and rent listings from Otodom.pl, Poland's #1 property portal. Get clean numeric price, area, room, district, and city data per listing while we handle blocks and fingerprint rotation for you.
Pricing
from $1.80 / 1,000 result row emitteds
Rating
0.0
(0)
Developer
DevilScrapes
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
🎯 What this scrapes
Otodom.pl is Poland's #1 property portal, and the rival cluster targeting it is the deepest we've measured in this fleet: 41 Actors already compete for it on the Apify Store, 16 with real paying users, the leader (fatihtahta/otodom-pl-scraper) running 90 jobs a month for 145 users. This Actor pulls listing cards straight off Otodom's own search-results JSON for both sprzedaż (sale) and wynajem (rent) — flats, houses, plots, commercial units, warehouses, and garages — across as many Polish cities and districts as you want in a single run, and normalizes every card into clean numeric fields: bare PLN price, price-per-m², floor area, room count, and district/city/province, instead of forcing you to scrape the rendered page yourself.
🔥 What we handle for you
- 🛡️ Browser fingerprint rotation —
curl-cffiimpersonates real Chrome and Firefox TLS handshakes, rotated across requests, so the target sees a browser, not Python. - 🌐 Proxy session rotation via Apify Proxy — fresh session and exit IP on every block, always pinned to a Polish (
PL) residential exit so you never get a wrong-country page silently. - 🔁 Retries with exponential backoff on
408 / 429 / 5xx— up to 5 attempts per page,Retry-Afterhonoured. - 🧱 Search- and page-level fault isolation — one blocked search or one bad listing is skipped and logged, never crashes the run.
- 🧊 Clean, typed dataset rows — Pydantic-validated, ISO-8601 timestamps, numeric price/area/room fields with an explicit currency instead of one rendered blob.
- 💰 Pay-Per-Event pricing — you only pay for results that hit your dataset. No data, no charge.
💡 Use cases
- Home-buyer market research — pull current sprzedaż listings for a Polish city, price-per-m² included, to compare districts fast.
- Rental market benchmarking — track wynajem listing prices and area across Warsaw, Kraków, Wrocław, and other cities in one run.
- PropTech and real-estate analytics — feed a clean, deduped listings dataset into a pricing or valuation model.
- Relocation services — build client-facing property shortlists with district, room-count, and fee data included.
⚙️ How to use it
- Click Try for free at the top of the page.
- Add one or more searches — pick a transaction type (sale/rent), a property type, and a location path copied from an otodom.pl search URL (e.g.
mazowieckie/warszawa/warszawa/warszawa). - Click Start. Output streams into the run's dataset.
- Export from Storage → Dataset as JSON, CSV, or Excel — or fetch via the API.
📥 Input
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
searches | array | yes | — | 1-50 structured searches: transactionType ('sale'|'rent'), propertyType ('flat'|'house'|'room'|'plot'|'commercial'|'warehouse'|'garage'), locationPath, maxPages (1-50). |
maxResults | integer | no | 100 | Cap on rows this run, summed across all Searches. |
proxyConfiguration | object | no | RESIDENTIAL group | The Actor pins country_code='PL' internally whenever a proxy is used (never user-configurable). |
Example input
{"searches": [{"transactionType": "sale","propertyType": "flat","locationPath": "mazowieckie/warszawa/warszawa/warszawa","maxPages": 2},{"transactionType": "rent","propertyType": "flat","locationPath": "malopolskie/krakow/krakow/krakow","maxPages": 1}],"maxResults": 40,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
📤 Output
Every row is one dataset item.
| Field | Type | Notes |
|---|---|---|
listing_id | string | Otodom's numeric ad id, stringified — stable, globally unique. |
url | string | Canonical https://www.otodom.pl/pl/oferta/ |
transaction_type | string | 'sale' or 'rent', from the listing itself. |
property_type | string | Otodom's estate label, e.g. 'flat', 'house', 'investment'. |
title | string | Listing headline as shown on the search card. |
price | ['number', 'null'] | Asking price (sale) or monthly rent (rent). |
currency | string | Always 'PLN'. |
price_per_sqm | ['number', 'null'] | Otodom's own computed price/m². |
additional_rent_fee | ['number', 'null'] | Monthly administrative/maintenance fee (czynsz), separate from price. |
area_sqm | ['number', 'null'] | Floor area in square metres. |
terrain_area_sqm | ['number', 'null'] | Plot/terrain area in square metres, for houses and plots. |
rooms | ['integer', 'null'] | Room count, parsed from Otodom's enum label. |
floor | ['string', 'null'] | Otodom's raw floor label, e.g. 'FIRST', 'GROUND'. |
district | ['string', 'null'] | District/neighbourhood name, when geocoded. |
city | ['string', 'null'] | City name from the listing's address. |
province | ['string', 'null'] | Voivodeship (province) name. |
is_private_owner | ['boolean', 'null'] | True when listed directly by owner. |
is_promoted | ['boolean', 'null'] | True when Otodom marks the ad as promoted. |
image_urls | array | Gallery photo URLs (empty OK). |
scraped_at | string | ISO 8601 UTC row-creation timestamp. |
Example output
{"listing_id": "65432101","url": "https://www.otodom.pl/pl/oferta/mieszkanie-3-pokoje-mokotow-warszawa-ID4abcd","transaction_type": "sale","property_type": "flat","title": "Przestronne mieszkanie na Mokotowie","price": 850000.0,"currency": "PLN","price_per_sqm": 15454.5,"additional_rent_fee": 600.0,"area_sqm": 55.0,"rooms": 3,"floor": "FIRST","district": "Mokotów","city": "Warszawa","province": "mazowieckie","is_private_owner": false,"is_promoted": true,"image_urls": ["https://ap.otodom.pl/img/65432101_large.jpg"],"scraped_at": "2026-09-17T12:00:00+00:00"}
💰 Pricing
Pay-Per-Event — you pay only when these events fire:
| Event | USD | What it is |
|---|---|---|
actor-start | $0.20 | One-off warm-up charge per run |
result-row | $0.0018 | Per unique dataset item |
Example: 1 000 results at the rates above ≈ $2.00. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.
🚧 Limitations
v1 is search-results only — no detail-page enrichment, so fields only the detail page carries (full description text, energy label, exact address, building year) are out of scope for v1. district is null when a listing's reverse-geocoding doesn't carry one (common for some rural/plot listings). A location_path must be copied from a real otodom.pl search URL's path segments — a free-text city name alone is not accepted, since Otodom's own path vocabulary is what determines which listings a search matches.
❓ FAQ
Do I need an Otodom account or API key?
No. This Actor scrapes Otodom.pl's own publicly listed property data — no login, no API key.
How do I find my locationPath?
Search on otodom.pl with your filters, then copy the path segments after /wyniki/sprzedaz/mieszkanie/ (or /wynajem/...) from the resulting URL — e.g. mazowieckie/warszawa/warszawa/warszawa.
Can I scrape multiple cities and both sale and rent in one run?
Yes — add as many searches entries as you want (up to 50), mixing transaction types, property types, and cities freely; we dedupe across all of them.
Why is there no enrich option like some of your other real-estate Actors?
Otodom's search-results JSON already carries price, area, rooms, fees, and location — v1 focuses on getting that data reliably rather than shipping a partial detail-page enrichment toggle.
💬 Your feedback
Spotted a bug, hit a weird edge case, or need a new field? Open an issue on the Actor's Issues tab on Apify Console — we ship fixes weekly and we read every report.