# Otodom.pl Scraper — Polish Real Estate Data Extractor (`logiover/otodom-pl-scraper-polish-real-estate-data`) Actor

Scrape real estate listings from Otodom.pl — Poland's #1 property portal. Extract apartments, houses, plots and commercial properties by location, price (PLN), area, rooms and market. Direct NEXT\_DATA access (no browser): price, m², czynsz, GPS, address, agency and image gallery per ad.

- **URL**: https://apify.com/logiover/otodom-pl-scraper-polish-real-estate-data.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Real estate, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Otodom.pl Real Estate Scraper

Extract property listings from **[Otodom.pl](https://www.otodom.pl)** — Poland's #1 real estate portal (OLX Group, 200K+ active listings). Scrape apartments, houses, plots, commercial space, warehouses, garages and rooms by location, transaction type, price (PLN), area, rooms, market and owner type.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com)
[![Direct HTTP](https://img.shields.io/badge/Engine-HTTP%20%2B%20__NEXT_DATA__-brightgreen)]()

---

### How It Works

Otodom is a Next.js SSR site. Every search-results page embeds the full listing payload as JSON inside `<script id="__NEXT_DATA__">`. The actor fetches the HTML once per page via `got-scraping`, parses out the JSON blob, and walks `props.pageProps.data.searchAds.items[]`. **No browser, no cheerio, no GraphQL token.**

GET https://www.otodom.pl/pl/wyniki/{sprzedaz|wynajem}/{type}/{location-slug}
?priceMin=&priceMax=
&areaMin=&areaMax=
&roomsNumber=[ONE,TWO,...]
&market=PRIMARY|SECONDARY|ALL
&ownerTypeSingleSelect=ALL|PRIVATE|BUSINESS
&distanceRadius=0|5|10|15|25|50|75
&by=LATEST|PRICE|PRICE_PER_M|AREA
&direction=ASC|DESC
&limit=24|36|48|72&page={N}

Otodom deploys mild bot defense (no full DataDome/Akamai). **RESIDENTIAL Apify Proxy with `country=PL` is strongly recommended** — datacenter often gets blocked. With residential PL the actor runs cleanly at ≥600ms request delay.

---

### Input

```json
{
  "locationSlugs": ["mazowieckie/warszawa", "malopolskie/krakow"],
  "transaction": "sale",
  "propertyType": "apartment",
  "priceMin": 500000,
  "priceMax": 1500000,
  "areaMin": 40,
  "areaMax": 90,
  "roomsMin": 2,
  "roomsMax": 3,
  "market": "SECONDARY",
  "ownerType": "ALL",
  "sort": "latest",
  "distanceRadius": 0,
  "limit": 72,
  "maxListings": 500,
  "maxPagesPerTask": 10,
  "requestDelay": 800,
  "maxRetries": 3,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "PL" }
}
````

#### Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `locationSlugs` | string\[] | required | URL location paths (each = one task) |
| `transaction` | enum | `sale` | `sale` / `rent` |
| `propertyType` | enum | `apartment` | `apartment` / `house` / `plot` / `commercial` / `warehouse` / `garage` / `room` |
| `priceMin` / `priceMax` | int | `0` | PLN range (0 = no bound) |
| `areaMin` / `areaMax` | int | `0` | m² range |
| `roomsMin` / `roomsMax` | int (1-10) | `0` | Bedroom range |
| `market` | enum | `ALL` | `ALL` / `PRIMARY` (new build) / `SECONDARY` (resale) |
| `ownerType` | enum | `ALL` | `ALL` / `PRIVATE` / `BUSINESS` |
| `sort` | enum | `latest` | `latest` / `price_asc` / `price_desc` / `price_per_m_asc` / `price_per_m_desc` / `area_asc` / `area_desc` |
| `distanceRadius` | enum km | `0` | `0` / `5` / `10` / `15` / `25` / `50` / `75` |
| `limit` | enum | `72` | `24` / `36` / `48` / `72` |
| `maxListings` | int | `200` | Total cap across all locations (0 = unlimited) |
| `maxPagesPerTask` | int | `5` | Pages per location (Otodom caps ~50 pages × 72) |
| `requestDelay` | int (ms) | `800` | Delay between page fetches |
| `maxRetries` | int | `3` | Retries on HTTP 403/429/503 (rotates proxy IP) |
| `proxyConfiguration` | object | `RESIDENTIAL`+`PL` | RESIDENTIAL strongly recommended |

***

### Location Slugs

Location slugs are URL paths Otodom uses internally. To find one: open otodom.pl, apply a location filter, and copy the path between `/wyniki/{txn}/{type}/` and `?` from the URL. Examples:

#### Voivodeships (16)

| Voivodeship | Slug |
|---|---|
| Mazowieckie (Warsaw) | `mazowieckie` |
| Małopolskie (Kraków) | `malopolskie` |
| Dolnośląskie (Wrocław) | `dolnoslaskie` |
| Pomorskie (Gdańsk) | `pomorskie` |
| Wielkopolskie (Poznań) | `wielkopolskie` |
| Śląskie (Katowice) | `slaskie` |
| Łódzkie (Łódź) | `lodzkie` |
| Lubelskie (Lublin) | `lubelskie` |
| Podkarpackie (Rzeszów) | `podkarpackie` |
| Kujawsko-pomorskie (Bydgoszcz) | `kujawsko-pomorskie` |
| Zachodniopomorskie (Szczecin) | `zachodniopomorskie` |
| Warmińsko-mazurskie (Olsztyn) | `warminsko-mazurskie` |
| Świętokrzyskie (Kielce) | `swietokrzyskie` |
| Podlaskie (Białystok) | `podlaskie` |
| Lubuskie (Zielona Góra) | `lubuskie` |
| Opolskie (Opole) | `opolskie` |

#### Major cities (drill in further)

| City | Slug |
|---|---|
| Warszawa | `mazowieckie/warszawa` |
| Kraków | `malopolskie/krakow/krakow/krakow` |
| Wrocław | `dolnoslaskie/wroclaw/wroclaw/wroclaw` |
| Poznań | `wielkopolskie/poznan/poznan/poznan` |
| Gdańsk | `pomorskie/gdansk/gdansk/gdansk` |
| Łódź | `lodzkie/lodz/lodz/lodz` |
| Katowice | `slaskie/katowice/katowice/katowice` |
| Szczecin | `zachodniopomorskie/szczecin/szczecin/szczecin` |
| Lublin | `lubelskie/lublin/lublin/lublin` |
| Bydgoszcz | `kujawsko-pomorskie/bydgoszcz/bydgoszcz/bydgoszcz` |
| Białystok | `podlaskie/bialystok/bialystok/bialystok` |
| Gdynia | `pomorskie/gdynia/gdynia/gdynia` |
| Toruń | `kujawsko-pomorskie/torun/torun/torun` |
| Rzeszów | `podkarpackie/rzeszow/rzeszow/rzeszow` |
| Kielce | `swietokrzyskie/kielce/kielce/kielce` |
| Olsztyn | `warminsko-mazurskie/olsztyn/olsztyn/olsztyn` |
| Wszystkie (all Poland) | `cala-polska` |

For sub-districts append more segments: `mazowieckie/warszawa/warszawa/warszawa/mokotow`, `malopolskie/krakow/krakow/krakow/stare-miasto`, etc.

***

### Output

Example record:

```json
{
  "adId": "67890123",
  "detailUrl": "https://www.otodom.pl/pl/oferta/sprzedam-3-pokojowe-mieszkanie-mokotow-warszawa-ID4abXY",
  "slug": "sprzedam-3-pokojowe-mieszkanie-mokotow-warszawa-ID4abXY",
  "title": "Przestronne 3-pokojowe mieszkanie na Mokotowie",
  "shortDescription": "5 min od metra Wierzbno, balkon, miejsce postojowe.",
  "transactionType": "sale",
  "propertyType": "apartment",
  "advertType": "AGENCY",
  "isPrivate": false,
  "market": "SECONDARY",
  "price": 1250000,
  "priceCurrency": "PLN",
  "pricePerSqm": 17361,
  "rentPrice": null,
  "areaSqm": 72,
  "terrainAreaSqm": null,
  "rooms": 3,
  "floor": "FLOOR_3",
  "totalFloors": 5,
  "province": "mazowieckie",
  "city": "Warszawa",
  "district": "Mokotów",
  "subdistrict": "Stary Mokotów",
  "street": "Puławska",
  "postalCode": "02-595",
  "fullAddress": "Puławska, Stary Mokotów, Mokotów, Warszawa, mazowieckie, 02-595",
  "latitude": 52.1923,
  "longitude": 21.0289,
  "mainImageUrl": "https://ireland.apollo.olxcdn.com/v1/files/.../image.jpg",
  "imageUrls": ["https://ireland.apollo.olxcdn.com/.../1.jpg", "..."],
  "imageCount": 14,
  "agencyId": "12345",
  "agencyName": "Sample Real Estate Sp. z o.o.",
  "agencySlug": "sample-real-estate-warszawa",
  "agencyLogoUrl": "https://...",
  "agencyType": "REGULAR",
  "isExclusive": false,
  "isFeatured": false,
  "isPromoted": true,
  "hasOpenDay": false,
  "investmentName": null,
  "investmentState": null,
  "dateCreated": "2026-04-28T09:14:22+02:00",
  "dateCreatedFirst": "2026-04-15T11:30:00+02:00",
  "pushedUpAt": "2026-05-03T08:00:00+02:00",
  "labels": ["Promowane"],
  "searchTransaction": "sale",
  "searchPropertyType": "apartment",
  "searchLocation": "mazowieckie/warszawa",
  "searchUrl": "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa?limit=72&by=LATEST&direction=DESC&page=1",
  "scrapedAt": "2026-05-04T13:00:00.000Z"
}
```

#### Notes

- **`adId`** is Otodom's stable listing ID (numeric, stored as string).
- **`detailUrl`** built from `slug` (always present in API payload).
- **`floor`** comes as enum strings (`GROUND`, `FLOOR_1`, ..., `CELLAR`, `ATTIC`) — left as raw values.
- **`pricePerSqm`** is taken from API when present, otherwise computed (`price / areaSqm`).
- **`rentPrice`** is the recurring monthly rent for rentals (separate from `price`).
- **`fullAddress`** is composed; for guaranteed accuracy use the original `province`/`city`/`district`/`street` fields.
- **`labels`** are Polish badge texts (`Promowane`, `Wyróżnione`, `Okazja`, etc.).

***

### Use Cases

- **Market research** — PLN/m² heatmaps by voivodeship, city and district
- **Investment screening** — yield = monthly rent / sale price per area
- **Lead generation** — `ownerType: PRIVATE` to find direct-owner listings; agency clusters via `agencyId`
- **Price tracking** — re-run periodically and diff against prior datasets (use `dateCreated` + `pushedUpAt`)
- **Primary-market monitoring** — `market: PRIMARY` to track new developer offers
- **Cross-city comparison** — multiple `locationSlugs` in one run

***

### Cost & Performance

- **Architecture:** HTTP fetch + JSON-blob extraction. No browser, no DOM walking.
- **Throughput:** 72 listings per page, ~1 page/sec at default `requestDelay=800`. ≈ 200 listings in 6-10s with residential proxy.
- **Memory:** 256MB minimum.
- **Compute Units:** ~0.004 CU per 100 listings.

***

### Limitations

- **Listing-level data only** in v1.0. Detail-only fields (full description, energy class, building material, heating, year built, parking spaces, all amenities, exact phone number) require a second per-item HTTP call to `/pl/oferta/{slug}` — planned for v1.1 behind a `fetchDetails` flag.
- **Pagination ceiling** — Otodom caps results around page 50 (× 72 = ~3600 per filter set). The actor detects pagination loops (compares first ID across pages) and stops. Narrow with `priceMin/Max` + `areaMin/Max` to reach deeper inventory.
- **Anti-bot** — datacenter proxies frequently get 403. Residential PL is strongly recommended.
- **Polish diacritics in slugs** — Otodom expects ASCII slugs (`krakow`, not `kraków`). The README table uses ASCII; the actor sends slugs as-is.

***

### Changelog

| Version | Date | Notes |
|---|---|---|
| 1.0.0 | 2026-05-04 | Initial release — direct HTTP + `__NEXT_DATA__` JSON extraction, 7 property types × sale/rent, all 16 voivodeships + drill-down, full filter set (price/area/rooms/market/ownerType/distance/sort), structured output with full Polish address breakdown, GPS, agency embedding, image gallery. |

# Actor input Schema

## `locationSlugs` (type: `array`):

URL location paths from Otodom. Each slug becomes its own scraping task. Use `cala-polska` for nationwide, a voivodeship slug like `mazowieckie`, or a deeper path like `mazowieckie/warszawa` or `malopolskie/krakow/krakow/krakow`. Find one by browsing otodom.pl, applying the location filter, and copying the path between `/wyniki/{txn}/{type}/` and `?` from the URL. Common slugs are listed in the README.

## `transaction` (type: `string`):

Sale (`sprzedaz`) or rent (`wynajem`). Auctions are not exposed via the public listing pages.

## `propertyType` (type: `string`):

Otodom URL category slug.

## `priceMin` (type: `integer`):

Minimum price in Polish złoty. 0 = no minimum.

## `priceMax` (type: `integer`):

Maximum price in Polish złoty. 0 = no maximum.

## `areaMin` (type: `integer`):

Minimum surface area. 0 = no minimum.

## `areaMax` (type: `integer`):

Maximum surface area. 0 = no maximum.

## `roomsMin` (type: `integer`):

Minimum bedroom count (1-10). 0 = no minimum.

## `roomsMax` (type: `integer`):

Maximum bedroom count (1-10). 0 = no maximum.

## `market` (type: `string`):

Primary market = developer / new build. Secondary market = resale. ALL = both.

## `ownerType` (type: `string`):

Filter by who's listing the property.

## `sort` (type: `string`):

Result ordering. Maps to `by` + `direction` query params.

## `distanceRadius` (type: `integer`):

Expand search to nearby areas. Otodom supports 0, 5, 10, 15, 25, 50, 75 km.

## `limit` (type: `integer`):

Page size. Otodom supports 24, 36, 48, 72.

## `maxListings` (type: `integer`):

Total cap across all location tasks (0 = unlimited).

## `maxPagesPerTask` (type: `integer`):

Pagination depth per location. Otodom caps results around page 50 (× 72 = ~3600). Narrow with price/area for deeper inventory.

## `requestDelay` (type: `integer`):

Delay between sequential page requests. Otodom is mildly bot-protected — keep ≥ 600ms.

## `maxRetries` (type: `integer`):

Retries per request on HTTP errors (rotates proxy IP).

## `proxyConfiguration` (type: `object`):

Apify Proxy is recommended. Otodom deploys mild bot defense — RESIDENTIAL with country=PL is strongly recommended; datacenter often gets blocked.

## Actor input object example

```json
{
  "locationSlugs": [
    "mazowieckie/warszawa"
  ],
  "transaction": "sale",
  "propertyType": "apartment",
  "priceMin": 0,
  "priceMax": 0,
  "areaMin": 0,
  "areaMax": 0,
  "roomsMin": 0,
  "roomsMax": 0,
  "market": "ALL",
  "ownerType": "ALL",
  "sort": "latest",
  "distanceRadius": 0,
  "limit": 72,
  "maxListings": 200,
  "maxPagesPerTask": 5,
  "requestDelay": 800,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PL"
  }
}
```

# Actor output Schema

## `adId` (type: `string`):

Otodom listing ID

## `detailUrl` (type: `string`):

Full URL to the listing page

## `slug` (type: `string`):

URL slug

## `title` (type: `string`):

Listing title

## `shortDescription` (type: `string`):

Card-level description snippet

## `transactionType` (type: `string`):

sale / rent

## `propertyType` (type: `string`):

apartment / house / plot / commercial / ...

## `advertType` (type: `string`):

AGENCY / PRIVATE / DEVELOPER (raw)

## `isPrivate` (type: `string`):

True if posted by private owner

## `market` (type: `string`):

PRIMARY (new) / SECONDARY (resale)

## `price` (type: `string`):

Total price

## `priceCurrency` (type: `string`):

Currency (PLN, EUR, USD)

## `pricePerSqm` (type: `string`):

Price per square meter

## `monthlyRent` (type: `string`):

Monthly admin/utility fee (czynsz). Present on both sale and rent listings.

## `areaSqm` (type: `string`):

Usable surface area

## `terrainAreaSqm` (type: `string`):

Plot/terrain area (houses, land)

## `rooms` (type: `string`):

Bedroom count

## `floor` (type: `string`):

Floor number/label (GROUND, FIRST, ...)

## `totalFloors` (type: `string`):

Total floors in the building

## `province` (type: `string`):

Voivodeship

## `city` (type: `string`):

City

## `district` (type: `string`):

District

## `subdistrict` (type: `string`):

Sub-district / quarter

## `street` (type: `string`):

Street name

## `postalCode` (type: `string`):

ZIP / postal code

## `fullAddress` (type: `string`):

Composed address string

## `latitude` (type: `string`):

GPS latitude

## `longitude` (type: `string`):

GPS longitude

## `mainImageUrl` (type: `string`):

Cover photo (large)

## `imageUrls` (type: `string`):

All listing images

## `imageCount` (type: `string`):

Total images

## `agencyId` (type: `string`):

Agency ID

## `agencyName` (type: `string`):

Agency display name

## `agencySlug` (type: `string`):

Agency URL slug

## `agencyLogoUrl` (type: `string`):

Agency logo image URL

## `agencyType` (type: `string`):

Agency category from API

## `isExclusive` (type: `string`):

Exclusive offer flag

## `isFeatured` (type: `string`):

Featured / highlighted listing

## `isPromoted` (type: `string`):

Promoted listing

## `hasOpenDay` (type: `string`):

Has scheduled open day

## `investmentName` (type: `string`):

New-build investment name (primary market)

## `investmentState` (type: `string`):

Construction state

## `dateCreated` (type: `string`):

Most recent post date

## `dateCreatedFirst` (type: `string`):

First-ever post date

## `pushedUpAt` (type: `string`):

Most recent bump

## `labels` (type: `string`):

Listing labels (badges)

## `searchTransaction` (type: `string`):

Transaction used in search

## `searchPropertyType` (type: `string`):

Property type used in search

## `searchLocation` (type: `string`):

Location slug used in search

## `searchUrl` (type: `string`):

Full search URL used

## `scrapedAt` (type: `string`):

ISO timestamp

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locationSlugs": [
        "mazowieckie/warszawa"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "PL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/otodom-pl-scraper-polish-real-estate-data").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "locationSlugs": ["mazowieckie/warszawa"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "PL",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/otodom-pl-scraper-polish-real-estate-data").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locationSlugs": [
    "mazowieckie/warszawa"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PL"
  }
}' |
apify call logiover/otodom-pl-scraper-polish-real-estate-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=logiover/otodom-pl-scraper-polish-real-estate-data",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Otodom.pl Scraper — Polish Real Estate Data Extractor",
        "description": "Scrape real estate listings from Otodom.pl — Poland's #1 property portal. Extract apartments, houses, plots and commercial properties by location, price (PLN), area, rooms and market. Direct NEXT_DATA access (no browser): price, m², czynsz, GPS, address, agency and image gallery per ad.",
        "version": "0.0",
        "x-build-id": "m6k30tvpIrhPsy4Np"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/logiover~otodom-pl-scraper-polish-real-estate-data/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-logiover-otodom-pl-scraper-polish-real-estate-data",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/logiover~otodom-pl-scraper-polish-real-estate-data/runs": {
            "post": {
                "operationId": "runs-sync-logiover-otodom-pl-scraper-polish-real-estate-data",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/logiover~otodom-pl-scraper-polish-real-estate-data/run-sync": {
            "post": {
                "operationId": "run-sync-logiover-otodom-pl-scraper-polish-real-estate-data",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "locationSlugs"
                ],
                "properties": {
                    "locationSlugs": {
                        "title": "Location Slugs",
                        "type": "array",
                        "description": "URL location paths from Otodom. Each slug becomes its own scraping task. Use `cala-polska` for nationwide, a voivodeship slug like `mazowieckie`, or a deeper path like `mazowieckie/warszawa` or `malopolskie/krakow/krakow/krakow`. Find one by browsing otodom.pl, applying the location filter, and copying the path between `/wyniki/{txn}/{type}/` and `?` from the URL. Common slugs are listed in the README.",
                        "default": [
                            "mazowieckie/warszawa"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "transaction": {
                        "title": "Transaction Type",
                        "enum": [
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Sale (`sprzedaz`) or rent (`wynajem`). Auctions are not exposed via the public listing pages.",
                        "default": "sale"
                    },
                    "propertyType": {
                        "title": "Property Type",
                        "enum": [
                            "apartment",
                            "house",
                            "plot",
                            "commercial",
                            "warehouse",
                            "garage",
                            "room"
                        ],
                        "type": "string",
                        "description": "Otodom URL category slug.",
                        "default": "apartment"
                    },
                    "priceMin": {
                        "title": "Min Price (PLN)",
                        "minimum": 0,
                        "maximum": 1000000000,
                        "type": "integer",
                        "description": "Minimum price in Polish złoty. 0 = no minimum.",
                        "default": 0
                    },
                    "priceMax": {
                        "title": "Max Price (PLN)",
                        "minimum": 0,
                        "maximum": 1000000000,
                        "type": "integer",
                        "description": "Maximum price in Polish złoty. 0 = no maximum.",
                        "default": 0
                    },
                    "areaMin": {
                        "title": "Min Area (m²)",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Minimum surface area. 0 = no minimum.",
                        "default": 0
                    },
                    "areaMax": {
                        "title": "Max Area (m²)",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Maximum surface area. 0 = no maximum.",
                        "default": 0
                    },
                    "roomsMin": {
                        "title": "Min Rooms",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Minimum bedroom count (1-10). 0 = no minimum.",
                        "default": 0
                    },
                    "roomsMax": {
                        "title": "Max Rooms",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Maximum bedroom count (1-10). 0 = no maximum.",
                        "default": 0
                    },
                    "market": {
                        "title": "Market",
                        "enum": [
                            "ALL",
                            "PRIMARY",
                            "SECONDARY"
                        ],
                        "type": "string",
                        "description": "Primary market = developer / new build. Secondary market = resale. ALL = both.",
                        "default": "ALL"
                    },
                    "ownerType": {
                        "title": "Owner Type",
                        "enum": [
                            "ALL",
                            "PRIVATE",
                            "BUSINESS"
                        ],
                        "type": "string",
                        "description": "Filter by who's listing the property.",
                        "default": "ALL"
                    },
                    "sort": {
                        "title": "Sort Order",
                        "enum": [
                            "latest",
                            "price_asc",
                            "price_desc",
                            "price_per_m_asc",
                            "price_per_m_desc",
                            "area_asc",
                            "area_desc"
                        ],
                        "type": "string",
                        "description": "Result ordering. Maps to `by` + `direction` query params.",
                        "default": "latest"
                    },
                    "distanceRadius": {
                        "title": "Distance Radius (km)",
                        "minimum": 0,
                        "maximum": 75,
                        "type": "integer",
                        "description": "Expand search to nearby areas. Otodom supports 0, 5, 10, 15, 25, 50, 75 km.",
                        "default": 0
                    },
                    "limit": {
                        "title": "Listings per Page",
                        "minimum": 24,
                        "maximum": 72,
                        "type": "integer",
                        "description": "Page size. Otodom supports 24, 36, 48, 72.",
                        "default": 72
                    },
                    "maxListings": {
                        "title": "Max Listings",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Total cap across all location tasks (0 = unlimited).",
                        "default": 200
                    },
                    "maxPagesPerTask": {
                        "title": "Max Pages per Task",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Pagination depth per location. Otodom caps results around page 50 (× 72 = ~3600). Narrow with price/area for deeper inventory.",
                        "default": 5
                    },
                    "requestDelay": {
                        "title": "Request Delay (ms)",
                        "minimum": 0,
                        "maximum": 30000,
                        "type": "integer",
                        "description": "Delay between sequential page requests. Otodom is mildly bot-protected — keep ≥ 600ms.",
                        "default": 800
                    },
                    "maxRetries": {
                        "title": "Max Retries",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Retries per request on HTTP errors (rotates proxy IP).",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Apify Proxy is recommended. Otodom deploys mild bot defense — RESIDENTIAL with country=PL is strongly recommended; datacenter often gets blocked."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
