idealista Listing Lookup — Spain Real Estate API
Pricing
from $9.75 / 1,000 successful lookups
idealista Listing Lookup — Spain Real Estate API
Look up any idealista.com property listing: price, price per m², size, rooms, floor, sale/rent, property type, and neighbourhood. Uses a real browser session through an unblocking proxy to reliably get past bot protection. Pay only for listings that resolve.
Pricing
from $9.75 / 1,000 successful lookups
Rating
0.0
(0)
Developer
Adrian Voss
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
idealista Listing Lookup — Price, Size & Features API
Paste a list of idealista property listing URLs and get structured data back for each one — price, price per m², size, rooms, floor, neighbourhood, city, property type, sale-or-rent, and the listing's feature tags. idealista is protected by DataDome, so this actor routes each lookup through a real browser session on Apify's UNBLOCKER proxy group to get past the challenge that blocks plain HTTP requests. Covers idealista's Spanish, Portuguese and Italian sites.
Who it's for
The accountable_eel catalogue also covers single-listing lookups on marketplaces that don't publish an open API. Each actor takes a list of listing URLs and returns one flat, stably-named row per input — price, size, condition, location, seller signal — read from the listing page itself rather than from CSS selectors that move with every redesign. Pricing is pay-per-event and per-listing: you pay for a listing that actually resolved, and nothing for a removed listing, a 404, or a page with no property data. No seat licence, no monthly minimum, no credit system to decode. This one covers idealista, the dominant property portal in Spain, Portugal and Italy — where the hard part isn't the parsing, it's getting past DataDome at all.
Why this one
- It actually gets past DataDome. A plain residential proxy with browser-like headers gets a block page. This routes through Apify's UNBLOCKER proxy group, which defeats the challenge.
- You don't pay to find out "gone." A removed listing, an invalid URL or a page without
property data comes back
found: falseand is never billed. - Price per m² comes computed.
pricePerSqmis parsed from the listing rather than left for you to derive frompriceandsizeSqm, which are also both returned. - Three markets, one actor. Spanish, Portuguese and Italian idealista listings all resolve through the same lookup.
- Bare IDs or full URLs. Pass a full listing URL or just the numeric listing id.
What you get
One row per input listing. Every field below is stably named and won't be renamed between runs.
| Field | Type / format | Description |
|---|---|---|
query | text | The listing URL or id exactly as submitted. |
found | boolean | Whether the page returned usable property data. Gates billing — false rows are never charged. |
scrapedAt | date (ISO 8601) | When the listing was read. |
data.title | text | Listing headline as shown on idealista. |
data.listingId | text | idealista's numeric listing id. |
data.propertyType | text | Property type as idealista classifies it — flat, house, and so on. |
data.operation | text | Whether the listing is a sale or a rental. |
data.price | number | Asking price or monthly rent, as a number. |
data.currency | text | Always EUR across all three markets. |
data.pricePerSqm | number | Price per square metre, as published on the listing. |
data.sizeSqm | number | Floor area in square metres. |
data.rooms | number | Room count as idealista reports it. |
data.floorInfo | text | Floor and lift information, as free text. |
data.neighbourhood | text | Neighbourhood or district. |
data.city | text | City the listing sits in. |
data.features | array | Feature tags from the listing — terrace, parking, air conditioning, and similar. |
data.url | link | The resolved listing URL. |
floorInfo and features are free-text as idealista publishes them, and they're published in
the listing's own language — Spanish, Portuguese or Italian depending on the site. Normalize
downstream if you're mixing markets in one table.
Price
$9.75 per 1,000 resolved listings, plus a $0.0507 start fee per run. A removed listing, an invalid URL, or a page without property data is never charged.
This is materially more expensive per row than the bulk idealista scrapers on the Store, and the reason is architectural: every lookup here is a full headless browser session through UNBLOCKER, billed by compute time, because that's what clears DataDome on a single listing page. If you need thousands of listings from search results, a crawler that amortizes one session across many listings will be cheaper. If you have specific listing URLs and need them resolved reliably, this is built for that. The start fee is per run, not per listing, so batch your lookups rather than running them one at a time.
How to use
- In the Apify Console. Open the actor page and click Start — the
listingUrlsfield is pre-filled with a working example. - Via the API. Call it with a POST request once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~idealista-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"listingUrls":["https://www.idealista.com/inmueble/12345678/"]}'
- On a schedule. Save the actor as an Apify Task, then add a Schedule so it runs on its own.
Common ways teams use this:
- Track asking prices across a watchlist of listings by re-running on a schedule and
diffing
price. - Benchmark price per m² across neighbourhoods using
pricePerSqm,cityandneighbourhoodtogether. - Verify a listing is still live before sending it to a client or publishing it.
- Enrich a property shortlist with size, rooms and feature tags from a list of URLs you already have.
- Compare sale versus rental yields in an area by running both and grouping on
operation.
Input
{"listingUrls": ["https://www.idealista.com/inmueble/110910838/","https://www.idealista.com/inmueble/106303416/","https://www.idealista.com/inmueble/111323975/","https://www.idealista.com/inmueble/108919870/","https://www.idealista.com/inmueble/109266379/","https://www.idealista.com/inmueble/110784153/","https://www.idealista.com/inmueble/110697237/","https://www.idealista.com/inmueble/111298148/"]}
One idealista.com property listing URL or bare numeric listing ID per line. Accepted formats: https://www.idealista.com/inmueble/112153132/, 112153132.
{"listingUrls": ["https://www.idealista.com/inmueble/12345678/","https://www.idealista.pt/imovel/23456789/"],"maxConcurrency": 2}
listingUrls is your list of idealista property listing URLs, or bare numeric listing ids.
Spanish (idealista.com), Portuguese (idealista.pt) and Italian (idealista.it) listings all
work and can be mixed in one run. maxConcurrency controls parallel browser sessions and
defaults to 2 — keep it low, since each session is a full headless browser through UNBLOCKER
and higher concurrency multiplies compute cost quickly rather than saving money.
Sample output
| query | found | status | scrapedAt |
|---|---|---|---|
| https://www.idealista.com/inmueble/106303416/ | false | OK | 2026-08-20T13:24:17.235Z |
A single row reads like this:
{"query": "https://www.idealista.com/inmueble/12345678/","found": true,"data": {"title": "Piso en venta en Malasaña","listingId": "12345678","propertyType": "Piso","operation": "venta","price": 485000,"currency": "EUR","pricePerSqm": 6928,"sizeSqm": 70,"rooms": 2,"floorInfo": "Planta 3ª exterior con ascensor","neighbourhood": "Universidad","city": "Madrid","features": ["Terraza", "Aire acondicionado"],"url": "https://www.idealista.com/inmueble/12345678/"},"scrapedAt": "2026-08-20T12:00:00.000Z"}
A listing that no longer resolves comes back with no data, and is never charged:
{"query": "https://www.idealista.com/inmueble/00000000/","found": false,"scrapedAt": "2026-08-20T12:00:04.000Z"}
Miss rows are written so you can see exactly which URLs failed rather than diffing your input list against the output.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it from a script, a workflow tool, or an AI agent, with no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~idealista-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"listingUrls":["https://www.idealista.com/inmueble/12345678/"]}'
n8n. Add an HTTP Request node: Method POST, URL
https://api.apify.com/v2/acts/accountable_eel~idealista-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>,
Body Content Type JSON, JSON Body {"listingUrls":["<listing URL>"]}.
Clay. Add an "HTTP API" column: Method POST, same URL, Body
{"listingUrls":["{{value}}"]}, mapping the row's listing URL into the array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "idealista Listing Lookup | Apify" — the agent will find and run this actor.
Tips
- Batch your listings into one run. The start fee is charged per run, not per listing, so one run of 200 listings costs one start fee and 200 runs of one listing cost 200.
- Keep
maxConcurrencyat 2–3. Each session is a full browser through UNBLOCKER, billed by compute time. Raising it makes a batch finish sooner, not cost less. - Normalize
featuresbefore comparing across markets. The tags come back in the listing's own language, so a Spanish "Terraza" and an Italian "Terrazzo" won't group on their own. - Use
pricePerSqmrather than deriving it. It's taken from the listing, so it matches what a buyer sees even where rounding differs fromprice ÷ sizeSqm. - Re-run on a schedule and diff
priceto catch reductions across a watchlist.
vs. alternatives
| What it costs | What you get | Trade-off | |
|---|---|---|---|
This actor (idealista-listing-lookup) | $9.75 per 1,000 resolved listings, $0.0507 actor start, nothing for a removed or invalid listing | Structured price, price per m², size, rooms, location and feature tags for listing URLs you already have, across ES/PT/IT | The most expensive per row of the four, because every lookup is a real browser session through UNBLOCKER. It also won't search or crawl — you supply the URLs. |
| igolaizola/idealista-scraper (2,041 users) | $0.0009 per result, $0.0009 per detail fetch, $0.005 start | The category leader: searches by location, filters, and crawls listings in bulk across Spain, Italy and Portugal | Roughly a tenth of the price per row and it discovers listings rather than requiring URLs. If you want volume from search results, use this. |
| dz_omar/idealista-scraper-api (1,221 users) | $0.003 per property, $0.0045 per detailed property, $0.01 start | Bulk property extraction with a detailed tier | Around a third of the price per row, also crawler-shaped rather than lookup-shaped. |
| Doing it yourself | Your time + a headless browser fleet, plus solving DataDome, its retries and its transient failures | The same data | This actor absorbs the UNBLOCKER routing, the retry logic and the parsing. DataDome is the whole difficulty; everything after it is straightforward. |
Competitor prices are their published FREE-tier list prices as of August 2026 and are not tracked here — check the actor's own page before relying on the comparison.
FAQ
What counts as "found"?
The listing page must load past DataDome and contain usable property data. Removed listings,
404s and pages without that data return found: false and are never charged.
Why does this need a real browser instead of a plain HTTP request? idealista is protected by DataDome. A plain residential proxy with browser-like headers gets the same block page as a bare request — this routes through Apify's UNBLOCKER proxy group specifically because it clears that challenge.
Why is it more expensive than the other idealista actors? Because it's a different shape. Bulk crawlers amortize one browser session across many listings found in search results. This resolves specific listing URLs one at a time, and each needs its own UNBLOCKER session. For volume from search, a crawler is cheaper; for reliable resolution of URLs you already hold, this is what it costs.
Can I use search-result or map pages instead of listing URLs? No. This actor takes individual property listing pages. If you need to discover listings from a search, a crawler-shaped actor is the right tool.
Does it work on idealista.pt and idealista.it?
Yes. All three sites resolve through the same lookup, and you can mix them in one run.
currency is EUR throughout.
Why are features and floorInfo not in English?
They're free text exactly as idealista publishes them, in the listing's own language.
Translating them would mean guessing, so they're passed through unchanged.
Is the price live or cached? Live. Every row is a fresh page load at run time — nothing is stored between runs.
Related actors
- Allegro Listing Lookup — the same listing-lookup shape for Allegro.pl marketplace listings.
- Shopify Store Lookup — live product catalogues for merchants running their own storefront.
- Open Food Facts Product Lookup — product data by barcode.
En español · Em português · In italiano
ES — Extrae datos estructurados de cualquier anuncio de idealista a partir de su URL: precio, precio por m², superficie, habitaciones, planta, barrio, ciudad y características. Solo pagas por los anuncios que se resuelven; los anuncios retirados son gratuitos. Palabras clave: API idealista, scraper idealista, precio por metro cuadrado, datos inmobiliarios, seguimiento de precios de vivienda.
PT — Extrai dados estruturados de qualquer anúncio do idealista a partir do URL: preço, preço por m², área, quartos, andar, bairro, cidade e características. Paga apenas pelos anúncios encontrados. Palavras-chave: API idealista, scraper idealista, preço por metro quadrado, dados imobiliários.
IT — Estrae dati strutturati da qualsiasi annuncio idealista partendo dall'URL: prezzo, prezzo al m², superficie, locali, piano, quartiere, città e caratteristiche. Paghi solo per gli annunci effettivamente trovati. Parole chiave: API idealista, scraper idealista, prezzo al metro quadro, dati immobiliari.