# Idealista Scraper — Extract Listings, Prices & Agency Contacts (`muhammadafzal/idealista-scraper`) Actor

Scrape Idealista real estate listings across Spain, Italy & Portugal. Extract price, GPS coordinates, energy rating, rooms, size, photos, and agency contact. DataDome bypass with stealth browser. Export scraped data, run the scraper via API, schedule and monitor runs, or integrate with other tools.

- **URL**: https://apify.com/muhammadafzal/idealista-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Idealista Scraper — Extract Listings, Prices & Agency Contacts

**Scrape Idealista real estate listings across Spain, Italy & Portugal.** Extract price, GPS coordinates, energy rating, rooms, size, photos, and agency contact from any city, region, or full Idealista search URL. DataDome bypass included via stealth browser + residential proxy.

Built for property investors, proptech teams, market analysts, and data brokers who need a reliable **Idealista API** alternative without fighting anti-bot protection.

[![Apify](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.4-blue)](https://www.typescriptlang.org/)
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay_Per_Event-green)](https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event)

### What does Idealista Scraper do?

- Extract Idealista listings across **Spain (idealista.com), Italy (idealista.it), Portugal (idealista.pt)**
- Filter by operation (sale / rent), property type, price, size, bedrooms, bathrooms, and 15+ amenity flags
- Returns **GPS coordinates, energy rating, price/m², rooms, photos, agency contact**
- Up to **1,800 listings per search** (Idealista's hard cap)
- Handles **DataDome anti-bot** automatically — stealth Playwright + warmed residential profile
- Optional detail-page enrichment: address, geo, bathrooms, full amenities, agency phone
- Works on Apify Free plan — proxy rotation, scheduling, webhooks, REST API included

### Why scrape Idealista?

Idealista is the dominant real estate platform in Southern Europe (60M+ monthly visits). Its public listing data is the canonical price signal for:

- **Investors** — yield analysis, neighborhood price tracking, comp sets across Madrid / Barcelona / Milan / Lisbon
- **Proptech & valuation models** — feed AVMs with GPS-accurate, energy-rating-tagged comps
- **Real estate agencies** — competitive monitoring of competitor inventory and pricing
- **Researchers & journalists** — Southern European housing dynamics, EU energy-certificate analysis

Idealista has no public API. This scraper is the practical alternative.

### What data can Idealista Scraper extract?

| Field | Type | Description |
|---|---|---|
| `listingId` | string | Idealista internal listing ID |
| `url` | string | Canonical listing URL |
| `locale` | `ES` \| `IT` \| `PT` | Country site |
| `price` | number | Asking price (€) |
| `pricePerSqm` | number | Price per m² |
| `rooms` | number | Bedroom count |
| `size` | number | Square meters |
| `energyRating` | `A`–`G` \| null | EU Energy Performance Certificate |
| `latitude` / `longitude` | number | GPS coordinates |
| `title` | string | Listing headline |
| `propertyType` | string | Home / office / land / etc. |
| `operation` | `sale` \| `rent` | Listing operation |
| `agencySlug` / `agencyName` | string | Listing agent identifier |
| `agencyPhone` | string | Agency contact phone (fetchDetails) |
| `amenities`, `photos` | array | Features + image URLs |
| `priceHistory` | array | Historical price changes (fetchDetails) |
| `description` | string | Full listing text (fetchDetails) |
| `scraped_at` | string ISO | Scrape timestamp |
| `source_url` | string | Traceability URL |

### How to scrape Idealista listings

#### Quick start

1. Open **Idealista Scraper** on Apify and click **Try for free**
2. Pick **Country** (Spain / Italy / Portugal) and **Operation** (sale / rent)
3. Enter a **Location** — either a slug like `madrid-comunidad_de_madrid` or a full Idealista search URL
4. Set **Max items** (1–1800) and any filters (price, bedrooms, amenities)
5. Toggle **Fetch listing details** if you need address, geo, agency phone (~10× requests)
6. Click **Start** — results stream into the dataset; export as JSON / CSV / Excel / HTML / XML or pull via Apify API

#### Input modes

**Search mode** (recommended for discovery):
```json
{
  "operation": "sale",
  "propertyType": "homes",
  "country": "es",
  "location": "madrid-comunidad_de_madrid",
  "maxItems": 100,
  "sortBy": "mostRecent",
  "minPrice": 200000,
  "maxPrice": 600000,
  "bedrooms": ["2", "3"]
}
````

**URL passthrough mode** (for precise filtered searches):

```json
{
  "startUrls": [{ "url": "https://www.idealista.com/venta-viviendas/madrid-madrid/con-precio-hasta_500000,habitaciones_2-3/" }],
  "maxItems": 500
}
```

`location` accepts an Idealista URL slug **or** a full search URL (passthrough — all UI filters override slug-based behavior). Boolean amenity flags (`balcony`, `terrace`, `lift`, `swimmingPool`, `seaViews`, `luxury`, `virtualTour`, …) map 1:1 to Idealista's filter UI.

### How much does it cost to scrape Idealista?

**Pay-Per-Event pricing** — you only pay for what you scrape.

| Event | Price | When charged |
|---|---|---|
| Actor Start | $0.007 | Once per run (per GB memory) |
| Result item | $0.00085 | Per listing scraped from search page |
| Enriched listing | $0.003 | Per detail page visit (only with `fetchDetails: true`) |

| Volume | Cost (search only) | Typical use |
|---|---|---|
| 1,000 listings | ~$0.85 | One city district, full sweep |
| 10,000 listings | ~$8.50 | ~5 metro searches across Spain |
| 100,000 listings | ~$85.00 | Full Madrid + Barcelona + Valencia snapshot |

`fetchDetails: true` adds $0.003/listing on top — it does not replace the base charge.

**On the Apify Free plan ($5 platform credit), you can extract roughly 5,000+ Idealista listings.** No subscription, no platform fees on top.

### Output example

```json
{
  "listingId": "99887766",
  "url": "https://www.idealista.com/inmueble/99887766/",
  "locale": "ES",
  "price": 450000,
  "pricePerSqm": 4500,
  "rooms": 3,
  "size": 100.0,
  "energyRating": "B",
  "latitude": 40.4168,
  "longitude": -3.7038,
  "title": "Piso en Madrid centro 3 habitaciones",
  "propertyType": "flat",
  "operation": "sale",
  "agencySlug": "inmobiliaria-centro",
  "agencyName": "Inmobiliaria Centro Madrid",
  "agencyPhone": null,
  "amenities": ["lift", "balcony", "air-conditioning"],
  "photos": ["https://img4.idealista.com/blur/..."],
  "priceHistory": null,
  "scraped_at": "2026-06-24T10:00:00.000Z",
  "source_url": "https://www.idealista.com/venta-viviendas/madrid-madrid/"
}
```

Download the full dataset as **JSON, CSV, Excel, HTML, or XML** from the Storage tab, or pull it via the [Apify API](https://docs.apify.com/api/v2).

### Tips

- **Start narrow.** Idealista caps results at ~1,800 per search. Split big metros by district or property type.
- **Skip `fetchDetails` first.** The list-page data covers price, size, rooms, energy rating, GPS for most use cases. Only enable details when you need agency phone or full amenities.
- **Bring your own proxy** for hardened DataDome targets. Spanish residential IPs from Decodo / Bright Data / IPRoyal outperform shared pools.
- **Schedule incremental runs** with `publicationDate=W` (last week) or `T`/`Y` (last 24/48h) to track new inventory cheaply.
- **Geo-fence with the slug.** `madrid-comunidad_de_madrid` ≠ `madrid-madrid` — first is the region, second is the city.

### Integration

#### JavaScript / TypeScript

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

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const input = {
  operation: 'sale',
  propertyType: 'homes',
  country: 'es',
  location: 'madrid-madrid',
  maxItems: 100,
};
const run = await client.actor('USERNAME/idealista-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

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

```python
from apify_client import ApifyClient

client = ApifyClient('<YOUR_API_TOKEN>')
run = client.actor('USERNAME/idealista-scraper').call(run_input={
    'operation': 'sale',
    'propertyType': 'homes',
    'country': 'es',
    'location': 'madrid-madrid',
    'maxItems': 100,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### CLI

```bash
echo '{ "operation": "sale", "country": "es", "location": "madrid-madrid", "maxItems": 50 }' | \
apify call USERNAME/idealista-scraper --silent --output-dataset
```

#### MCP server (for Claude / Cursor / ChatGPT)

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.apify.com/?tools=USERNAME/idealista-scraper",
        "--header",
        "Authorization: Bearer <YOUR_API_TOKEN>"
      ]
    }
  }
}
```

### Is it legal to scrape Idealista?

Our scrapers are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our scrapers, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data (e.g. agent phone numbers published on the listing). Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

### FAQ

**Does it bypass Idealista's DataDome anti-bot?**
Yes. The actor uses Playwright with stealth mode + pre-warmed residential proxy profiles tuned for DataDome. For aggressive blocking, plug in a premium ES residential proxy via `customProxyUrl`.

**Can I scrape Spain, Italy, and Portugal in one run?**
One country per run — the `country` input is single-select (`es` / `it` / `pt`). Schedule three runs in parallel; Apify routes each to the correct residential proxy region.

**Is there an official Idealista API?**
Idealista offers a partner API to licensed real estate agencies only (no public access, requires application + commercial agreement). This actor is the practical alternative for everyone else.

**What's the 1,800-listing cap?**
Idealista limits search results to ~1,800 per query. For larger markets, split by district, property subtype, or price band. Combine results downstream.

**How fresh is the data?**
Live — every run hits Idealista directly. Schedule runs hourly / daily via Apify Scheduler for continuous monitoring.

### Support

For feature requests, custom scraping work, or dedicated SLAs, contact us through the Apify Store actor page.

# Actor input Schema

## `startUrls` (type: `array`):

Use this field when the user provides one or more full Idealista search URLs (e.g. https://www.idealista.com/venta-viviendas/madrid-madrid/). Do NOT use this when the user describes a city or location — use location/country/operation instead. All UI filters in the URL are respected as passthrough.

## `operation` (type: `string`):

Listing operation: sale or rent. Use with location + country. Ignored when startUrls is provided.

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

Type of property to scrape. Ignored when startUrls is provided.

## `country` (type: `string`):

Idealista country site. es=idealista.com, it=idealista.it, pt=idealista.pt. Determines residential proxy region.

## `location` (type: `string`):

Idealista location URL slug (e.g. 'madrid-comunidad\_de\_madrid' or 'barcelona-barcelona') OR a plain city name (best-effort resolution). Use this when the user names a place — NOT when they provide a full URL (use startUrls for URLs).

## `maxItems` (type: `integer`):

Maximum number of listings to extract. Idealista caps search results at ~1800 per query. The actor will split queries by price band to bypass this cap when set above 1500.

## `sortBy` (type: `string`):

Sorting method applied to search results.

## `minPrice` (type: `integer`):

Minimum price filter. 0 = any.

## `maxPrice` (type: `integer`):

Maximum price filter. 0 = any.

## `minSize` (type: `integer`):

Minimum size in square meters. 0 = any.

## `maxSize` (type: `integer`):

Maximum size in square meters. 0 = any.

## `publicationDate` (type: `string`):

Filter by publication recency. Empty = any. Use W/T/M for incremental scheduled runs.

## `bedrooms` (type: `array`):

Bedroom counts to include. Empty = any. Idealista uses '0','1','2','3','4','5'.

## `bathrooms` (type: `array`):

Bathroom counts to include. Empty = any.

## `homeType` (type: `array`):

Home subtypes. Only used when propertyType=homes. Empty = any.

## `condition` (type: `array`):

Property condition filter. Empty = any.

## `floor` (type: `array`):

Floor positions. Empty = any.

## `airConditioning` (type: `boolean`):

Only show listings with air conditioning.

## `fittedWardrobes` (type: `boolean`):

Only show listings with fitted wardrobes.

## `lift` (type: `boolean`):

Only show listings with a lift.

## `balcony` (type: `boolean`):

Only show listings with a balcony.

## `terrace` (type: `boolean`):

Only show listings with a terrace.

## `exterior` (type: `boolean`):

Only show exterior-facing listings.

## `garage` (type: `boolean`):

Only show listings with garage / parking.

## `garden` (type: `boolean`):

Only show listings with a garden.

## `swimmingPool` (type: `boolean`):

Only show listings with swimming pool.

## `storageRoom` (type: `boolean`):

Only show listings with storage room.

## `accessible` (type: `boolean`):

Only show wheelchair-accessible listings.

## `seaViews` (type: `boolean`):

Only show listings with sea views.

## `luxury` (type: `boolean`):

Only show luxury listings.

## `plan` (type: `boolean`):

Only show listings with floor plan.

## `virtualTour` (type: `boolean`):

Only show listings with virtual tour.

## `fetchDetails` (type: `boolean`):

Visit each listing's detail page to enrich with address, geo coords, bathrooms, energy rating, agency phone, and full amenities. ~10× more requests — slower and higher block risk. Adds the 'enriched-listing' charge on top of standard dataset-item billing.

## `maxConcurrency` (type: `integer`):

Maximum concurrent browser pages for detail-page fetches. Lower for hardened DataDome regions.

## `customProxyUrl` (type: `string`):

Optional: full proxy URL (http://user:pass@host:port). Overrides Apify proxy. Recommended for hardened DataDome targets — Apify residential pool may be burned. Use Decodo / Bright Data / IPRoyal ES residential.

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

Apify proxy. Defaults to residential Spain (ES). Change apifyProxyCountry to IT or PT when scraping idealista.it / idealista.pt.

## Actor input object example

```json
{
  "startUrls": [],
  "operation": "sale",
  "propertyType": "homes",
  "country": "es",
  "location": "madrid-madrid",
  "maxItems": 100,
  "sortBy": "relevance",
  "minPrice": 0,
  "maxPrice": 0,
  "minSize": 0,
  "maxSize": 0,
  "publicationDate": "",
  "bedrooms": [],
  "bathrooms": [],
  "homeType": [],
  "condition": [],
  "floor": [],
  "airConditioning": false,
  "fittedWardrobes": false,
  "lift": false,
  "balcony": false,
  "terrace": false,
  "exterior": false,
  "garage": false,
  "garden": false,
  "swimmingPool": false,
  "storageRoom": false,
  "accessible": false,
  "seaViews": false,
  "luxury": false,
  "plan": false,
  "virtualTour": false,
  "fetchDetails": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Array of extracted Idealista listings. Each item includes listingId, url, locale, price, pricePerSqm, rooms, size, energyRating, latitude, longitude, title, propertyType, operation, agencySlug, agencyName, agencyPhone, amenities, photos, description, floor, elevator, parking, garage, priceHistory, scraped\_at, source\_url.

# 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 = {
    "startUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/idealista-scraper").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 = { "startUrls": [] }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/idealista-scraper").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 '{
  "startUrls": []
}' |
apify call muhammadafzal/idealista-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=muhammadafzal/idealista-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Idealista Scraper — Extract Listings, Prices & Agency Contacts",
        "description": "Scrape Idealista real estate listings across Spain, Italy & Portugal. Extract price, GPS coordinates, energy rating, rooms, size, photos, and agency contact. DataDome bypass with stealth browser. Export scraped data, run the scraper via API, schedule and monitor runs, or integrate with other tools.",
        "version": "1.0",
        "x-build-id": "WaYl44tXYcZM7Vbt0"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/muhammadafzal~idealista-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-muhammadafzal-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/muhammadafzal~idealista-scraper/runs": {
            "post": {
                "operationId": "runs-sync-muhammadafzal-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/muhammadafzal~idealista-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-muhammadafzal-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",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs (full Idealista search URLs)",
                        "type": "array",
                        "description": "Use this field when the user provides one or more full Idealista search URLs (e.g. https://www.idealista.com/venta-viviendas/madrid-madrid/). Do NOT use this when the user describes a city or location — use location/country/operation instead. All UI filters in the URL are respected as passthrough.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "url": {
                                    "title": "URL",
                                    "type": "string",
                                    "description": "Full Idealista search URL (e.g. https://www.idealista.com/venta-viviendas/madrid-madrid/). All UI filters in the URL are respected as passthrough."
                                }
                            },
                            "required": [
                                "url"
                            ]
                        }
                    },
                    "operation": {
                        "title": "Operation",
                        "enum": [
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Listing operation: sale or rent. Use with location + country. Ignored when startUrls is provided.",
                        "default": "sale"
                    },
                    "propertyType": {
                        "title": "Property Type",
                        "enum": [
                            "homes",
                            "newDevelopments",
                            "offices",
                            "premises",
                            "garages",
                            "lands",
                            "storageRooms",
                            "buildings",
                            "bedrooms"
                        ],
                        "type": "string",
                        "description": "Type of property to scrape. Ignored when startUrls is provided.",
                        "default": "homes"
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "es",
                            "it",
                            "pt"
                        ],
                        "type": "string",
                        "description": "Idealista country site. es=idealista.com, it=idealista.it, pt=idealista.pt. Determines residential proxy region.",
                        "default": "es"
                    },
                    "location": {
                        "title": "Location (URL slug or city name)",
                        "type": "string",
                        "description": "Idealista location URL slug (e.g. 'madrid-comunidad_de_madrid' or 'barcelona-barcelona') OR a plain city name (best-effort resolution). Use this when the user names a place — NOT when they provide a full URL (use startUrls for URLs).",
                        "default": "madrid-madrid"
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 1800,
                        "type": "integer",
                        "description": "Maximum number of listings to extract. Idealista caps search results at ~1800 per query. The actor will split queries by price band to bypass this cap when set above 1500.",
                        "default": 100
                    },
                    "sortBy": {
                        "title": "Sort By",
                        "enum": [
                            "relevance",
                            "lowestPrice",
                            "highestPrice",
                            "mostRecent",
                            "biggest",
                            "smallest",
                            "lowestPriceM2",
                            "highestPriceM2"
                        ],
                        "type": "string",
                        "description": "Sorting method applied to search results.",
                        "default": "relevance"
                    },
                    "minPrice": {
                        "title": "Min price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum price filter. 0 = any.",
                        "default": 0
                    },
                    "maxPrice": {
                        "title": "Max price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum price filter. 0 = any.",
                        "default": 0
                    },
                    "minSize": {
                        "title": "Min size (m²)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum size in square meters. 0 = any.",
                        "default": 0
                    },
                    "maxSize": {
                        "title": "Max size (m²)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum size in square meters. 0 = any.",
                        "default": 0
                    },
                    "publicationDate": {
                        "title": "Publication date",
                        "enum": [
                            "",
                            "Y",
                            "T",
                            "W",
                            "M"
                        ],
                        "type": "string",
                        "description": "Filter by publication recency. Empty = any. Use W/T/M for incremental scheduled runs.",
                        "default": ""
                    },
                    "bedrooms": {
                        "title": "Bedrooms",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Bedroom counts to include. Empty = any. Idealista uses '0','1','2','3','4','5'.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "bathrooms": {
                        "title": "Bathrooms",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Bathroom counts to include. Empty = any.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "homeType": {
                        "title": "Home type",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Home subtypes. Only used when propertyType=homes. Empty = any.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "condition": {
                        "title": "Condition",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Property condition filter. Empty = any.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "floor": {
                        "title": "Floor",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Floor positions. Empty = any.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "airConditioning": {
                        "title": "Air conditioning",
                        "type": "boolean",
                        "description": "Only show listings with air conditioning.",
                        "default": false
                    },
                    "fittedWardrobes": {
                        "title": "Fitted wardrobes",
                        "type": "boolean",
                        "description": "Only show listings with fitted wardrobes.",
                        "default": false
                    },
                    "lift": {
                        "title": "Lift",
                        "type": "boolean",
                        "description": "Only show listings with a lift.",
                        "default": false
                    },
                    "balcony": {
                        "title": "Balcony",
                        "type": "boolean",
                        "description": "Only show listings with a balcony.",
                        "default": false
                    },
                    "terrace": {
                        "title": "Terrace",
                        "type": "boolean",
                        "description": "Only show listings with a terrace.",
                        "default": false
                    },
                    "exterior": {
                        "title": "Exterior",
                        "type": "boolean",
                        "description": "Only show exterior-facing listings.",
                        "default": false
                    },
                    "garage": {
                        "title": "Garage",
                        "type": "boolean",
                        "description": "Only show listings with garage / parking.",
                        "default": false
                    },
                    "garden": {
                        "title": "Garden",
                        "type": "boolean",
                        "description": "Only show listings with a garden.",
                        "default": false
                    },
                    "swimmingPool": {
                        "title": "Swimming pool",
                        "type": "boolean",
                        "description": "Only show listings with swimming pool.",
                        "default": false
                    },
                    "storageRoom": {
                        "title": "Storage room",
                        "type": "boolean",
                        "description": "Only show listings with storage room.",
                        "default": false
                    },
                    "accessible": {
                        "title": "Accessible",
                        "type": "boolean",
                        "description": "Only show wheelchair-accessible listings.",
                        "default": false
                    },
                    "seaViews": {
                        "title": "Sea views",
                        "type": "boolean",
                        "description": "Only show listings with sea views.",
                        "default": false
                    },
                    "luxury": {
                        "title": "Luxury",
                        "type": "boolean",
                        "description": "Only show luxury listings.",
                        "default": false
                    },
                    "plan": {
                        "title": "Floor plan available",
                        "type": "boolean",
                        "description": "Only show listings with floor plan.",
                        "default": false
                    },
                    "virtualTour": {
                        "title": "Virtual tour available",
                        "type": "boolean",
                        "description": "Only show listings with virtual tour.",
                        "default": false
                    },
                    "fetchDetails": {
                        "title": "⭐ Fetch listing details (richer data, slower)",
                        "type": "boolean",
                        "description": "Visit each listing's detail page to enrich with address, geo coords, bathrooms, energy rating, agency phone, and full amenities. ~10× more requests — slower and higher block risk. Adds the 'enriched-listing' charge on top of standard dataset-item billing.",
                        "default": false
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Maximum concurrent browser pages for detail-page fetches. Lower for hardened DataDome regions.",
                        "default": 3
                    },
                    "customProxyUrl": {
                        "title": "Custom Proxy URL (BYO premium residential)",
                        "type": "string",
                        "description": "Optional: full proxy URL (http://user:pass@host:port). Overrides Apify proxy. Recommended for hardened DataDome targets — Apify residential pool may be burned. Use Decodo / Bright Data / IPRoyal ES residential."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Apify proxy. Defaults to residential Spain (ES). Change apifyProxyCountry to IT or PT when scraping idealista.it / idealista.pt.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "ES"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
