Idealista $1π° Search By URLs and Keywords
Pricing
from $1.00 / 1,000 results
Idealista $1π° Search By URLs and Keywords
From $1/1K. Extract property listings from Idealista Spain, Italy, and Portugal. Get prices, sizes, rooms, coordinates, advertiser details, phone numbers, descriptions, photos, and 35+ fields per listing. Supports buy, rent, and rooms via filters or direct Idealista URLs. Blazing fast, reliable.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Idealista Scraper (Spain, Italy, Portugal)
Extract property listings from idealista across its three markets: idealista.com (Spain), idealista.it (Italy), and idealista.pt (Portugal). The scraper pulls prices, size, rooms, coordinates, advertiser and phone, full descriptions, photo galleries, and 35+ fields per listing. It supports buy, rent, and rooms, with a Search mode that builds URLs for you and a URL mode that scrapes any idealista search link you paste.
Why this scraper
- Three markets in one actor: Spain, Italy, and Portugal, selectable per run.
- 50+ fields per listing, including price per m2, energy rating, GPS coordinates, advertiser name and phone, construction year, the full description, and the complete photo gallery with no repeated images.
- Two modes: search by location, or paste idealista URLs directly (multi-URL supported, with forward pagination).
- Buy, rent, and room listings, plus price and bedroom filters (Search mode) that work the same in every market. In URL mode the pasted URL's own filters apply.
- Fast and cost-efficient: low memory footprint and quick runs keep large pulls cheap.
- Optional detail enrichment: turn it off for a faster, lean run, or on for the full record.
Data you get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
| id | "00000001" |
| url | "https://www.idealista.com/inmueble/00000001/" |
| market | "ES" |
| operation | "sale" |
| title | "Sample Flat in Example Street" |
| propertyType | "flat" |
| price | 450000 |
| priceText | "450.000 EUR" |
| pricePerM2 | 4736 |
| previousPrice | 480000 |
| priceDropped | true |
| currency | "EUR" |
| size | 95.0 |
| rooms | 3 |
| bathrooms | 2 |
| floor | "3rd floor with lift" |
| hasLift | true |
| hasTerrace | true |
| hasGarage | 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" |
| neighborhood | "Example District" |
| city | "Example City" |
| photoCount | 24 |
| isBranded | true |
| hasVideo | true |
| has3DTour | false |
| hasFloorPlan | true |
| description | "Full advertiser description text appears here when fetchDetails is on." |
| latitude | 40.0000 |
| longitude | -3.0000 |
| address | "Example District, Example City" |
| advertiserName | "Sample Agency" |
| advertiserType | "professional" |
| phone | "+34 000 000 000" |
| features | ["95 m2", "3 rooms", "2 bathrooms", "terrace"] |
| images | ["https://img4.idealista.com/blur/WEB_DETAIL/0/id.pro.es.image.master/00/00/00/000000000.jpg"] |
| imageCount | 24 |
| thumbnail | "https://img4.idealista.com/blur/591_420_mq/0/id.pro.es.image.master/00/00/00/000000000.jpg" |
| tags | ["price drop"] |
| source | "www.idealista.com" |
| scrapedAt | "2026-01-01T00:00:00.000000+00:00" |
| changeType (incremental mode only) | "UPDATED" |
| changedFields (incremental mode only) | ["price"] |
| firstSeenAt (incremental mode only) | "2026-01-01T00:00:00Z" |
| lastSeenAt (incremental mode only) | "2026-01-02T00:00:00Z" |
How to use
Search Spain (Madrid), buy, lean run:
{"mode": "search","market": "es","operation": "sale","locations": ["madrid-madrid"],"maxPages": 3,"maxListings": 90,"fetchDetails": false,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "ES" }}
Search with price and bedroom filters, full detail:
{"mode": "search","market": "es","operation": "sale","locations": ["barcelona-barcelona"],"minPrice": 200000,"maxPrice": 500000,"minBedrooms": 3,"fetchDetails": true,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "ES" }}
Search Italy (rent in Rome):
{"mode": "search","market": "it","operation": "rent","locations": ["roma-roma"],"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "IT" }}
URL mode (paste idealista search links, multiple supported):
{"mode": "url","urls": ["https://www.idealista.com/venta-viviendas/madrid-madrid/","https://www.idealista.pt/comprar-casas/lisboa/"],"maxPages": 2,"fetchDetails": true}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | "search" | "search" or "url". |
| market | string | "es" | Market for Search mode: es, it, or pt. URL mode infers it per URL. |
| operation | string | "sale" | sale, rent, or room (Search mode). |
| locations | array | ["madrid-madrid"] | idealista location slugs (Search mode). |
| urls | array | (example) | idealista search URLs (URL mode). |
| minPrice | integer | (none) | Minimum price. Search mode only. |
| maxPrice | integer | (none) | Maximum price. Search mode only. |
| minBedrooms | integer | (none) | Minimum rooms. Search mode only. |
| maxBedrooms | integer | (none) | Maximum rooms. Search mode only. |
| maxPages | integer | 60 | Pages per search (30 per page). 60 is idealista's per-search ceiling (~1,800 listings); runs are also bounded by maxListings. |
| maxListings | integer | 100 | Total listings cap across all searches. 0 means unlimited. |
| maxConcurrency | integer | 6 | Parallel detail fetches (1 to 12) when detail pages are on. |
| fetchDetails | boolean | true | Open detail pages for coordinates, advertiser, phone, full description, and photos. |
| proxy | object | Residential | Proxy configuration. Residential in the listing's country is recommended. |
| resumeFromRunId | string | (none) | Continue ONE specific interrupted run β paste a previous run/dataset ID. See Resume & recurring updates. |
| incrementalMode | boolean | false | Recurring/scheduled monitoring of the SAME search β only NEW/UPDATED/REAPPEARED listings are returned on later runs. |
| stateKey | string | (auto) | Name an incremental-mode monitoring campaign, or share state across differently-configured runs. |
| emitUnchanged | boolean | false | Incremental mode: also return UNCHANGED listings (extra rows, extra billing). |
| emitExpired | boolean | false | Incremental mode: also return EXPIRED listings once a run fully scans the tracked search (extra rows, extra billing). |
Resume & recurring updates
Two different features, both off by default:
resumeFromRunIdcontinues ONE specific interrupted or massive crawl. Paste a previous run ID or dataset ID and this run skips every listing already collected there β no duplicate rows, no duplicate detail-page charges. (This is separate from the actor's own automatic mid-run checkpoint, which already lets one very long crawl survive an Apify platform migration without any input.)incrementalModeis for scheduling this actor daily/weekly against the SAME search. The actor remembers the previous run's listings itself (state is kept in a dedicated key-value store, scoped to the search/URL and filter settings, or to a manualstateKey). Every listing in the output gets achangeType:NEW,UPDATED,REAPPEARED, or (withemitExpiredon)EXPIRED. By default only NEW/UPDATED/REAPPEARED listings are returned β turn onemitUnchanged/emitExpiredto also get (and pay for) the rest.
changeType, changedFields, firstSeenAt, and lastSeenAt are only present on the output row when incrementalMode is on; a normal run's records are unchanged.
resumeFromRunId and incrementalMode can be combined to bootstrap a new monitoring campaign from a previous large pull β but only on the FIRST incremental run for a given state key. If that state key already has tracked listings, the run fails fast rather than silently mixing baselines; use a different stateKey to start a fresh campaign.
A note on what counts as "changed": a field that goes missing on one run (for example this run's detail-page fetch for a specific listing failed) is never treated as a real change on its own β the actor carries the last known value forward internally so a transient fetch hiccup never gets billed as an UPDATE, and does not erode over repeated failures. A genuine value change (e.g. a real price drop) is always detected and reported, even during a run where that listing's detail fetch failed.
Fields excluded from change detection: scrapedAt (the timestamp this actor stamps on every record β it necessarily differs on every fetch and is not a site-side change). No other field is excluded: a same-search, two-pass live measurement (idealista.com, 3 pinned listings, ~80s apart, full detail fetch) found every other field β including price, the full description, the photo gallery, and lastUpdatedText β byte-identical across both passes with zero fetch errors, so nothing else is masked from change detection. In particular idealista shows no relative-age ("posted 2h ago") text and no distance-from-search-point field, so there was nothing else to watch for.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape β the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record β not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify β Settings β Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Output example
Sample shape: values are illustrative placeholders, not from a live listing.
{"id": "00000001","url": "https://www.idealista.com/inmueble/00000001/","market": "ES","operation": "sale","title": "Sample Flat in Example Street","propertyType": "flat","price": 450000,"priceText": "450.000 EUR","pricePerM2": 4736,"previousPrice": 480000,"priceDropped": true,"currency": "EUR","size": 95.0,"rooms": 3,"bathrooms": 2,"floor": "3rd floor with lift","hasLift": true,"hasTerrace": true,"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.0000,"longitude": -3.0000,"address": "Example District, Example City","neighborhood": "Example District","city": "Example City","photoCount": 24,"isBranded": true,"hasVideo": true,"has3DTour": false,"hasFloorPlan": true,"advertiserName": "Sample Agency","advertiserType": "professional","phone": "+34 000 000 000","features": ["95 m2", "3 rooms", "2 bathrooms", "terrace"],"images": ["https://img4.idealista.com/blur/WEB_DETAIL/0/id.pro.es.image.master/00/00/00/000000000.jpg"],"imageCount": 24,"source": "www.idealista.com","scrapedAt": "2026-01-01T00:00:00.000000+00:00"}
Plan requirements
idealista serves listings only to residential connections in the listing's country, so a residential proxy is required for reliable results. On Apify, residential proxy access is included from the Starter plan upward. The actor defaults the proxy country to your chosen market. Free-tier accounts without residential access will likely receive zero results; add residential proxy credit and re-run.