{
  "openapi": "3.0.1",
  "info": {
    "title": "Otodom.pl Scraper - Property Listings, Prices & Rentals",
    "description": "Scrape Otodom.pl properties for sale and rent, including apartments, houses, plots, commercial spaces, garages, rooms and new developments. Build searches by city, transaction, property type and filters, or paste Otodom URLs directly.",
    "version": "1.0",
    "x-build-id": "TAoRKODFnhs9sfDdH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~otodom-pl-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-otodom-pl-scraper",
        "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/abotapi~otodom-pl-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-otodom-pl-scraper",
        "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/abotapi~otodom-pl-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-otodom-pl-scraper",
        "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": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "1. Search mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Search mode = pick transaction + property type + cities + filters below. URL mode = paste any Otodom search URL refined in a browser (recommended for filters not exposed below, like district/neighborhood).",
            "default": "search"
          },
          "transaction": {
            "title": "Transaction",
            "enum": [
              "sprzedaz",
              "wynajem"
            ],
            "type": "string",
            "description": "Sale (sprzedaż) or rent (wynajem). Used to build the canonical Otodom URL.",
            "default": "sprzedaz"
          },
          "estate": {
            "title": "Property type",
            "enum": [
              "mieszkanie",
              "dom",
              "dzialka",
              "lokal",
              "garaz",
              "inwestycja",
              "pokoj",
              "haleimagazyny"
            ],
            "type": "string",
            "description": "Otodom property type segment. Apartment (mieszkanie), house (dom), plot (działka), commercial (lokal), garage (garaż), investment / new development (inwestycja), room (pokój), halls and warehouses (hale i magazyny).",
            "default": "mieszkanie"
          },
          "locations": {
            "title": "Cities",
            "type": "array",
            "description": "Polish city names. Recognized: Warszawa, Kraków, Wrocław, Gdańsk, Łódź, Poznań, Szczecin, Bydgoszcz, Lublin, Białystok, Katowice, Gdynia, Sopot, Gliwice, Zabrze, Rzeszów, Olsztyn, Toruń, Kielce, Radom, Częstochowa, Bytom, Tychy, Opole, Sosnowiec, plus all 16 voivodeship names. For unknown / smaller cities, leave empty (Poland-wide search) or use URL mode. The cartesian product of property type × city is searched.",
            "items": {
              "type": "string"
            }
          },
          "marketType": {
            "title": "Market type",
            "enum": [
              "all",
              "primary",
              "secondary"
            ],
            "type": "string",
            "description": "Filter by primary (rynek pierwotny, new from developer) or secondary (rynek wtórny, resale). Default = both.",
            "default": "all"
          },
          "minPrice": {
            "title": "Min price (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Lower bound on totalPrice (PLN). Optional."
          },
          "maxPrice": {
            "title": "Max price (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on totalPrice (PLN). Optional."
          },
          "minArea": {
            "title": "Min area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Lower bound on areaInSquareMeters. Optional."
          },
          "maxArea": {
            "title": "Max area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on areaInSquareMeters. Optional."
          },
          "minRooms": {
            "title": "Min rooms",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Minimum number of rooms (1-10)."
          },
          "maxRooms": {
            "title": "Max rooms",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Maximum number of rooms (1-10)."
          },
          "buildYear": {
            "title": "Min build year",
            "minimum": 1900,
            "maximum": 2030,
            "type": "integer",
            "description": "Only listings built in this year or later (1900-2030). Search mode only; listings without a build year on Otodom are excluded by the site."
          },
          "postedDate": {
            "title": "Posted within",
            "enum": [
              "",
              "1",
              "3",
              "7",
              "14"
            ],
            "type": "string",
            "description": "Only listings posted within the last 1, 3, 7 or 14 days. Empty = any time. Search mode only.",
            "default": ""
          },
          "districts": {
            "title": "Districts",
            "type": "array",
            "description": "City districts to search, e.g. Mokotów, Wola (one search per district; Search mode only). Applies to city locations such as Warszawa or Kraków, ignored for voivodeships. Use the district name as written on Otodom.",
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "DEFAULT",
              "LATEST",
              "PRICE_ASC",
              "PRICE_DESC",
              "AREA_ASC",
              "AREA_DESC"
            ],
            "type": "string",
            "description": "Default = newest. Otodom inserts promoted listings ahead of organic order regardless of sort, so sort is best-effort.",
            "default": "DEFAULT"
          },
          "urls": {
            "title": "Search URLs (URL mode)",
            "type": "array",
            "description": "One or more full otodom.pl URLs: a search (city, district, filters, sort, ?page=N), a single listing page (/pl/oferta/...), or an agency profile (/pl/firmy/biura-nieruchomosci/<name>-ID...). Tip: open otodom.pl in your browser, copy the URL from the address bar. Leaving this field untouched scrapes the eight sample URLs listed here. Unsupported pages (new-development detail pages, agency directory lists, m.otodom.pl, /en/ and old-style addresses) are skipped with an error in the log. Search-mode-only fields above (transaction, property type, cities, market type, sort order) are ignored; the price/area/rooms filters above still apply to listings found via search and agency URLs. Pagination starts at the page in the URL and walks forward.",
            "default": [
              "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa/warszawa/warszawa",
              "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/mazowieckie/warszawa/warszawa/warszawa?page=2",
              "https://www.otodom.pl/pl/wyniki/wynajem/mieszkanie/cala-polska?priceMin=1000&priceMax=3000&by=PRICE&direction=ASC",
              "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/cala-polska?ownerTypeSingleSelect=ALL&roomsNumber=%5BTWO%5D&market=PRIMARY",
              "https://www.otodom.pl/pl/wyniki/sprzedaz/mieszkanie/malopolskie/krakow/krakow/krakow/stare-miasto?distanceRadius=5",
              "https://www.otodom.pl/pl/wyniki/sprzedaz/inwestycja/cala-polska",
              "https://www.otodom.pl/pl/oferta/2-pok-46-38-m2-balkon-umeblowane-do-wejscia-0-prowizji-ID4CBFQ",
              "https://www.otodom.pl/pl/firmy/biura-nieruchomosci/hampton-home-nieruchomosci-ID3065052"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "How many SERP pages to walk per city × property type combination (or per pasted URL). Each page returns ~36 listings. Leave empty to walk every result page.",
            "default": 0
          },
          "maxListings": {
            "title": "Max listings (total)",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Stop after this many listings across all searches. 0 = no cap. Values above 1,000,000 are rejected.",
            "default": 20
          },
          "fetchDetails": {
            "title": "Fetch detail pages (richer data, slower)",
            "type": "boolean",
            "description": "When ON, also fetch each listing's detail page for GPS coordinates, full description, agent phone, building year, ownership type, full feature list. SERP cards already carry id, title, price, area, rooms, agency and the cover image. City, province, latitude/longitude, description and contact details come from the detail page, so they are empty when this is off. Default ON.",
            "default": true
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Default = Apify residential with country=PL. Gives clean first-try fetches and the fastest end-to-end wall time."
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run (optional)",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Listings already collected there (matched by id) are skipped, so this run only saves the new ones. Leave empty for a normal fresh run. For ongoing scheduled monitoring of this search, use incrementalMode below instead."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "Turn on when you run this same search on a schedule (e.g. daily) and only want to know what's new or changed since last time. The actor remembers this search's listings itself, no run ID needed. Every field of a listing is compared (price, area, rooms, title, description, address, contact and agency data, features, image count and the rest) except scrapedAt, images, imageUrl, isPromoted and any field you list in the ignore setting at the end of this section; ignored fields stay in the output but never trigger UPDATED. dateModified is the site's own modified-at stamp (it moves when an ad is edited or refreshed); list it to ignore refresh-only changes. Adds changeType (NEW/UPDATED/UNCHANGED/REAPPEARED/EXPIRED), changedFields, firstSeenAt, and lastSeenAt to every row. Off by default so existing scheduled runs are unaffected. See stateKey, emitUnchanged, and emitExpired below.",
            "default": false
          },
          "stateKey": {
            "title": "State key for incremental mode (Optional)",
            "type": "string",
            "description": "Optional label for the incrementalMode baseline. Leave empty to auto-derive one from your search settings (mode/transaction/estate/locations/urls/marketType/price/area/rooms ranges/sort) — a different filter setup automatically gets its own baseline, never sharing one by accident. Set this only if you want multiple differently-configured runs to intentionally share one baseline."
          },
          "emitUnchanged": {
            "title": "Emit unchanged listings (incremental mode)",
            "type": "boolean",
            "description": "When incrementalMode is on, also output listings that are UNCHANGED since the last run (changeType=UNCHANGED, changedFields=[]). Off by default: unchanged listings are silently skipped, so you only see and pay for what's new or different. Turning this on bills extra dataset-item rows for listings that haven't changed.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired listings (incremental mode)",
            "type": "boolean",
            "description": "When incrementalMode is on, also output a row for previously-tracked listings that are no longer found (changeType=EXPIRED), so you can detect delistings. Only emitted after a run that scans the full tracked search with no page/item cap and no resumeFromRunId — a partial run never marks a still-live listing as expired. Off by default. Turning this on bills extra dataset-item rows.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Incremental mode only. Field names to leave out when deciding whether a listing changed (they still appear in the output). Use a dotted path for a nested field, for example agency.name. Fields excluded by default: scrapedAt, images, imageUrl, isPromoted. Example: dateModified, agency.name. Leave empty to compare every other field.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}