Otodom Scraper
Pricing
Pay per event
Otodom Scraper
Export public Otodom Poland sale and rental listings with prices, property attributes, photos, locations, and advertiser metadata.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Export public Otodom Poland sale and rental listings as structured JSON, CSV, Excel, XML, or RSS data. The Actor follows real Otodom search URLs, preserves their filters, paginates results, and returns prices, property attributes, photos, location details, and advertiser metadata. Use it for one-time research or schedule repeated snapshots for Polish property market monitoring.
The default search mode is efficient: it reads the structured data already embedded in Otodom result pages. Optional detail enrichment visits each offer page to add full descriptions, more attributes, coordinates, images, and available public advertiser contacts. No Otodom login is required.
What can you do with this Otodom scraper?
- Export current apartments, houses, plots, commercial properties, rooms, garages, and developments covered by an Otodom search URL.
- Compare sale or rental inventory between cities, districts, property types, and saved filter combinations.
- Build recurring snapshots for new-listing, removed-listing, and price-change analysis in your own database.
- Collect PLN prices, price per square metre, area, room count, floor, market type, and location hierarchy.
- Preserve property photo URLs without downloading large image files.
- Capture public agency, developer, owner classification, and available assigned-agent metadata.
- Enrich selected listings with complete descriptions and detailed property attributes.
- Feed Otodom data into spreadsheets, BI tools, warehouses, CRM workflows, or Apify integrations.
Who is it for?
Property investors and analysts can compare asking prices, price per square metre, and available inventory across Polish markets.
Real estate agencies can monitor competing listings, neighbourhood supply, and public advertiser information.
Developers and researchers can use the Actor as an unofficial Otodom data export rather than maintaining page parsing and retry logic.
Relocation and housing teams can create filtered rental datasets for cities such as Lublin, Warsaw, Gdańsk, or Katowice.
Data teams can schedule repeatable runs and join records by stable Otodom IDs in an external history table.
Why use this Actor?
- Search URL fidelity — copy a real filtered Otodom results URL and the Actor keeps those source filters.
- Typed records — output is normalized into stable fields instead of raw HTML.
- Two depth levels — use fast search snapshots or enable offer-page enrichment only when the additional detail is valuable.
- Bounded collection —
maxItemsstops pagination and avoids unnecessary source requests. - Economical delivery — a browser-like direct HTTP route avoids browser runtime and proxy transfer while bounded retries handle transient failures.
- Integration-ready output — the default dataset works with Apify API clients, webhooks, schedules, exports, and MCP.
- Transparent partial enrichment — if one optional detail page fails, the useful search record is retained instead of disappearing.
What Otodom property data is extracted?
| Field | Meaning |
|---|---|
propertyId | Stable Otodom listing or development identifier |
url | Canonical public offer URL |
title | Listing headline |
transaction | Sale or rental classification |
propertyType | Flat, house, land, investment, or other source category |
market | Primary, secondary, or another available market value |
price | Advertised amount and currency |
rentPrice | Rent or maintenance amount when exposed |
pricePerSquareMeter | PLN/m² or other source currency/m² value |
areaSquareMeters | Interior floor area |
terrainAreaSquareMeters | Plot area when relevant |
rooms | Room count classification |
floor | Floor classification |
city, province | Locality and Polish voivodeship |
locationPath | Ordered source location hierarchy |
latitude, longitude | Approximate public coordinates when available |
advertiserType | Agency, developer, or private-owner classification |
agency | Public agency or developer metadata |
contact | Available public advertiser or assigned-agent metadata |
description | Search summary, or full plain text when enriched |
attributes | Build year, heating, equipment, market, and other source attributes |
features | Property tags and feature labels |
imageUrls | Public property photo URLs |
createdAt, modifiedAt | Source timestamps when available |
sourceSearchUrl | Input or paginated search URL that produced the record |
scrapedAt | Timestamp when this Actor produced the record |
Otodom does not expose every field for every listing.
Missing source values are returned as null, empty arrays, or empty objects rather than invented values.
Getting started
- Open an Otodom search in your browser.
- Apply the location, transaction, property type, price, room, or other filters you need.
- Copy the resulting
https://www.otodom.pl/pl/wyniki/...URL. - Add it to Otodom search or offer URLs.
- Choose a
maxItemslimit. - Leave detail enrichment off for a fast inventory snapshot, or enable it for richer offer data.
- Click Start.
- Open the Property listings dataset view or export it in your preferred format.
The prefilled Lublin apartment search is a working example and can be run without editing any field.
Input parameters
startUrls
An array of public Otodom Poland URLs. Supported paths are:
- Search results:
https://www.otodom.pl/pl/wyniki/... - Individual offers:
https://www.otodom.pl/pl/oferta/...
You can mix search and offer URLs in one run.
Duplicate properties are emitted once by stable propertyId.
Only HTTPS Otodom URLs are accepted; unrelated domains and unsupported paths fail validation.
If omitted, the Actor uses a nationwide apartments-for-sale search.
maxItems
Maximum unique records saved across all start URLs. Allowed range: 1–1,000. Default: 20. The Actor stops fetching new result pages after reaching the limit.
includeDetails
When false, records come from structured search-page data and already include the main price, property, image, location, and advertiser fields.
When true, each search record is enriched from its public offer page with full descriptions, additional attributes, coordinates, image variants, and available public contact metadata.
Offer URLs supplied directly are always parsed as detail pages.
maxConcurrency
Maximum simultaneous offer-page enrichment requests. Allowed range: 1–10. Default: 3. Lower values are gentler and often more reliable for long jobs. This setting does not increase search-page pagination concurrency.
Example input: Lublin apartments for sale
{"startUrls": [{"url": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/lubelskie/lublin/lublin/lublin"}],"maxItems": 25,"includeDetails": false,"maxConcurrency": 3}
For rental data, use a real Otodom URL containing /wyniki/wynajem/.
For another city or property type, build the search on Otodom and paste its URL unchanged.
Example output
{"propertyId": "12345678","url": "https://www.otodom.pl/pl/oferta/bright-three-room-apartment-IDexample","title": "Bright three-room apartment with balcony","transaction": "SELL","propertyType": "FLAT","market": "secondary","price": { "value": 650000, "currency": "PLN" },"rentPrice": { "value": 620, "currency": "PLN" },"pricePerSquareMeter": { "value": 12500, "currency": "PLN" },"areaSquareMeters": 52,"terrainAreaSquareMeters": null,"rooms": "THREE","floor": "SECOND","city": "Lublin","province": "lubelskie","locationPath": ["lubelskie", "Lublin", "Śródmieście"],"latitude": 51.2465,"longitude": 22.5684,"advertiserType": "AGENCY","isPrivateOwner": false,"agency": { "name": "Sample Property Agency", "type": "AGENCY" },"contact": { "name": "Sample Agent", "phones": ["+48123456789"] },"description": "Three-room apartment near public transport with a balcony.","attributes": { "build_year": "2020", "heating": "urban" },"features": ["BALCONY", "PARKING_SPOT"],"imageUrls": ["https://ireland.apollo.olxcdn.com/v1/files/sample/image"],"createdAt": "2025-01-15T12:00:00Z","modifiedAt": "2025-01-16T09:30:00Z","sourceSearchUrl": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/lubelskie/lublin/lublin/lublin","scrapedAt": "2025-01-16T10:00:00Z"}
The example is anonymized. Actual records contain current public source values.
How much does it cost to scrape Otodom properties?
The Actor uses pay-per-event pricing:
- one
startevent per run; - one
itemevent for each unique property record written to the dataset.
At the FREE-tier price of $0.005 per run plus $0.0023 per property, approximate Actor charges are:
| Result volume | Approximate Actor charge |
|---|---|
| 10 properties | $0.0280 |
| 100 properties | $0.2350 |
| 1,000 properties | $2.3050 |
Paid Apify plans receive the decreasing item prices configured for their tier. Optional detail enrichment has no separate charge event, but it can take longer and use more source requests. Your final total can also include Apify platform usage according to your account and plan. Always check the live pricing shown on the Actor page before starting a large run.
Recurring Polish property market monitoring
The Actor returns current snapshots; it does not silently retain a cross-run property history or send built-in alerts. Use Apify schedules and your own stable-ID store to create monitoring:
- Save a filtered Otodom URL for the market segment.
- Schedule the Actor daily, weekly, or monthly.
- Export each dataset to a database, object store, or spreadsheet.
- Join snapshots on
propertyId. - Compare
price.value,modifiedAt, availability, and newly appearing IDs. - Trigger your own notification or dashboard refresh when the comparison meets your rules.
This separation keeps every run reproducible and avoids mixing old records into the current run dataset.
Spreadsheet and data-pipeline exports
From the dataset page, export results as JSON, CSV, Excel, XML, RSS, or HTML. For repeat automation, use a dataset API URL or an Apify integration.
Useful patterns include:
- send a completed dataset to Google Sheets;
- load daily snapshots into BigQuery, Snowflake, PostgreSQL, or S3;
- call a webhook after each run;
- connect Make, Zapier, n8n, or another automation tool;
- ingest records into a property intelligence or lead-review workflow.
Nested fields such as price, agency, contact, and attributes are objects.
Flatten them in your destination if a spreadsheet workflow requires scalar columns.
Run through the Apify API with cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~otodom-property-scraper/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls": [{"url": "https://www.otodom.pl/pl/wyniki/wynajem/mieszkanie/lubelskie/lublin/lublin/lublin"}],"maxItems": 20,"includeDetails": false}'
Poll the returned run ID until it reaches a terminal status, then read its default dataset. Keep your Apify token in an environment variable or secret manager.
Run with JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/otodom-property-scraper').call({startUrls: [{url: 'https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/cala-polska',}],maxItems: 50,includeDetails: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Collected ${items.length} Otodom properties`);
For asynchronous systems, use .start() instead of .call() and attach a webhook or poll the run.
Run with Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/otodom-property-scraper').call(run_input={'startUrls': [{'url': 'https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/cala-polska',}],'maxItems': 50,'includeDetails': False,})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(f'Collected {len(items)} Otodom properties')
Use the stable propertyId field when upserting records into your destination.
Use with Apify MCP
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/otodom-property-scraper"
Claude Desktop setup
Add this HTTP server to the mcpServers object in Claude Desktop configuration:
{"mcpServers": {"apify": {"type": "http","url": "https://mcp.apify.com?tools=automation-lab/otodom-property-scraper"}}}
Cursor setup
Open Cursor Settings → MCP → Add new global MCP server and use the same apify HTTP configuration above.
Restart the MCP connection after saving it.
VS Code setup
Add the same server object under servers.apify in your workspace or user MCP configuration, with type set to http and the Actor-specific URL shown above.
Start the server from the VS Code MCP servers view.
Example prompts to ask through MCP:
- “Using the Apify MCP Otodom tool, collect 20 current apartments for sale in Lublin from this filtered URL and summarize median PLN per square metre.”
- “Run the Otodom property scraper through MCP for five enriched rental listings and compare public amenities.”
- “Use MCP to start the Otodom property scraper with my saved search URL and return the dataset link.”
The Actor only supports workflows represented by its input schema; an MCP prompt does not add unsupported filtering or alert features.
Reliability and retries
The Actor uses a lightweight direct request with a browser-like HTTP stack. If Otodom returns a temporary block, rate limit, network failure, or server error, it makes a bounded fresh direct request after backoff. The working route needs neither a browser nor proxy transfer, which keeps normal and enriched runs economical.
Search pages are fetched sequentially.
Detail pages use the bounded maxConcurrency value.
Transient failures are retried twice.
Deterministic invalid URLs and missing offers are not retried indefinitely.
When optional detail enrichment fails for one offer, the Actor logs a warning and preserves the useful search-page record. A challenged or structurally unexpected search page is treated as an error, not as a successful empty result.
Limits and source behavior
- The Actor supports public Polish Otodom search and offer pages only.
- Otodom may change fields, categories, URL structures, or availability without notice.
- Search ordering can change while long pagination jobs are running.
- Promoted listings can appear alongside ordinary results.
- Duplicate IDs are removed within one run.
- Phone numbers, coordinates, descriptions, and agency details are returned only when publicly exposed by the source.
- Photo URLs are collected, but the Actor does not download or archive image binaries.
maxItemsis capped at 1,000 per run to keep jobs bounded.- Built-in historical storage, change alerts, valuation models, and owner identity inference are not provided.
For large recurring jobs, split work by meaningful Otodom search filters rather than repeatedly requesting one extremely broad search.
Troubleshooting
Why did the Actor return fewer records than maxItems?
The search may contain fewer unique public listings, the supplied page may be near the end of pagination, or several start URLs may overlap. Check the original Otodom URL in a browser and inspect run warnings.
Why is a field null?
Otodom does not expose every attribute for every property.
Enable includeDetails for additional offer-page fields, but do not expect private or absent source data to appear.
Why did my input fail immediately?
Only HTTPS URLs on otodom.pl or www.otodom.pl are accepted.
Use a /pl/wyniki/ search URL or /pl/oferta/ property URL copied from Otodom.
Why is an enriched record missing some detail fields?
The source can remove an offer between search discovery and the detail request, or a detail request can fail after retries. The Actor intentionally preserves the valid search record and logs the enrichment warning.
How should I detect price changes?
Schedule repeat runs, store each snapshot externally, and compare price.value by stable propertyId.
The Actor does not compare past runs automatically.
Responsible use and legality
This Actor extracts publicly available property information. You are responsible for complying with Otodom terms, applicable law, database rights, privacy rules, and the rules governing your downstream use.
Collect only what you need. Do not use public contact details for spam, harassment, unlawful profiling, or discriminatory housing decisions. Protect exported personal data, set appropriate retention periods, and honour valid deletion or access requests where applicable. The Actor does not bypass logins or access private account data.
Related Actors by automation-lab
- OLX Poland Classifieds Scraper for broader Polish classified listings.
- Otomoto Scraper for Polish vehicle marketplace records.
These are separate sources and datasets. They are not merged into Otodom results automatically.
FAQ
Does this provide an official Otodom API?
No. It provides an Actor and dataset API over public Otodom pages. It is not affiliated with or endorsed by Otodom.
Can I paste a filtered Otodom URL?
Yes. That is the recommended way to specify locations, transactions, property types, prices, rooms, and other source filters.
Can I scrape one property?
Yes.
Pass its public /pl/oferta/ URL in startUrls.
An individual offer is parsed as a detailed record.
Does it support Otodom mieszkania and rentals?
Yes.
Use a real apartment search URL for sale (sprzedaz) or rent (wynajem).
The same input pattern works for supported Otodom locations and property categories.
Does it download photos?
No. It returns public photo URLs, avoiding unnecessary storage and transfer.
Can I schedule it?
Yes. Use an Apify schedule, then store or compare datasets in your own monitoring workflow.
Is every public contact guaranteed?
No. Contacts appear only when the current public source record exposes them.
What happens when Otodom blocks a request?
The Actor retries transient failures with fresh direct HTTP requests and bounded backoff. If retries are exhausted, the run fails rather than claiming that a challenged page contains zero listings.