
Global Sources Supplier Scraper
scrape.ly/store/cornerledger/globalsources-scraperLead generationE-commerce
2 monthly users

Scrape otodom.pl property listings in Poland from search URLs, city or district names, or listing URLs: price, price per m², area, rooms, floor, address, GPS, features, photos, agency, seller name and phone numbers.
Scrape property listings from otodom.pl, Poland's largest real estate portal. Paste a search URL or just type a city or district name, and get clean rows with price, price per m², area, rooms, floor, full address, GPS, features, photos, agency details and the seller's phone numbers. No login, no browser, about 1,000 fully detailed listings in under 90 seconds.
| Field | Description |
|---|---|
startUrls | otodom.pl search results URLs (filters in the URL are kept) or listing URLs |
locations | City, district or region names, or otodom location paths |
maxItems | Maximum listings per search (0 = no limit) |
transaction / propertyType / market | sale or rent; flat, studio, house, room, plot, commercial, warehouse, garage, investment; all, primary or secondary |
ownerType, sortBy | private / agency / developer; newest, price, price per m² or area |
priceMin … plotAreaMax | Price, price per m², area, rooms, build year and plot area ranges |
postedWithinDays, keyword, distanceRadius | Recent listings only, text in the description, extra radius in km |
fetchDetails | Open each listing for description, all features, GPS and phones (default on) |
{
"locations": ["Kraków"],
"transaction": "sale",
"propertyType": "flat",
"priceMax": 900000,
"roomsMin": 2,
"sortBy": "newest",
"maxItems": 100
}
| Field | Description |
|---|---|
id, url, title | Listing id, link and title |
transaction, propertyType, market | sale/rent, flat/house/..., primary/secondary |
price, currency, pricePerM2, rentPrice, deposit | Prices in PLN (rentPrice is the monthly building fee) |
area, plotArea, rooms, floor, totalFloors, buildYear | Size and building data |
buildingType, buildingMaterial, condition, ownershipType, heating, windowsType, energyCertificate, availableFrom, elevator | Property details |
address, street, subdistrict, district, city, province, latitude, longitude | Location |
description | Full description as plain text (descriptionHtml keeps the HTML) |
sellerType, sellerName, contactName, phone, phones, contacts | Seller and contact numbers shown on the listing |
agencyId, agencyName, agencyUrl, agencyAddress, agencyLicenseNumber | Agency or developer |
extras, equipment, security, media, features, tags | Amenities |
mainImage, images, imageCount, floorPlans, videoUrl, view3dUrl | Media |
isPromoted, isExclusiveOffer, isPrivateOwner, createdAt, modifiedAt, pushedUpAt, status | Flags and dates |
details | Every labelled value from the listing's details table |
Example (trimmed; seller and agency are fictional):
{
"id": 68439349,
"url": "https://www.otodom.pl/pl/oferta/radzikowskiego-100-m2-3-poziomy-5-pokoi-ID4Dact",
"title": "Radzikowskiego 100 m2 3 poziomy 5 pokoi",
"transaction": "sale",
"propertyType": "flat",
"market": "secondary",
"price": 1049999,
"currency": "PLN",
"pricePerM2": 10633.98,
"rentPrice": null,
"deposit": null,
"area": 98.74,
"plotArea": null,
"rooms": 5,
"floor": "3",
"floorNumber": 3,
"totalFloors": 4,
"buildYear": 2001,
"buildingType": "block",
"buildingMaterial": "breezeblock",
"condition": "to_renovation",
"ownershipType": null,
"heating": "gas",
"windowsType": "plastic",
"energyCertificate": null,
"availableFrom": null,
"elevator": false,
"parking": null,
"address": "ul. Eljasza Walerego Radzikowskiego, Azory Zachód, Prądnik Biały, Kraków, małopolskie",
"street": "ul. Eljasza Walerego Radzikowskiego",
"subdistrict": "Azory Zachód",
"district": "Prądnik Biały",
"city": "Kraków",
"province": "małopolskie",
"postalCode": null,
"locationId": "malopolskie/krakow/krakow/krakow/pradnik-bialy/azory-zachod",
"latitude": 50.085896,
"longitude": 19.894537,
"description": "ul. Radzikowskiego 77 ; Kraków Bronowice\nCena: 1 049 000 zł\nMamy przyjemność zaprezentować mieszkanie z potencjałem: 3-poziomowe, 5-pokojowe.\nLokalizacja w jedn...",
"sellerType": "business",
"sellerName": "Anna Kowalska",
"contactName": "Anna Kowalska",
"phone": "+48500000000",
"phones": [
"+48500000000"
],
"contacts": [
{
"name": "Anna Kowalska",
"phone": "+48500000000"
}
],
"agencyId": 100000,
"agencyName": "Przykładowe Nieruchomości",
"agencyUrl": "https://www.otodom.pl/pl/firmy/biura-nieruchomosci/przykladowe-nieruchomosci-ID100000",
"agencyLogo": null,
"agencyAddress": "ul. Przykładowa 1, 30-001 Kraków",
"agencyLicenseNumber": null,
"developmentTitle": null,
"developmentUrl": null,
"isPromoted": false,
"isExclusiveOffer": false,
"isPrivateOwner": false,
"tags": [
"TWO_LEVEL",
"BALCONY"
],
"extras": [
"balcony",
"two_storey"
],
"equipment": [],
"security": [],
"media": [],
"features": [],
"mainImage": "https://ireland.apollo.olxcdn.com/v1/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbiI6InIyb3owMG1pcm5qbjMtQVBMIiwidyI6W3siZm4iOiJlbnZmcXFlMWF5NGsxLUFQTCIsInMiOiIxNiIsImEiOiIwIiwicCI6IjEwLC0xMCJ9XX0.WwySNdLwFfJb4TPtTEBvocUoNukfl1MCOL-eBeaxGDg/image;s=2048x1536;q=80",
"imageCount": 21,
"images": [
"https://ireland.apollo.olxcdn.com/v1/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbiI6InIyb3owMG1pcm5qbjMtQVBMIiwidyI6W3siZm4iOiJlbnZmcXFlMWF5NGsxLUFQTCIsInMiOiIxNiIsImEiOiIwIiwicCI6IjEwLC0xMCJ9XX0.WwySNdLwFfJb4TPtTEBvocUoNukfl1MCOL-eBeaxGDg/image;s=2048x1536;q=80",
"https://ireland.apollo.olxcdn.com/v1/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbiI6IjZ6ZjdxeXN2dHdnNzMtQVBMIiwidyI6W3siZm4iOiJlbnZmcXFlMWF5NGsxLUFQTCIsInMiOiIxNiIsImEiOiIwIiwicCI6IjEwLC0xMCJ9XX0.5qi0Numsmy8GrYDD7Evyei_d7qIz3BPX4rhA-GhdbkM/image;s=2048x1536;q=80"
],
"floorPlans": [
"https://ireland.apollo.olxcdn.com/v1/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbiI6Ind3eHMxZDlqN3ptYTItQVBMIiwidyI6W3siZm4iOiJlbnZmcXFlMWF5NGsxLUFQTCIsInMiOiIxNiIsImEiOiIwIiwicCI6IjEwLC0xMCJ9XX0.-s7ZFBAk4MuainXO50Jjs44IB6yImit646HFWYW5pQk/image",
"https://ireland.apollo.olxcdn.com/v1/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbiI6Im01M3g1ZXJoa3M4cjEtQVBMIiwidyI6W3siZm4iOiJlbnZmcXFlMWF5NGsxLUFQTCIsInMiOiIxNiIsImEiOiIwIiwicCI6IjEwLC0xMCJ9XX0.JLuPxcL-bhTE51JjQ8Gp28uAtgXZKDmgah5TbOxHrO0/image"
],
"videoUrl": null,
"view3dUrl": null,
"referenceId": null,
"status": "active",
"createdAt": "2026-09-20T09:42:37Z",
"modifiedAt": "2026-10-15T22:03:30Z",
"pushedUpAt": "2026-10-16T00:03:30+02:00",
"details": {
"price": "1 049 999 zł",
"price_per_m": "10 633,98 zł/m²",
"m": "98,74 m²",
"market": "secondary",
"building_type": "block"
},
"searchUrl": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/malopolskie/krakow/krakow/krakow",
"detailsScraped": true,
"scrapedAt": "2026-10-15T22:59:18.504Z"
}
You pay $1.50 per 1,000 listings ($0.0015 per listing) plus a small amount of platform usage. A job of 1,000 fully detailed listings cost about $0.03 in platform usage in our tests (compute plus about 24 MB of datacenter traffic), so 1,000 listings ≈ $1.53 in total. You only pay for listings saved to the dataset; "not found" rows are free.
Is it legal to scrape otodom.pl? The actor reads only public listing pages that anyone can open without an account. Make sure your use of the data, especially personal data such as names and phone numbers, complies with GDPR and the site's terms.
Do I need an account or a proxy? No login is needed. The default datacenter proxy works well; you can switch to residential proxies (pinned to Poland) if you ever see blocks.
How many listings can I get? All results of a search: the actor pages through the whole result list (Warsaw flats for sale alone have about 20,000). Use maxItems to cap each search.
Why are some fields empty? Sellers fill in different fields. A missing value means the listing does not show it. New-development pages show pricePerM2From, areaFrom and areaTo instead of a single price.
Can I scrape only search results, without opening every listing? Yes, turn off Fetch full details. Rows then have the search-card data (price, area, rooms, floor, location, agency, photos) and the run is faster and lighter.
Can I schedule it or use the API? Yes. Schedule runs in the console, or start runs and read datasets through the REST API.
Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
startUrlsarrayOptionalStart URLs
otodom.pl search results URLs (any filters you set on the site are kept) or listing URLs. Filters below are added on top of a search URL's own filters.
locationsarrayOptionalLocations
City, district or region names, e.g. 'Kraków', 'Mokotów', 'Gdańsk Wrzeszcz', 'pomorskie'. Each is matched to otodom.pl's own location and searched with the deal, property type and filters below. An otodom location path such as 'malopolskie/krakow/krakow/krakow' also works.
maxItemsintegerOptionaldefault 20Max listings per search
Maximum listings to save for each start URL search and each location. Listing URLs are always saved. 0 means no limit.
transactionenumOptionaldefault "sale"Deal type
Used with Locations.
propertyTypeenumOptionaldefault "flat"Property type
Used with Locations.
marketenumOptionaldefault "all"Market
Primary = new from developer, secondary = resale.
ownerTypeenumOptionaldefault "all"Seller type
Show only listings by this kind of seller.
sortByenumOptionaldefault "default"Sort by
Order of search results.
searchAllPolandbooleanOptionaldefault falseSearch all of Poland
With no Start URLs and no Locations, search the whole country with the settings above.
priceMinintegerOptionalMin price (PLN)
Total price, or monthly rent for rentals.
priceMaxintegerOptionalMax price (PLN)
Total price, or monthly rent for rentals.
pricePerM2MinintegerOptionalMin price per m² (PLN)
Minimum price per square metre.
pricePerM2MaxintegerOptionalMax price per m² (PLN)
Maximum price per square metre.
areaMinintegerOptionalMin area (m²)
Minimum living area.
areaMaxintegerOptionalMax area (m²)
Maximum living area.
roomsMinintegerOptionalMin rooms
Minimum number of rooms (11 means more than 10).
roomsMaxintegerOptionalMax rooms
Maximum number of rooms.
buildYearMinintegerOptionalBuilt from (year)
Earliest construction year.
buildYearMaxintegerOptionalBuilt until (year)
Latest construction year.
plotAreaMinintegerOptionalMin plot area (m²)
Houses and plots only.
plotAreaMaxintegerOptionalMax plot area (m²)
Houses and plots only.
postedWithinDaysenumOptionaldefault ""Posted within (days)
Only listings added recently.
keywordstringOptionalKeyword in description
Only listings whose description contains this text, e.g. 'balkon'.
distanceRadiusenumOptionaldefault "0"Extra radius (km)
Also include listings up to this distance around the location.
fetchDetailsbooleanOptionaldefault trueFetch full details
Open each listing for the description, all features, all photos, GPS, agency details and phone numbers. Turn off for a faster, lighter scan of search results only.
maxConcurrencyintegerOptionaldefault 8Max concurrency
Parallel requests. The site rate-limits aggressive clients, so higher is not always faster.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["DATACENTER…Proxy
Datacenter proxies work well for otodom.pl. Residential proxies are pinned to Poland unless you pick a country.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| id | number | null | |
| agencyId | number | string | null | |
| price | number | null | |
| pricePerM2 | number | null | |
| pricePerM2From | number | null | |
| rentPrice | number | null | |
| deposit | number | null | |
| area | number | null | |
| areaFrom | number | null | |
| areaTo | number | null | |
| plotArea | number | null | |
| rooms | number | null | |
| floorNumber | number | null | |
| totalFloors | number | null | |
| buildYear | number | null | |
| latitude | number | null | |
| longitude | number | null | |
| imageCount | number | null | |
| investmentUnits | number | null | |
| elevator | boolean | null | |
| isPromoted | boolean | null | |
| isExclusiveOffer | boolean | null | |
| isPrivateOwner | boolean | null | |
| detailsScraped | boolean | null | |
| phones | array | null | |
| contacts | array | null | |
| tags | array | null | |
| extras | array | null | |
| equipment | array | null | |
| security | array | null | |
| media | array | null | |
| features | array | null | |
| images | array | null | |
| floorPlans | array | null | |
| details | object | null | |
| url | string | null | |
| title | string | null | |
| transaction | string | null | |
| propertyType | string | null | |
| market | string | null | |
| currency | string | null | |
| floor | string | null | |
| buildingType | string | null | |
| buildingMaterial | string | null | |
| condition | string | null | |
| ownershipType | string | null | |
| heating | string | null | |
| windowsType | string | null | |
| energyCertificate | string | null | |
| availableFrom | string | null | |
| parking | string | null | |
| address | string | null | |
| street | string | null | |
| subdistrict | string | null | |
| district | string | null | |
| city | string | null | |
| county | string | null | |
| province | string | null | |
| postalCode | string | null | |
| locationId | string | null | |
| description | string | null | |
| sellerType | string | null | |
| sellerName | string | null | |
| contactName | string | null | |
| phone | string | null | |
| agencyName | string | null | |
| agencyUrl | string | null | |
| agencyLogo | string | null | |
| agencyAddress | string | null | |
| agencyLicenseNumber | string | null | |
| developmentTitle | string | null | |
| developmentUrl | string | null | |
| mainImage | string | null | |
| videoUrl | string | null | |
| view3dUrl | string | null | |
| referenceId | string | null | |
| status | string | null | |
| createdAt | string | null | |
| modifiedAt | string | null | |
| pushedUpAt | string | null | |
| descriptionHtml | string | null | |
| searchUrl | string | null | |
| scrapedAt | string | null | |
| error | string | null | |
| investmentState | string | null | |
| investmentDelivery | string | null |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Listing | One otodom.pl listing saved (with or without full details). Not-found or failed listings are free. | $0.0015 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('roamandroof/otodom-scraper').call({
"startUrls": [
{
"url": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa/warszawa/warszawa"
}
],
"maxItems": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"DATACENTER"
]
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run roamandroof/otodom-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=roamandroof/otodom-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
Inputs the developer prepared for common jobs. Open one to see its input, then copy it to your account to run it as-is or adjust it.
Listings from an Otodom search URL with details.
Primary market listings from a search URL.
Quick rental list for a city.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.