Fotocasa.es $1๐ฐ Buy, Rent & Property Details
Pricing
from $1.00 / 1,000 listing scrapeds
Fotocasa.es $1๐ฐ Buy, Rent & Property Details
From $1/1K. Scrape Spain property listings from fotocasa.es. Get price, surface, rooms, baths, address, GPS, agency, phone, energy rating, photos and 140+ fields. Buy and rent, all regions, all property types.
Pricing
from $1.00 / 1,000 listing scrapeds
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
9 days ago
Last modified
Categories
Share
Fotocasa.es Scraper
Extract property listings from fotocasa.es, Spain's leading property portal, at scale. Search by location and filters or paste direct search URLs, and get clean, structured records with price, surface, rooms, bathrooms, full address, GPS coordinates, agency and contact details, energy rating, photos and 140+ fields per listing. Forward-walking pagination, optional per-listing detail enrichment, and ready-to-use exports to your apps.
Why This Scraper?
- 140+ fields per listing - far more than typical alternatives, including both camelCase and snake_case field names so the output drops into any existing pipeline.
- Buy and rent, every region, every property type - flats, houses, duplexes, penthouses, studios, lofts, new construction, garages, offices, land and more.
- Rich location data - city, neighborhood, full address and precise latitude/longitude for every listing.
- Agency and contact details - agency name, alias, type, phone, and (with detail enrichment) agent name, email and listing reference.
- Two input modes - search by location with filters, or feed direct fotocasa.es search URLs.
- Powerful filters - price, rooms, bathrooms and surface ranges, plus operation, property type and sort order.
- Export anywhere - pipe results into Notion, Airtable, Linear or other apps via MCP connectors, with the full record always kept in the dataset.
Data You Get
Sample shape - values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
| id | 1_000000000 |
| propertyId | 000000000 |
| title | C/ de Ejemplo, Centro |
| rawPrice | 295000 |
| currency | EUR |
| pricePerSqm | 4538.46 |
| surface | 65 |
| rooms | 3 |
| baths | 2 |
| floor | 4 |
| propertyType | 2 |
| propertySubtype | 1 |
| operation | sale |
| city | Madrid |
| neighborhood | Centro |
| latitude | 40.4168 |
| longitude | -3.7038 |
| agencyName | Example Agency SL |
| phone | +34000000000 |
| reference | REF-00000 |
| energyCertificate | {"energyEfficiencyRatingType": "C"} |
| images | ["https://static.fotocasa.es/images/ads/0000?rule=original"] |
| url | https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/centro/000000000/d |
How to Use
Search a city for homes to buy:
{"mode": "search","locations": ["madrid-capital"],"operation": "comprar","propertyType": "viviendas","maxListings": 50}
Search with filters and sorting:
{"mode": "search","locations": ["barcelona-capital"],"operation": "alquiler","minPrice": 800,"maxPrice": 1500,"minRooms": 2,"sortBy": "price_asc","maxListings": 100}
Scrape direct URLs with full detail enrichment:
{"mode": "url","urls": ["https://www.fotocasa.es/es/comprar/viviendas/valencia-capital/todas-las-zonas/l"],"fetchDetails": true,"maxListings": 200}
Input Parameters
| Parameter | Type | Description |
|---|---|---|
| mode | string | search (location + filters) or url (direct URLs). |
| locations | array | Location slugs, e.g. madrid-capital, barcelona-capital/centro. Search mode only. |
| operation | string | comprar (buy) or alquiler (rent). Search mode only. |
| propertyType | string | Property category, e.g. viviendas, pisos, casas. Search mode only. |
| sortBy | string | relevance, newest, price_asc, price_desc, surface_asc, surface_desc. |
| minPrice / maxPrice | integer | Price range filter (EUR). |
| minRooms / maxRooms | integer | Rooms range filter. |
| minBaths / maxBaths | integer | Bathrooms range filter. |
| minSurface / maxSurface | integer | Surface range filter (mยฒ). |
| urls | array | Direct search URLs. URL mode only; filter fields are ignored. |
| fetchDetails | boolean | Adds energy rating, full features, reference and contact from the listing detail page. Slower and increases cost per listing. |
| maxPages | integer | Optional safety limit on result pages walked per search. Leave empty (or 0) for unlimited โ the walk continues until the site's natural end of results (an empty page) or maxListings is hit; only set a value to hard-stop pagination earlier. |
| maxListings | integer | The run's sole cap on total listings scraped. Default 20. 0 = unlimited (walk the whole catalogue, bounded only by maxPages if set). |
| proxy | object | Proxy configuration. Residential proxy with a Spanish (ES) exit is enabled by default, which fotocasa.es requires for reliable access. |
| residentialCountries | array | Country codes used for the residential proxy. fotocasa.es requires a Spanish (ES) exit. |
| maxResidentialRequests | integer | Per-run residential request budget (default 10000). Set lower to cap cost, or 0 to disable. |
| backupProxyUrl | string | Optional last-resort failover proxy URL used when the Apify proxy is unavailable. |
| mcpConnectors | array | MCP connectors to forward a per-listing summary to: notion, linear, airtable, apify. The full record always stays in the dataset. |
| notionParentPageUrl | string | Notion page under which the new database is created (Notion connector only). |
| maxNotifyListings | integer | Max listings forwarded to MCP connectors per run (default 50). |
| resumeFromRunId | string | Optional. Paste a previous run ID (or its dataset ID) to continue that run as a delta: listings already saved there are skipped, so this run only adds new ones. Fails fast, before any scraping, if the ID doesn't resolve to a readable run or dataset. For recurring monitoring of the same search, use incrementalMode below instead. |
| incrementalMode | boolean | Off by default. Turn on for daily/recurring monitoring of the same search: the actor remembers the previous run's listings itself and classifies every listing NEW / UPDATED / UNCHANGED / REAPPEARED (and EXPIRED, opt-in). UNCHANGED listings are suppressed (not returned, not billed) unless emitUnchanged is on. |
| stateKey | string | Optional, incremental mode only. Names a monitoring campaign so its state stays stable, or so two differently-configured runs can deliberately share one baseline. Leave empty to derive a key automatically from the search/URL and filter/detail settings. |
| emitUnchanged | boolean | Off by default, incremental mode only. Also return (and bill) listings unchanged since the last run, marked UNCHANGED. |
| emitExpired | boolean | Off by default, incremental mode only. Also return (and bill) synthetic EXPIRED rows for listings that were tracked but no longer appear โ only produced once a run has fully scanned the tracked search (not when maxListings capped it, or resumeFromRunId was used that run). |
Full-catalogue runs and resuming
To walk an entire search (not just a page or two), set maxListings: 0 and leave maxPages empty (or 0) โ the actor then paginates until the site itself runs out of results. If a full-catalogue run is interrupted (platform migration, manual abort, or a fresh run days later to pick up new listings), pass the previous run's ID as resumeFromRunId: the actor pages through that run's dataset, seeds its dedup set with the listing IDs already collected, and then scrapes only new listings. Separately, an interrupted run also survives a platform migration/resurrect on its own โ the actor checkpoints its seen-listing state during the run and resumes from it automatically; that checkpoint is cleared once a run finishes cleanly.
Incremental / recurring updates
resumeFromRunId continues one specific interrupted run. incrementalMode is the opposite use case: you schedule this actor to run the same search again and again (daily, weekly) and want only what changed, without pasting any id. Turn incrementalMode on and the actor keeps a baseline in its own key-value store, keyed on a hash of: mode, locations, operation, propertyType, sortBy, urls, every price/rooms/baths/surface filter, and fetchDetails. Two searches with different filters never share a baseline; raising or lowering maxListings/maxPages between runs does not fork a new one (caps are excluded from the key on purpose โ only what's tracked matters).
Each listing is classified against the baseline:
- NEW โ not seen before.
- UPDATED โ a tracked field changed;
changedFieldslists which ones. - UNCHANGED โ nothing changed. Suppressed by default (not returned, not billed) โ turn on
emitUnchangedto get the full snapshot every run instead. - REAPPEARED โ previously marked
EXPIRED, now found again. - EXPIRED โ was tracked, no longer found. Only emitted when
emitExpiredis on, and only after a run that fully scanned the tracked search (amaxListings/maxPagescap, orresumeFromRunId, skips expiry detection for that run rather than risk tombstoning a listing that simply wasn't reached yet).
Two exclusions from the change-fingerprint, both deliberate:
- The embedded
agency/publisherobjects are excluded โ they carry that agency's own profile data (name, description, ranking, ...), not the listing's. Including them whole in the change fingerprint would re-flag every listing an agency holds asUPDATEDwhenever that agency edits its own profile, unrelated to any specific listing. The derived listing-level fields (agencyName,phone,clientAlias,clientType,clientUrl) stay in the diff โ a listing switching to a different agency or contact is still reported. - Fields only ever populated by
fetchDetails(energyCertificate,reference,extraFeatures,constructionType,groundSurface,qualityRate,purchaseType,agentName,agentEmail,contactName,creationDate) are excluded from the diff for one classification whenever either side of the comparison โ this run's fetch, or the stored baseline โ lacks a landed detail-page fetch. Otherwise a single transient detail-fetch failure would read as those fields being wiped from the listing, and a listing's first-ever successful detail fetch (after an earlier failure) would read as those fields suddenly appearing as a "change".
Everything else โ including rawPrice/price and any occupancy/status-shaped field โ is real listing data and participates in the diff normally; a genuine price change always reports UPDATED, never silently dropped.
Output Example
Sample shape - values are illustrative placeholders, not from a live listing.
{"id": "1_000000000","propertyId": "000000000","title": "C/ de Ejemplo, Centro","rawPrice": 295000,"currency": "EUR","pricePerSqm": 4538.46,"surface": 65,"rooms": 3,"baths": 2,"floor": "4","propertyType": 2,"propertySubtype": 1,"operation": "sale","transactionTypeId": 1,"city": "Madrid","neighborhood": "Centro","address": { "municipality": "Madrid", "province": "Madrid", "zipCode": "28000" },"latitude": 40.4168,"longitude": -3.7038,"agencyName": "Example Agency SL","clientAlias": "Example Agency","clientType": "professional","phone": "+34000000000","reference": "REF-00000","energyCertificate": { "energyEfficiencyRatingType": "C" },"images": ["https://static.fotocasa.es/images/ads/0000?rule=original"],"photosCount": 12,"description": "Bright reformed home in a well-connected central area.","url": "https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/centro/000000000/d"}
Export to Your Apps (MCP Connectors)
Beyond the dataset, this Actor can send a condensed summary of each listing straight into the tools you already use, via Model Context Protocol (MCP) connectors. The full record is always kept in the dataset; the connector receives a readable summary (title plus key fields) per item.
Supported connectors: Notion, Linear, Airtable, and Apify.
- Authorize the connector once under Apify โ Settings โ Integrations.
- Select one or more in the
mcpConnectorsinput. - (Notion only) Set
notionParentPageUrlto the page the new database should be created under. - Optionally cap how many listings are forwarded with
maxNotifyListings(default 50).
{"mode": "search","locations": ["madrid-capital"],"operation": "comprar","maxListings": 50,"mcpConnectors": ["notion"],"notionParentPageUrl": "https://www.notion.so/your-workspace/Listings-0000"}