Idealista Scraper icon

Idealista Scraper

From $1/1K. Scrape Idealista properties across Spain, Italy, and Portugal. Extract 35+ fields including prices, sizes, rooms, coordinates, advertiser…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

Idealista Scraper at a glance

Idealista Scraper is a ready-to-run Apify actor from abotapi for collecting real estate data. Its documented output includes id, title, change type (incremental mode), operation and price, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $1.70 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Real Estate, Automation, Developer Tools
Pricing
$1.70 per 1,000 results (Free plan), from $1.00 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
29 options

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.

What Idealista Scraper can do

  • Three markets, one actor. Spain, Italy and Portugal, selected per run in Search mode; URL mode detects the market automatically from each pasted link.
  • 50+ fields on full detail. Price per m2, energy rating, GPS coordinates, advertiser name, phone when the listing page shows it, construction year, the complete description and up to 40 deduplicated photos.
  • Two ways to search. Build a search from a location, operation and filters, or paste any idealista search URL directly. Multiple URLs and forward pagination are supported.
  • Buy, rent or room listings in every market, with idealista's own search filters in Search mode (price, size, bedrooms, bathrooms, property type, features, condition, freshness and sort order), built into the search itself so they work the same way across Spain, Italy and Portugal.
  • Detail enrichment on demand. Turn it off for a fast run with search-result fields only, or on for the full record, one extra page fetch per listing.
  • Built for schedules. Incremental mode returns only new, updated and reappeared listings on recurring runs, and a run that cannot reach the site fails loudly instead of returning an empty dataset.

Choose what to collect

These inputs let you configure Idealista Scraper - Property Listings, Prices & Contacts. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · requiredHow to find listings. 'Search by Location' builds URLs from the fields below; 'Direct URLs' scrapes the idealista search URLs you paste.

Choices: search, url

marketstringWhich idealista market to search (Search mode only). URL mode infers the market from each URL.

Choices: es, it, pt

operationstringBuy, rent, or rent a room (Search mode only).

Choices: sale, rent, room

locationsarrayidealista 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.
minPriceintegerMinimum 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.
maxPriceintegerMaximum price in EUR (Search mode only). Sent to idealista as its own price filter and re-checked on every result.
minBedroomsintegerMinimum 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).
Show 22 more inputs
More input fields
InputWhat it controls
maxBedroomsintegerMaximum 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).
minSizeintegerMinimum built area in square metres (Search mode only). Sent to idealista as its size filter and re-checked on every result.
maxSizeintegerMaximum built area in square metres (Search mode only). Sent to idealista as its size filter and re-checked on every result.
bathroomsstringidealista's own bathrooms filter (Search mode only): exactly 1, exactly 2, or 3 and more. Leave empty for any.

Choices: 1, 2, 3+

propertyTypesarrayRestrict 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.
featuresarrayOnly listings that have every selected feature (Search mode only), using idealista's own filters.
conditionsarrayRestrict to these conditions (Search mode only). Leave empty for any.
publishedWithinstringOnly listings published within this window (Search mode only, idealista.com Spain; ignored with a warning on Italy and Portugal).

Choices: 24h, 48h, week, month

sortBystringOrder 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.

Choices: priceAsc, priceDesc, newest, pricePerSqmAsc, pricePerSqmDesc, sizeDesc, sizeAsc, priceDrops

urlsarrayidealista 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.
maxPagesintegerMaximum 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.
maxListingsintegerMaximum 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.
fetchDetailsbooleanOpen 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.
resumeFromRunIdstringPaste 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.
incrementalModebooleanTurn 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.
stateKeystringOptional. 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.
emitUnchangedbooleanOff 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.
emitExpiredbooleanOff 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.
ignoreFieldsForChangesarrayField 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.
mcpConnectorsarrayOptionally 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).
notionParentPageUrlstringURL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

idID (text)
titleTitle (text)
changeTypeChange type (incremental mode) (text)
operationOperation (text)
pricePrice (number)
pricePerM2Price/m2 (number)
currencyCurrency (text)
roomsRooms (number)
bathroomsBaths (number)
sizeSize (m2) (number)
propertyTypeType (text)
energyConsumptionRatingEnergy (text)
Show 10 more fields
marketMarket (text)
latitudeLat (number)
longitudeLng (number)
advertiserNameAdvertiser (text)
phonePhone (text)
urlURL (link)
changedFieldsChanged fields (incremental mode) (text)
firstSeenAtFirst seen at (incremental mode) (text)
lastSeenAtLast seen at (incremental mode) (text)
provinceProvince (text)

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "id": "00000001",
  "url": "https://www.idealista.com/inmueble/00000001/",
  "market": "ES",
  "operation": "sale",
  "title": "Piso en Calle Ejemplo",
  "propertyType": "flat",
  "price": 450000,
  "priceText": "450.000 EUR",
  "pricePerM2": 4737,
  "previousPrice": 480000,
  "priceDropped": true,
  "currency": "EUR",
  "size": 95,
  "rooms": 3,
  "bathrooms": 2,
  "floor": "3rd floor with lift",
  "hasLift": true,
  "hasTerrace": true,
  "hasHomeStaging": false,
  "orientation": "South facing",
  "heating": "Central heating",
  "condition": "Second hand, good condition",
  "constructionYear": 1985,
  "energyConsumptionRating": "D",
  "energyEmissionsRating": "D",
  "reference": "REF-0001",
  "lastUpdatedText": "Listing updated on 1 January",
  "description": "Full advertiser description text appears here when fetchDetails is on.",
  "latitude": 40,
  "longitude": -3,
  "address": "Example District, Example City",
  "neighborhood": "Example District",
  "city": "Example City",
  "province": "Example Province",
  "photoCount": 24,
  "isBranded": true,
  "isProfessionalAd": true,
  "hasVideo": true,
  "has3DTour": false,
  "hasFloorPlan": true,
  "advertiserName": "Sample Agency",
  "advertiserType": "professional",
  "phone": "+34 000 000 000",
  "features": [
    "95 m2 construidos",
    "3 habitaciones",
    "2 baños",
    "Terraza"
  ],
  "images": [
    "https://img4.idealista.com/blur/WEB_DETAIL/0/id.pro.es.image.master/00/00/00/000000000.jpg"
  ],
  "imageCount": 24,
  "imageTags": [
    {
      "url": "https://img4.idealista.com/blur/WEB_DETAIL/0/id.pro.es.image.master/00/00/00/000000000.jpg",
      "tag": "Cocina"
    }
  ],
  "tags": [
    "price drop"
  ],
  "source": "www.idealista.com",
  "scrapedAt": "2026-01-01T00:00:00.000000+00:00"
}

Ways to use this data

  • Real estate investors and flippers: track price drops and new listings across three markets to spot deals early.
  • Market researchers and analysts: build historical price-per-m2 and rent datasets by neighborhood and city.
  • Relocation and property agencies: aggregate cross-market listings into one feed for clients comparing Spain, Italy and Portugal.
  • Lead generation teams: capture advertiser names and phone numbers from professional listings for outreach.
  • Journalists and academics: monitor housing supply, price trends and listing turnover over time.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does Idealista Scraper return?

The documented output for Idealista Scraper includes id, title, change type (incremental mode), operation, price, price/m2, currency and rooms. Availability of each field depends on the source page and the selected mode.

How much does Idealista Scraper cost?

It costs $1.70 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only NEW, UPDATED and REAPPEARED listings for the same search, and unchanged ones are not billed unless you turn on Emit unchanged. REAPPEARED only ever appears for a listing that was previously marked EXPIRED, and EXPIRED itself only happens when Emit expired listings is on and an earlier run fully scanned the tracked search without a cap or a resume getting in the way.

Why did my run fail instead of returning an empty dataset?

If every attempt to read the search results is refused, the run fails outright with a clear message instead of returning zero listings, so "no matches for this search" is never confused with "the site could not be read". If only part of a run was refused, for example one location out of several, the run still succeeds and returns what it found, with a status message noting the run is incomplete. If a run is nearing its own platform time limit, it stops opening new detail pages and returns the listing fields it already has for the remaining listings instead of being cut off with nothing pushed; the status message reports how many listings were affected.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each listing into Notion, Linear or Airtable.

Ready to collect with Idealista Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.