Otodom Pl $0.8💰 URL Search | Location Filters | Rich Output avatar

Otodom Pl $0.8💰 URL Search | Location Filters | Rich Output

Pricing

from $0.80 / 1,000 results

Go to Apify Store
Otodom Pl $0.8💰 URL Search | Location Filters | Rich Output

Otodom Pl $0.8💰 URL Search | Location Filters | Rich Output

Pull property listings from Otodom.pl. Apartments, houses, plots, commercial, garages, new developments, rooms; sale and rent. Search builder (city + transaction + property type + filters) and URL-paste modes.

Pricing

from $0.80 / 1,000 results

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

27

Total users

4

Monthly active users

4 days ago

Last modified

Share

Otodom.pl Property Scraper

Pull property listings from Otodom.pl, the largest property portal in Poland (OLX Group). Apartments, houses, plots, commercial, garages, new developments, rooms; sale and rent. Search builder (city + transaction + property type + filters) and URL-paste modes, with auto forward pagination across SERP pages.

Output is one flat JSON record per listing: id, title, price, area, rooms, full address, GPS coordinates, description, agent contact, building year, ownership, market type, and full feature list.

Why This Scraper?

  • Polish portal coverage: top-80 cities + all 16 voivodeships recognized by name (Warszawa, Kraków, Wrocław, Gdańsk, Łódź, Sopot, ...). For unknown cities, drop a URL into URL mode.
  • 30 fields per listing: SERP fields (price, area, rooms, city, agency, photo) plus detail-page enrichment (lat/lng, description, full feature list, build year, ownership, market type, agent phone).
  • Two input modes: structured search (transaction, property type, price/area/rooms ranges, market type, sort) or paste any otodom.pl URL refined in your browser.
  • Forward pagination by default: maxPages walks every result page per search unless capped; per-search budget cap so multi-city searches return balanced results.
  • Resume across runs: paste a previous run/dataset ID into resumeFromRunId to continue a full-catalogue walk without re-scraping already-collected listings.
  • Incremental & recurring monitoring: turn on incrementalMode for a scheduled (e.g. daily) run of the same search — the actor remembers it itself and flags every row NEW/UPDATED/UNCHANGED/REAPPEARED/EXPIRED, so you only see (and pay for) what changed.
  • Low memory footprint: ~80 MB peak memory, ~36 listings/page.
  • Resilient session management: automatic 3-tier proxy preflight (chosen proxy → default Apify proxy → no proxy), so free-tier accounts get a graceful fallback instead of a hard fail.

Data You Get

Sample shape, values are illustrative placeholders, not from a live listing.

FieldExample
id"00000001"
url"https://www.otodom.pl/pl/oferta/sample-listing-ID00000"
title"Sample Apartment Title"
transaction"sprzedaz"
estate"mieszkanie"
priceTotal750000
priceCurrency"PLN"
pricePerSquareMeter15000
rentPricenull
rentAdditionalnull
depositnull
areaInSquareMeters50.0
rooms2
floor"3"
buildingFloors5
buildYear2010
marketType"secondary"
ownership"full_ownership"
buildingType"block"
buildingMaterial"concrete"
heating"urban"
windowsType"plastic"
city"Warszawa"
province"mazowieckie"
district"Mokotów"
street"ul. Sample"
postalCode"00-000"
latitude52.0000
longitude21.0000
agencyName"Sample Agency"
advertiserType"agency"
contactName"Agent Name"
phone"+48000000000"
contactDetailsfull upstream ad.contactDetails block (verbatim — includes email, all phones, types)
agencyfull upstream ad.agency block (verbatim — id, address, license, slug, branding)
ownerfull upstream ad.owner block (verbatim — id, profile URL, role)
referenceId"REF-0001"
description"Full seller description text appears here when fetchDetails=true."
features["meble", "balkon", "winda"]
isPromotedfalse
isExclusivefalse
isPrivateOwnerfalse
imageCount12
imageUrl"https://ireland.apollo.olxcdn.com/v1/files/000000000-OTODOM/image"
dateCreated"2026-01-01T00:00:00.000Z"
investmentEstimatedDeliverynull
scrapedAt"2026-04-28T00:00:00.000Z"
changeType"NEW" (incremental mode only — see below)
changedFields[] (incremental mode only)
firstSeenAt"2026-04-28T00:00:00.000Z" (incremental mode only)
lastSeenAt"2026-04-28T00:00:00.000Z" (incremental mode only)

How to Use

Search mode, basic Warsaw apartments for sale

{
"mode": "search",
"transaction": "sprzedaz",
"estate": "mieszkanie",
"locations": ["Warszawa"],
"maxPages": 3,
"maxListings": 50,
"fetchDetails": true,
"proxy": { "useApifyProxy": true }
}

Search mode, rentals in three cities, filtered

{
"mode": "search",
"transaction": "wynajem",
"estate": "mieszkanie",
"locations": ["Warszawa", "Krakow", "Wroclaw"],
"minPrice": 2000,
"maxPrice": 4500,
"minRooms": 2,
"maxRooms": 3,
"sortBy": "PRICE_ASC",
"maxPages": 2,
"maxListings": 60,
"fetchDetails": true,
"proxy": { "useApifyProxy": true }
}

Search mode, new developments only (primary market)

{
"mode": "search",
"transaction": "sprzedaz",
"estate": "mieszkanie",
"locations": ["Warszawa"],
"marketType": "primary",
"maxPages": 2,
"maxListings": 30,
"fetchDetails": true,
"proxy": { "useApifyProxy": true }
}

URL mode, paste any otodom.pl search URL

{
"mode": "url",
"urls": [
"https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa/warszawa/warszawa/mokotow",
"https://www.otodom.pl/pl/wyniki/wynajem/dom/malopolskie/krakow/krakow/krakow"
],
"minPrice": 400000,
"maxRooms": 3,
"maxPages": 5,
"maxListings": 100,
"fetchDetails": true,
"proxy": { "useApifyProxy": true }
}

URL mode is the recommended path when you need filters not exposed above (district, neighborhood, building type), or for cities outside the built-in lookup table. Open Otodom.pl, refine your search in the browser, copy the URL. The price/area/rooms range fields (minPrice/maxPrice/minArea/maxArea/minRooms/maxRooms above) still apply to listings found via pasted URLs, as shown here.

Input Parameters

ParameterTypeDefaultDescription
modestring"search""search" (use filters below) or "url" (paste URLs)
transactionstring"sprzedaz""sprzedaz" (sale) or "wynajem" (rent)
estatestring"mieszkanie"mieszkanie, dom, dzialka, lokal, garaz, inwestycja, pokoj
locationsstring[]["Warszawa"]Polish city names (built-in lookup for top 80 cities + 16 voivodeships)
marketTypestring"all"all, primary (rynek pierwotny), secondary (rynek wtórny)
minPrice, maxPriceintegernonePLN range on totalPrice
minArea, maxAreaintegernonem² range on areaInSquareMeters
minRooms, maxRoomsintegernoneRoom count range, 1 to 10
sortBystring"DEFAULT"DEFAULT, LATEST, PRICE_ASC, PRICE_DESC, AREA_ASC, AREA_DESC
urlsstring[]exampleFull otodom.pl URLs (URL mode only)
maxPagesintegernonePages to walk per search (each page ~36 listings). Leave empty to walk every result page
maxListingsinteger20Stop after N total. 0 = no cap
fetchDetailsbooleantrueFetch detail page for GPS, description, agent phone, features
resumeFromRunIdstringnonePrevious run/dataset ID; already-collected listings (by id) are skipped so the run only saves new ones
incrementalModebooleanfalseRecurring monitoring of the SAME search: remembers listings itself across scheduled runs and adds changeType/changedFields/firstSeenAt/lastSeenAt to every row
stateKeystringautoOptional label for the incremental baseline; leave empty to auto-derive one from your search settings
emitUnchangedbooleanfalseAlso output UNCHANGED rows (bills extra dataset-item rows)
emitExpiredbooleanfalseAlso output EXPIRED tombstones for delisted listings, only after a complete (uncapped, non-resumed) scan
proxyobjectdatacenterApify proxy config

Incremental mode (recurring monitoring)

Turn on incrementalMode when you run this same search on a schedule (daily, hourly, whatever fits) and only want to know what's new or changed since last time — no need to paste a run ID.

  • How it remembers: a hash of your search settings (mode, transaction, estate, locations/URLs, market type, price/area/room filters, sort) becomes a stateKey unless you set one manually. Two differently-configured runs never share a baseline by accident; the same configuration always resumes the same one.
  • What you get: every row gets changeType (NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED), changedFields (which fields differ from last time), firstSeenAt, and lastSeenAt.
  • What's suppressed by default: UNCHANGED rows are skipped (not pushed, not billed) unless you turn on emitUnchanged.
  • Delistings: turn on emitExpired to get a tombstone row for listings that disappeared. This only fires after a run that scanned the entire tracked search with no maxPages/maxListings cap and no resumeFromRunId truncating it — a partial run can't tell "delisted" from "not reached yet", so it skips EXPIRED detection instead of guessing.
  • Distinct from resumeFromRunId: that continues ONE specific interrupted crawl by pasting its run/dataset id. incrementalMode is for ongoing scheduled monitoring and needs no id. The two combine only when bootstrapping: pass resumeFromRunId on the very first incrementalMode run to seed its baseline from a prior non-incremental pull.
  • Off by default: existing scheduled runs are unaffected until you opt in.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape — the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record — not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Output Example

Sample shape, values are illustrative placeholders, not from a live listing.

{
"id": "00000001",
"url": "https://www.otodom.pl/pl/oferta/sample-listing-ID00000",
"title": "Sample Apartment Title",
"transaction": "sprzedaz",
"estate": "mieszkanie",
"priceTotal": 750000,
"priceCurrency": "PLN",
"pricePerSquareMeter": 15000,
"rentPrice": null,
"rentAdditional": null,
"deposit": null,
"areaInSquareMeters": 50.0,
"rooms": 2,
"floor": "3",
"buildingFloors": 5,
"buildYear": 2010,
"marketType": "secondary",
"ownership": "full_ownership",
"buildingType": "block",
"buildingMaterial": "concrete",
"heating": "urban",
"windowsType": "plastic",
"city": "Warszawa",
"province": "mazowieckie",
"district": "Mokotów",
"street": "ul. Sample",
"postalCode": "00-000",
"latitude": 52.0000,
"longitude": 21.0000,
"agencyName": "Sample Agency",
"advertiserType": "agency",
"contactName": "Agent Name",
"phone": "+48000000000",
"referenceId": "REF-0001",
"description": "Full seller description text appears here when fetchDetails=true.",
"features": ["meble", "balkon", "winda"],
"isPromoted": false,
"isExclusive": false,
"isPrivateOwner": false,
"imageCount": 12,
"imageUrl": "https://ireland.apollo.olxcdn.com/v1/files/000000000-OTODOM/image",
"dateCreated": "2026-01-01T00:00:00.000Z",
"investmentEstimatedDelivery": null,
"scrapedAt": "2026-04-28T00:00:00.000Z"
}

Plan Requirement

  • Default proxy is Apify residential with country=PL. Gives clean first-try fetches and the fastest end-to-end wall time.
  • Bring your own proxy URLs: paste them into the proxy field instead. Make sure they reach Poland for stable routing.
  • fetchDetails ON: roughly 1 extra HTTP request per listing. Latitude / longitude, full description, agent phone, build year, and the full feature list only appear on the detail page; turn it OFF only if you do not need any of these.