Otodom Scraper | Poland Property Listings avatar

Otodom Scraper | Poland Property Listings

Pricing

from $2.20 / 1,000 results

Go to Apify Store
Otodom Scraper | Poland Property Listings

Otodom Scraper | Poland Property Listings

Extract Polish property listings, prices in PLN, rooms, floor area, public contacts and company profiles from Otodom. Pay per delivered row plus a run start fee.

Pricing

from $2.20 / 1,000 results

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Otodom Scraper

Extract Polish property listings, developer profiles and agency portfolios from Otodom as rows you can export.

  • Sale and rental prices, rooms, floor area and listing links.
  • Searches by city, voivodeship, full location path or nationwide scope.
  • Property-type, market, price, area and private-owner filters.
  • Listing details and available phone contacts with enrichDetails.
  • Pay for delivered rows: $3.00 per 1,000 rows on the Free plan, plus a start fee.

What does Otodom Scraper do?

Otodom Scraper collects public property information from otodom.pl in Poland. Each listing or company profile becomes a separate row. Use the results to compare asking prices, monitor inventory or build a property research dataset.

  • Sale and rent: search location or locations; choose channel: "rent" for rentals.
  • Listing URLs: supply known listing links in detailUrls.
  • Developer: supply developerUrl for a profile and available portfolio listings.
  • Agency: supply agencyUrl for a property broker's profile and available portfolio listings.
  • Detail enrichment: enrichDetails: true adds available listing attributes to the same row, not an extra billed row.

What data can you extract from Otodom?

Listing rows

Rows use rowType: "listing". Availability varies by listing and whether details were requested.

FieldDescriptionExample
idEntity identifier used for deduplication68241709
rowTypeRow categorylisting
nameListing titleTwo-room apartment with balcony
listingIdOtodom listing identifier68241709
channelSale or rental channelsale
marketPrimary or secondary marketPRIMARY
estateOtodom property categoryFLAT
priceNumeric asking price, when present610000
priceDisplayDisplay price including currency610000 PLN
currencyPrice currencyPLN
roomsRoom count2
sqmArea in square metres48.5
pricePerSqmPrice per square metre12577
floorFloor number or label2
cityListing cityWarszawa
addressAvailable structured address{"locality":"Warszawa","country":"PL"}
geoAvailable coordinates{"lat":52.23,"lng":21.01}
listingUrlDirect listing linkhttps://www.otodom.pl/pl/oferta/example-ID4abc
imageUrlsAvailable image links[]
yearBuiltConstruction year from details2020
energyCertificateEnergy information from detailsnull
phonesAvailable public contact numbers[{"value":"+1 555 0100","type":"mobile"}]
personNamed owner or agent, when present{"name":"Jane Doe","role":"agent"}
orgAgency identity, when present{"name":"Example Agency","id":"123"}
contentDepthPreview or detailed rowdetail
leadAbsencesReasons unavailable contact fields are empty{}

Developer and agency profile rows

Both profile modes currently use rowType: "developer" and type: "developer". Agency profiles also contain agencyId; there is no separate agency row category. Portfolio listings use the listing format above. The profile and every listing count separately toward the same input's row limit.

FieldDescriptionExample
idProfile identifier10556359
rowTypeProfile row categorydeveloper
nameCompany nameExample Property Company
developerIdProfile identifier, also populated for agencies10556359
agencyIdAdditional identifier on agency profiles7893026
listingUrlCompany profile link/pl/firmy/deweloperzy/develia-ID10556359
cityCompany locationWarszawa
descriptionCompany description, when presentExample company description
phonesAvailable profile phone contacts[]
sellAdsSale-ad count reported by the profile12
investmentAdsInvestment-ad count reported by the profile2

How to scrape Otodom

  1. Open Otodom Scraper in Apify Console.
  2. Fill one target field, such as location: "warszawa".
  3. Set maxResults to 3 or 5 for a first run.
  4. Click Start and wait for the run to finish.
  5. Download the dataset or read it through the API.

With all target fields empty, the Actor starts an example run using the form's Warsaw apartment sample, limited to 3 rows. Normal event charges apply. With channel: "auto", a single target selects the mode. When targets conflict, the priority is detailUrls, developer fields, agency fields, then locations. Use one target family per run to avoid unintended choices.

Sale and rent

Enter a city slug such as warszawa, a voivodeship such as mazowieckie, a full Otodom location path, or national / polska. Use locations for several places. A place alone selects sale; rentals require channel: "rent". Clear the form's sample location when entering only other locations.

Listing URLs

Paste listing links containing /pl/oferta/ into detailUrls. Otodom subdomains and site-relative paths are accepted. This reads known listings rather than discovering matching properties by location.

Developer profiles

Use developerUrl, or a developer slug and ID. The output starts with the profile, followed by available portfolio listings within the row limit. A complete profile URL is the least ambiguous input.

Agency profiles

Use agencyUrl, or an agency slug and ID. This returns the company profile and available portfolio listings, not a directory of every agency in Poland.

What to fill in

FieldWhat to enterDefault
locationOne Polish place or full location pathForm sample: warszawa
locationsAdditional places, merged with location[]
detailUrlsListing or company profile links[]
channelauto, sale, rent, developer, agencyauto
developerUrlDeveloper profile URLEmpty
developerId / developerSlugDeveloper ID and URL slugEmpty
agencyUrlAgency profile URLEmpty
agencyId / agencySlugAgency ID and URL slugEmpty
maxResultsRows per input, from 1 to 50070; form sample 3
propertyTypemieszkanie, dom, dzialka, lokal, pokoj, garaz, inwestycjamieszkanie
marketALL, PRIMARY or SECONDARYALL
minPrice / maxPricePrice bounds in PLNUnset
minArea / maxAreaArea bounds in square metresUnset
roomsRoom count 1–6, or ONE–SIXEmpty
privateOnlyKeep private-owner listingsfalse
sortByEmpty, DEFAULT, PRICE, AREA or DATEEmpty
sortDirectionASC or DESC with a sort choiceEmpty
maxPagesCompatibility setting; does not limit current search pagination1
enrichDetailsAdd available listing detailsForm: true; see below
includeRawInclude a size-limited copy of source data in rawfalse

For a nonempty API input that omits enrichDetails, the Actor currently uses false, unlike the form default. Set it explicitly when details matter.

Sale example

{
"location": "warszawa",
"channel": "sale",
"market": "PRIMARY",
"maxResults": 3,
"enrichDetails": true
}

Rent example

{
"locations": ["krakow", "wroclaw"],
"channel": "rent",
"maxResults": 3
}

Listing URL example

Replace the illustrative link with a current Otodom listing URL.

{
"detailUrls": ["https://www.otodom.pl/pl/oferta/example-ID4abc"],
"maxResults": 1
}

Developer example

{
"developerUrl": "https://www.otodom.pl/pl/firmy/deweloperzy/develia-ID10556359",
"maxResults": 3
}

Agency example

{
"agencyUrl": "https://www.otodom.pl/pl/firmy/biura-nieruchomosci/ko-estate-ID7893026",
"maxResults": 3
}

maxItems and limit are accepted as aliases for maxResults. Unknown fields do not fail input resolution: close misspellings are corrected, while other unknown fields are ignored with a note. Invalid enumerated filters, such as an unrecognized market, are dropped with a warning.

Input-validation failures use INVALID_INPUT: <field> — <how to fix> before any rows are delivered or charged; the start fee is separate. For example, a non-Otodom URL is rejected. The INPUT_REPORT record in the default key-value store records how the input was interpreted, including corrections and ignored fields. INPUT_ECHO, RUN_SUMMARY and, on failure, ERROR_SUMMARY provide further run information.

Output example

Illustrative enriched listing; values and the URL are examples, not a current property offer.

{
"id": "68241709",
"rowType": "listing",
"name": "Example two-room apartment",
"type": "listing",
"status": "For Sale",
"country": "PL",
"authority": "otodom.pl",
"listingId": "68241709",
"channel": "sale",
"market": "PRIMARY",
"price": 610000,
"currency": "PLN",
"rooms": 2,
"sqm": 48.5,
"city": "Warszawa",
"listingUrl": "https://www.otodom.pl/pl/oferta/example-ID4abc",
"phones": [{"value": "+1 555 0100", "type": "mobile"}],
"emails": [],
"person": {"name": "Jane Doe", "role": "agent"},
"web": null,
"contentDepth": "detail"
}

Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. Nested fields such as phones are easiest to preserve in JSON.

Why use this Otodom scraper?

  • Pay per delivered row. Listings and profiles are billed individually, plus the run start fee.
  • Comparable fields. Prices, room counts and area appear under consistent field names.
  • Several inputs. Search multiple places or supply several listing URLs in one run; duplicate entities are removed before delivery.
  • Visible gaps. Missing property and contact values remain empty rather than being invented.
  • No proxy setup. You do not need to set up proxies.

Rows already written to the dataset remain available after a stop. Do not assume unfinished collection has been delivered: this Actor does not guarantee partial delivery when interrupted before results are written.

How much does it cost to scrape Otodom?

The Actor uses pay-per-event pricing. The start event costs $0.005 per GB of allocated memory, with at least one event. At the default 1024 MB, one start costs $0.005. Platform usage is included in these prices.

Apify planStart at 1024 MBPrice per rowPrice per 1,000 rows
Free$0.005$0.003$3.00
Starter$0.005$0.003$3.00
Scale$0.005$0.0026$2.60
Business$0.005$0.0022$2.20
  • maxResults applies to each input, not to every row type separately. Default: 70; larger requests are collected in parts of 70, up to the input maximum of 500.
  • Free Apify plan users are limited to 200 rows per run and 10 runs of this Actor. These are limits set by the Actor's developer.
  • The Maximum cost per run setting (maxTotalChargeUsd in the API) limits the whole run, including multiple inputs.
  • Available matches, finite search coverage and duplicate removal can reduce the number delivered.

Example: three locations returning five distinct rows each produce 15 rows. On the Free plan at 1024 MB, the event cost is 15 × $0.003 + $0.005 = $0.050. A profile row counts toward this calculation just like a listing.

What happens when the run timeout is too short

If a collection job needs longer than the run's remaining time, the Actor can save its progress and pause. An eligible paused run can resume automatically, continuing the existing job instead of submitting the same work again. Rows already stored in the dataset are skipped on resume, so they are not pushed or charged twice.

A deliberate pause may appear as ABORTED. Check the run log and status message before retrying: a manual abort or an unrelated failure is not a saved pause and does not guarantee automatic recovery. Resume attempts are limited; increasing the timeout may still be necessary.

Use with AI agents and the API

Apify MCP server

Add this Actor to a remote MCP client, such as Claude, ChatGPT, Cursor or VS Code:

https://mcp.apify.com?tools=lentic_clockss/otodom-scraper

Sign in with Apify using OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; the agent can then read rows with get-dataset-items. For clients without remote MCP support, run npx @apify/actors-mcp-server --tools lentic_clockss/otodom-scraper with APIFY_TOKEN set.

Example prompt: "Get three Warsaw apartments for sale from Otodom, with listing details, prices in PLN and listing URLs."

Apify API

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/otodom-scraper").call(run_input={
"location": "warszawa", "maxResults": 3, "enrichDetails": True
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/otodom-scraper').call({
location: 'warszawa', maxResults: 3, enrichDetails: true
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

For HTTP, send the input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~otodom-scraper/runs with your token in the Authorization: Bearer header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.

Integrations

Use the Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or a webhook. Apify Schedules can repeat a saved input for regular inventory comparisons.

Po polsku

Otodom Scraper pobiera publiczne ogłoszenia sprzedaży i wynajmu nieruchomości w Polsce, a także profile deweloperów i biur nieruchomości. Wpisz miasto w location albo kilka miejsc w locations. Aby szukać mieszkań na wynajem, ustaw channel na rent. Gotowe linki do ogłoszeń podaj w detailUrls, a adres firmy w developerUrl lub agencyUrl. Ustaw maxResults na 3, aby zacząć od małej próby. Każdy zwrócony wiersz jest rozliczany osobno; profil firmy również liczy się jako wiersz. Dochodzi opłata za rozpoczęcie uruchomienia. Wyniki zawierają dostępne ceny w PLN, powierzchnię, liczbę pokoi i linki. Numery telefonów zależą od ogłoszenia; dla wyszukiwania ustaw enrichDetails na true. Wyniki można pobrać jako CSV, Excel lub JSON.

FAQ

The Actor collects public data. You are responsible for complying with Otodom's terms and applicable data protection law. Processing personal data requires a lawful basis; public availability alone is not permission for every use.

Why did my run end as ABORTED?

A run can be aborted manually or by the calling integration. Check the run log and status message. Do not treat ABORTED as a promise that the run will restart automatically; inspect the dataset before deciding whether to retry.

How many results can I get?

Set maxResults from 1 to 500 per input. The default is 70, while the form sample is 3. Available listings, search coverage, your cost ceiling and the free-plan cap can all reduce the final count.

Why are some fields empty?

Listings do not always show prices, coordinates or contact details. Preview rows contain fewer details. Company profiles have different fields from listings. emails remains empty and web is not populated by this Actor.

Does it return phone numbers?

When public contact numbers are available, they appear in phones. Set enrichDetails: true for search listings. Phone availability is not guaranteed, and no contact form is submitted.

Can I get a developer's entire portfolio?

Not necessarily. Company profiles expose a limited set of portfolio listings. Increasing maxResults does not guarantee access to all of them.

Is this an official Otodom API?

No. This is an independent Actor for reading public Otodom data through Apify, not an official Otodom service.

Limitations

  • Poland and Otodom only; this Actor does not combine other property portals.
  • Listings can change or disappear between discovery and detail collection.
  • Search coverage is finite, and filters can reduce results below the requested count.
  • Developer and agency portfolios may be incomplete; their profile counts can exceed delivered listings.
  • Agency profiles retain the developer row category. Use agencyId to identify agency profile rows.
  • Detail enrichment can fail for individual listings, leaving preview-level information.
  • Emails and website links are not supplied; phone numbers and exact addresses are not guaranteed.

More real estate and property data scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Report problems or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.