{
  "openapi": "3.0.1",
  "info": {
    "title": "Idealista Scraper - Property Listings, Prices & Contacts",
    "description": "From $1/1K. Scrape Idealista properties across Spain, Italy, and Portugal. Extract 35+ fields including prices, sizes, rooms, coordinates, advertiser contacts, phone numbers, descriptions, and photos. Supports properties for sale, rent, and rooms.",
    "version": "1.1",
    "x-build-id": "7gdn27Xs10BFqXrAQ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~idealista-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-idealista-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~idealista-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-idealista-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~idealista-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-idealista-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": "Search Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "How to find listings. 'Search by Location' builds URLs from the fields below; 'Direct URLs' scrapes the idealista search URLs you paste.",
            "default": "search"
          },
          "market": {
            "title": "Market",
            "enum": [
              "es",
              "it",
              "pt"
            ],
            "type": "string",
            "description": "Which idealista market to search (Search mode only). URL mode infers the market from each URL.",
            "default": "es"
          },
          "operation": {
            "title": "Operation",
            "enum": [
              "sale",
              "rent",
              "room"
            ],
            "type": "string",
            "description": "Buy, rent, or rent a room (Search mode only).",
            "default": "sale"
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "idealista location slugs (Search mode only). Examples: ES 'madrid-madrid', 'barcelona-barcelona'; IT 'roma-roma', 'milano-milano'; PT 'lisboa', 'porto'. Tip: open the area on idealista and copy the slug from the URL.",
            "items": {
              "type": "string"
            }
          },
          "minPrice": {
            "title": "Min Price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum price in EUR (Search mode only; in URL mode the pasted URL's own filters apply). Sent to idealista as its own price filter and re-checked on every result."
          },
          "maxPrice": {
            "title": "Max Price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum price in EUR (Search mode only). Sent to idealista as its own price filter and re-checked on every result."
          },
          "minBedrooms": {
            "title": "Min Bedrooms",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Minimum number of bedrooms (Search mode only). Sent to idealista as its room filter and re-checked on every result (idealista.pt shows no room count on result cards, so there the site's own T0-T5 filter decides). Italy counts rooms (locali)."
          },
          "maxBedrooms": {
            "title": "Max Bedrooms",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of bedrooms (Search mode only). Sent to idealista as its room filter and re-checked on every result (idealista.pt: site filter only; Italy counts rooms)."
          },
          "minSize": {
            "title": "Min Size (m2)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum built area in square metres (Search mode only). Sent to idealista as its size filter and re-checked on every result."
          },
          "maxSize": {
            "title": "Max Size (m2)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum built area in square metres (Search mode only). Sent to idealista as its size filter and re-checked on every result."
          },
          "bathrooms": {
            "title": "Bathrooms",
            "enum": [
              "1",
              "2",
              "3+"
            ],
            "type": "string",
            "description": "idealista's own bathrooms filter (Search mode only): exactly 1, exactly 2, or 3 and more. Leave empty for any."
          },
          "propertyTypes": {
            "title": "Property types",
            "type": "array",
            "description": "Restrict the search to these property types (Search mode only). Leave empty for all. 'House / villa' is idealista's chalets (ES), ville (IT) or moradias (PT) category.",
            "items": {
              "type": "string",
              "enum": [
                "flat",
                "penthouse",
                "duplex",
                "loft",
                "house"
              ],
              "enumTitles": [
                "Flat / apartment",
                "Penthouse",
                "Duplex",
                "Loft",
                "House / villa"
              ]
            }
          },
          "features": {
            "title": "Must have (all selected)",
            "type": "array",
            "description": "Only listings that have every selected feature (Search mode only), using idealista's own filters.",
            "items": {
              "type": "string",
              "enum": [
                "elevator",
                "parking",
                "terrace",
                "balcony",
                "garden",
                "pool",
                "airConditioning",
                "storage",
                "wardrobes"
              ],
              "enumTitles": [
                "Lift / elevator",
                "Garage / parking",
                "Terrace",
                "Balcony",
                "Garden",
                "Swimming pool",
                "Air conditioning",
                "Storage room",
                "Built-in wardrobes"
              ]
            }
          },
          "conditions": {
            "title": "Condition",
            "type": "array",
            "description": "Restrict to these conditions (Search mode only). Leave empty for any.",
            "items": {
              "type": "string",
              "enum": [
                "newBuild",
                "good",
                "toRenovate"
              ],
              "enumTitles": [
                "New build",
                "Good condition",
                "To renovate"
              ]
            }
          },
          "publishedWithin": {
            "title": "Published within",
            "enum": [
              "24h",
              "48h",
              "week",
              "month"
            ],
            "type": "string",
            "description": "Only listings published within this window (Search mode only, idealista.com Spain; ignored with a warning on Italy and Portugal)."
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "priceAsc",
              "priceDesc",
              "newest",
              "pricePerSqmAsc",
              "pricePerSqmDesc",
              "sizeDesc",
              "sizeAsc",
              "priceDrops"
            ],
            "type": "string",
            "description": "Order of results (Search mode only). Leave empty for idealista's default relevance order. With a listing cap, sorting decides which listings are collected first. In URL mode the pasted URL's own sort applies."
          },
          "urls": {
            "title": "Search URLs",
            "type": "array",
            "description": "idealista search URLs to scrape (URL mode only). Multi-URL supported. Filter fields are ignored in this mode. Pagination starts at the page in the URL and walks forward. Supported shapes: search, pagina-N / lista-N pages, path filters (con-...), ?ordenado-por sorting, districts, provinces, /geo/ areas, /pro/ agency pages, other property types, /en/ prefix, map view (rewritten to the list) on idealista.com and idealista.it. Agencies directories, new-build promotion pages and single listing pages are skipped with a warning. Leave the field untouched to scrape one example per shape.",
            "default": [
              "https://www.idealista.com/venta-viviendas/madrid-madrid/",
              "https://www.idealista.com/venta-viviendas/madrid-madrid/pagina-2.htm",
              "https://www.idealista.com/venta-viviendas/madrid-madrid/con-metros-cuadrados-mas-de_80/",
              "https://www.idealista.com/venta-viviendas/madrid-madrid/?ordenado-por=precios-asc",
              "https://www.idealista.com/alquiler-viviendas/madrid-madrid/",
              "https://www.idealista.com/venta-viviendas/madrid/centro/",
              "https://www.idealista.com/venta-viviendas/madrid-provincia/",
              "https://www.idealista.com/geo/venta-viviendas/canorroto/",
              "https://www.idealista.com/pro/engel-volkers-madrid/",
              "https://www.idealista.com/venta-garajes/madrid-madrid/",
              "https://www.idealista.com/en/venta-viviendas/madrid-madrid/",
              "https://www.idealista.com/venta-viviendas/madrid-madrid/mapa-google",
              "https://www.idealista.it/vendita-case/roma-roma/",
              "https://www.idealista.it/affitto-case/milano-milano/lista-2.htm"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max Pages Per Search",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum pages to paginate per search (30 listings per page). 0 means no limit of your own: the actor stops at idealista's own ceiling of 60 pages (about 1,800 listings) per search, and the run is also bounded by Max Listings. Lower it only for quick test runs.",
            "default": 0
          },
          "maxListings": {
            "title": "Max Listings",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum listings to return across all searches. Set 0 for unlimited. For large pulls (e.g. 10,000), provide many locations or filtered URLs: idealista shows at most about 1,800 listings (page 60) per single search, so big runs must be partitioned across several areas or price bands.",
            "default": 100
          },
          "maxConcurrency": {
            "title": "Detail Concurrency",
            "minimum": 1,
            "maximum": 12,
            "type": "integer",
            "description": "Parallel detail-page fetches when Fetch Detail Pages is on. Higher is faster but puts more load on the proxy. 1 to 12.",
            "default": 6
          },
          "fetchDetails": {
            "title": "Fetch Detail Pages",
            "type": "boolean",
            "description": "Open each listing's detail page to add coordinates, agent and phone, full description, all photos, bathrooms, condition, orientation, and heating. Turn off for a faster, lighter run with SERP fields only.",
            "default": true
          },
          "proxy": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Residential proxy in the listing's country is strongly recommended. The actor defaults the country to the chosen market and rotates across EU pools when needed."
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for listings already collected there. Use this after an interrupted run, or when continuing a big pull across another run. For recurring monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings. A listing counts as UPDATED when any returned field changes (price, title, features, description, images, coordinates and so on), compared against the last saved copy; only the scrape timestamp (scrapedAt) is always excluded, and you can exclude more with \"Ignore fields when detecting changes\". Turn on \"Emit unchanged\" or \"Emit expired\" only when you also want those listings returned (and billed). State is kept separately for each search/URL and filter setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/URL and filter settings — different searches then never mix state with each other."
          },
          "emitUnchanged": {
            "title": "Emit unchanged listings (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired listings (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search from its first page — not when Max Listings or Max Pages capped it, when a pasted URL starts at page 2 or later, or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "uniqueItems": true,
            "type": "array",
            "description": "Field names that must NOT make a listing count as UPDATED. They stay in the returned data; they are only left out of the change comparison and out of the changedFields list. Use a top-level name (images) or a dotted path to a nested key (coordinates.latitude). Applied to the saved copy too, so adding a field here does not cause a one-time wave of UPDATED rows.",
            "items": {
              "type": "string"
            }
          },
          "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}