Fotocasa Scraper: Spain Real Estate Listings & Property Data
Pricing
from $0.50 / 1,000 listings
Fotocasa Scraper: Spain Real Estate Listings & Property Data
Scrape Fotocasa.es real estate listings in Spain: homes for sale and for rent by city or district name, search URL with every filter, or listing URL. Property data: id, price, surface, rooms, bathrooms, floor, address, coordinates, agency, features, description, photos. No login.
Pricing
from $0.50 / 1,000 listings
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 hours ago
Last modified
Categories
Features
Share
Fotocasa listings in Spain, logged out: places by name (a city, a district or a neighbourhood) for sale or for rent, Fotocasa search URLs with every filter you set on the site, or listing URLs in, one row per listing out — the listing id and URL, the transaction, the property type, the price in euros, the surface, rooms, bathrooms and floor, the address, district, city and coordinates, the agency's name and phone, the features, the description and every photo URL — several searches in one run, a max per search. One free search row per input carries a completeness verdict: COMPLETE (the search's end), CAPPED (your limit), TRUNCATED (the site's own limit of about 9,900 listings a search, with its count) or PARTIAL. No login, no API key, no browser, proxies handled for you.
$1.00 per 1,000 listing rows on the Free plan, $0.85 on Starter. A run start is $0.0035. The default input returns about 50 rows for about $0.0535. A value that names nothing is a free row that says why.

Why this Fotocasa scraper
- The leader's default job, and your own searches. Give places by name (
Madrid,Chamberí, Madrid) withoperationbuy or rent and a property type, or paste the URL of a search from your browser: a city, a district or a neighbourhood, with every filter you set there (price band, surface, rooms, bathrooms, flats or houses, the sort). The actor reads the site's own search context from that page, so the rows are the ones the site lists for it. - Whole records from the search itself. Fotocasa's own search gives 100 listings a call with the price, the surface, rooms, bathrooms, floor and condition, the address, district, city, postal code and coordinates, the agency's name and phone, the features, the whole description and every photo. No extra call per listing, so a search of 1,000 listings is read in about 10 calls.
- Listing URLs for one listing. A listing URL reads the listing's own page: the same fields and the energy and emissions ratings.
- Every listing of a search, checked. Newest first (or the sort of your URL), page after page, until the search's end: the free
searchrow says COMPLETE with the site's count. The site serves about 9,900 listings of one search, whatever its count (measured 2026-11-01); a run that reaches that end says TRUNCATED with the count. A listing met twice (on another page, in another search of the run) is delivered and charged once. - Private advertisers stay private. An agency's public name and phone are delivered; a private advertiser is named by type only. Every input gets a row.
Who it's for
- Real estate investors and analysts — the flats and houses of a city or a district for sale or for rent, with the price, the surface and the coordinates, to compare prices per m² by neighbourhood.
- Agencies and property managers — the competition of a zone: which agencies list what, at what price, with how many photos, and what is new this week.
- Relocation and rental services — the rentals of a city with your filters (rooms, price band, surface), read again every day to see what is new.
Quick start
The newest 50 homes for sale in a city
{"locations": ["Madrid"],"operation": "buy","propertyType": "homes","maxItemsPerSearch": 50}
Rentals of two districts by name
{"locations": ["Chamberí, Madrid","Gràcia, Barcelona"],"operation": "rent","maxItemsPerSearch": 100}
A search URL with its filters, and one listing
{"searchUrls": ["https://www.fotocasa.es/es/alquiler/viviendas/barcelona-capital/todas-las-zonas/l?maxPrice=2000&minRooms=2","https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/aire-acondicionado-calefaccion-terraza-trastero-ascensor-amueblado/190909371/d"],"maxItemsPerSearch": 100}
Output
One row per listing (and one free search row per input):
| field | meaning |
|---|---|
row_type | listing (one listing, charged) or search (the input's row with the walk's verdict; free). |
input_index | The 1-based position of the input this row answers: locations first, then searchUrls. |
input_value | The input as you gave it (the place name or the URL). |
input_kind | Which input it came from: place (locations) or url (searchUrls). |
search_url | The Fotocasa URL this row comes from (your search URL without its page number, or the listing's page for a listing URL); null for a place by name. |
status | A search row: ok, no_results, not_found, invalid, duplicate, failed or not_read (see the FAQ). A listing row: ok. |
status_detail | Why a search row has its status, in a sentence (null when ok). |
scraped_at | When the row was read (UTC, ISO 8601). |
position | A listing row: its place among this input's delivered listings, in the search's order. |
page | A listing row: the search page it was on (100 listings a page; null for a listing URL). |
listing_id | The site's listing id (the number before /d in the listing's URL). Deduplicate across runs and join to your own data on this. |
url | The listing's page on fotocasa.es. |
transaction | buy, rent, share, transfer or rent_to_own, as the site gives it. |
property_type | The site's property type: homes, garages, land, premises, offices, storage_rooms, buildings or new_homes. |
property_subtype | The site's subtype where it names one: flat, apartment, house, semi_detached_house, penthouse, duplex, loft, studio, ground_floor, rural_property, a land kind. |
price | The price in euros (a rent: a month); null when the advertiser hides it. |
currency | EUR when a price is given. |
price_period | month for a rent; null for a sale. |
price_drop | The price drop the site shows on the listing, in euros (null when there is none). |
price_per_m2 | The price divided by the surface, in euros per m² (null without both). |
surface_m2 | The surface in m², as the advertiser gives it. |
rooms | Rooms (bedrooms), as the site gives them. |
bathrooms | Bathrooms. |
floor | The floor in words: ground floor, mezzanine, 1st floor … 15th floor or higher, penthouse (null where the site gives none or a code not read). |
floor_code | The site's own floor code (3 ground floor, 4 mezzanine, 6 the 1st floor … 32 penthouse). |
condition | The condition the advertiser gives: new, almost_new, very_good, good, refurbished, for_renovation. |
features | The features the site lists, as keys: elevator, terrace, balcony, air_conditioner, heater, swimming_pool, garden, parking … (a listing URL's row adds the page's other extras, such as trastero, armarios). |
address | The address text the advertiser shows (a street with its number, or the zone). |
neighborhood | The neighbourhood (barrio). |
district | The district. |
city | The city or municipality (Madrid Capital, Barcelona Capital). |
province | The province. |
region | The autonomous community. |
zipcode | The postal code. |
latitude | Latitude of the point the listing shows (exact or approximate, as the advertiser chose). |
longitude | Longitude of the same point. |
location_ids | The site's nine location ids of the listing (country, community, province, area, comarca, municipality, level 6, district, neighbourhood), comma-separated. |
advertiser_type | professional (an agency or a developer) or private (a private person: never named). |
agency_name | A professional advertiser's public name (null for a private advertiser). |
agency_id | The site's id of the professional advertiser. |
agency_url | The agency's page on fotocasa.es. |
agency_phone | The phone number a professional advertiser publishes on the listing (often the site's tracked number). |
agency_logo | The agency's logo image. |
published_at | When the listing was published or last renewed on the site (UTC). |
is_new | Whether the site marks the listing as new. |
is_top | Whether the listing is in the site's paid top tier (null on a listing URL's row). |
is_new_construction | Whether the listing is a new-build home or part of a development. |
has_virtual_tour | Whether the listing has a virtual tour. |
description | The advertiser's description, whole, as the site gives it. |
photo_urls | The photos, original size, in the site's order (plans and videos left out). |
photos_count | How many photo URLs the row carries. |
energy_rating | A listing URL's row: the energy certificate's rating (A–G) when the certificate is valid; null on search rows. |
emissions_rating | A listing URL's row: the emissions rating (A–G) when the certificate is valid; null on search rows. |
record_source | Which answer gave the row: search (the site's search) or listing_page (a listing URL's page). |
place | A search row: the place the site resolved (Madrid, Madrid, Chamberí, Madrid). |
listings_count | A search row: the site's own count of listings for the search. |
listings_delivered | A search row: the listing rows this input delivered. |
pages_read | A search row: the search pages read. |
repeats_skipped | A search row: listings met again (on a later page, or delivered by another input of the run), skipped and not charged. |
verdict | A search row: COMPLETE (the search's end), CAPPED (your limit), TRUNCATED (the site's limit of about 9,900 listings a search, or an end under its count) or PARTIAL (stopped by a refusal or the time limit). |
verdict_detail | A search row: the verdict's reason in a sentence (the site's count, the end met, the cap). |
Example record:
{"row_type": "listing","input_index": 1,"input_value": "Madrid","input_kind": "place","search_url": null,"status": "ok","status_detail": null,"scraped_at": "2026-11-01T03:43:02Z","position": 7,"page": 1,"listing_id": "191267453","url": "https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/numancia/191267453/d","transaction": "buy","property_type": "homes","property_subtype": "flat","price": 210000,"currency": "EUR","price_period": null,"price_drop": null,"price_per_m2": 3750.0,"surface_m2": 56,"rooms": 2,"bathrooms": 1,"floor": "2nd floor","floor_code": 7,"condition": "good","features": null,"address": "Calle Alfonso XIII, Puente de Vallecas","neighborhood": "Numancia","district": "Puente de Vallecas","city": "Madrid Capital","province": "Madrid","region": "Madrid","zipcode": "28038","latitude": 40.40126,"longitude": -3.6628568,"location_ids": "724,14,28,173,0,28079,0,677,82","advertiser_type": "professional","agency_name": "N.C. GESTION INMOBILIARIA","agency_id": "9202776871777","agency_url": "https://www.fotocasa.es/inmobiliarias/nc-gestion-inmobiliaria-9202776871777","agency_phone": "+34900000000","agency_logo": "https://static.fotocasa.es/images/client/7714f89e-0040-470b-9fba-d5acf0c70836/20260605124730?rule=original","published_at": "2026-10-31T21:55:15Z","is_new": true,"is_top": false,"is_new_construction": false,"has_virtual_tour": false,"description": "Inmueble en periodo de transparencia hasta el día 04/11/2026P. iso en Madrid. Con una superficie de 56 m², se compone de salón-comedor, cocina amueblada, 2 dormitorios y 1 baño. Es …(truncated for display)","photo_urls": ["https://static.fotocasa.es/images/ads/c35f7e63-511e-460b-99f2-3540e0bd841f?rule=original","https://static.fotocasa.es/images/ads/4e2d522f-b778-4a88-baba-6160e6984bf8?rule=original","https://static.fotocasa.es/images/ads/3b45a3d8-2969-49d6-b421-3a295a9ca69a?rule=original","https://static.fotocasa.es/images/ads/d419342b-4b4e-4986-9ae4-861e6a46c61a?rule=original"],"photos_count": 11,"energy_rating": null,"emissions_rating": null,"record_source": "search","place": null,"listings_count": null,"listings_delivered": null,"pages_read": null,"repeats_skipped": null,"verdict": null,"verdict_detail": null}
Pricing
Pay for the listings a run delivers, plus one run start; no platform usage is billed to you. The listing price falls with your Apify plan.
| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
Listing (listing) | per 1,000 | $1.00 | $0.85 | $0.70 | $0.50 |
Run start (start) | per run | $0.0035 | $0.0035 | $0.0035 | $0.0035 |
A listing is $1.00 per 1,000 on the Free plan ($0.001 a listing), with the address, the coordinates, the agency, the features, the description and every photo included. Each run that delivers a charged listing also pays the run start, $0.0035 once; a run that delivers no charged listing pays nothing at all. So one search of 100 listings costs about $0.10 on the Free plan, and several searches in one run share one start. The free search row of every input, a value that is not a Fotocasa search or listing URL (invalid), a place or a listing the site does not have (not_found), a search with no match (no_results), a repeated input (duplicate), an input left at the cap or the time limit (not_read) and a refusal the run could not pass (failed) are never charged. A listing is charged once a run, also when several searches list it. A run that stops early (a timeout, an abort) is charged for the listings it delivered. maxItems counts the charged rows; before the first request the log names the price of each row at your plan and the most the run can cost. Enterprise plans have their own rates: the Actor's Pricing tab shows the price for your plan.
Usage patterns
- Places, searches and listings —
locationstakes places by name, one a line (Madrid,Chamberí, Madrid,Gràcia, Barcelona), searched foroperation(buy or rent) andpropertyType(homes, garages, land, premises, offices, storage rooms, buildings); the free search row names the place the site took.searchUrlstakes search URLs as your browser shows them (https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l,/es/alquiler/pisos/barcelona-capital/gracia/l; every filter in them is kept: price, surface, rooms, bathrooms, the subtypes, the sort) and listing URLs (…/<id>/d). Fotocasa only. - What a row is —
row_type=listing: one listing, in the search's order (position, and the searchpageit was on).row_type=search: the free row of one input value —place(the place the site resolved),listings_count(the site's own count),listings_delivered,pages_read,repeats_skipped, theverdictwith itsverdict_detail, and thestatuswith its reason. - How far a search goes —
maxItemsPerSearch(default 100; the form suggests 50; 0 = every listing the site serves) stops each search after that many new listings. The site serves about 9,900 listings of one search, whatever its count; a run that reaches that end says TRUNCATED with the count, and a district, a price band or a property type in the URL reads more of it.maxItemscaps the charged rows of the whole run. A run started over the API takes the defaults, not the form's suggestion: setmaxItemsPerSearchthere too. A place's search is newest first; a search URL keeps its own sort when it sets one.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
locations | array | Places to search, one a line: a city (Madrid), a district (Chamberí, Madrid) or a neighbourhood (Gràcia, Barcelona). Each is resolved by Fotocasa's own place search (its first place) and searched for the operation and the property type below. A place Fotocasa does not know gives a free row with no listing. | |
operation | buy / rent | "buy" | What the places above search: properties for sale or for rent. A Fotocasa URL keeps its own (comprar, alquiler, compartir, traspaso in the URL). |
propertyType | homes / garages / land / premises / offices / storage_rooms / buildings | "homes" | The property type the places above search. A Fotocasa URL keeps its own (viviendas, pisos, casas, garajes … in the URL). |
searchUrls | array | Fotocasa search URLs as your browser shows them, one a line (https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l), with every filter you set on the site kept (?maxPrice=500000&minRooms=3, a district /madrid-capital/chamberi/l, flats only /pisos/, rentals /alquiler/), and listing URLs (https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/…/190909371/d) for one listing's whole record. | |
maxItemsPerSearch | integer | 100 | Stop each search (a place or a search URL) after this many new listings. 0 = every listing Fotocasa serves the search: up to about 9,900 (the site's limit of one search). |
maxItems | integer | 0 | Stop the whole run after this many listing rows, over every search. 0 = no run cap (each search keeps its own cap). |
feedback | string | A note to the people who maintain this Actor: what you needed and did not get. For example a missing field, a wrong or empty result, or the Actor you switch from or to, and why. The run does not read it: the rows and the charges stay the same. A person reads every note. |
Errors
A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:
- the status message starts with
INPUT REJECTED; - the dataset holds one row,
{"error": true, "code": "…", "message": "…"}, and no results; - the key-value store record
ERRORholds the same object.
From code, check error on the first row before reading results.
A URL that is not a Fotocasa search or listing URL (an agency page, the home page, another site) is not an error: it gets one free search row with status invalid that says why, and the run goes on with the others. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.
FAQ
Which status is which?
A search row's status is ok (listings served), no_results (the site lists nothing for it; read on two connections), not_found (a place, a search page or a listing the site does not have; checked on two connections), invalid (an empty value, a URL that is not a Fotocasa search or listing URL), duplicate (the same search or listing again in the input: read once; or a listing another input already delivered), failed (the site refused every try; free) or not_read (left at maxItems, the charge limit or the run's time limit). A listing row's status is ok.
Does it give a private advertiser's name or phone?
No. A professional advertiser's public name, page, logo and phone are delivered; a private advertiser is a person and is named by type only (advertiser_type private).
Why is the energy rating empty on search rows?
The site's search does not carry the energy certificate. A listing URL in searchUrls reads the listing's own page, and its row carries the energy and emissions ratings.
Does it need a Fotocasa account or API key?
No. Everything is read from fotocasa.es's public search and pages, logged out.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/fotocasa-scraper').call({"locations": ["Madrid"], "operation": "buy", "propertyType": "homes", "maxItemsPerSearch": 50});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/fotocasa-scraper').call(run_input={'locations': ['Madrid'], 'operation': 'buy', 'propertyType': 'homes', 'maxItemsPerSearch': 50})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/fotocasa-scraper --input '{"locations": ["Madrid"], "operation": "buy", "propertyType": "homes", "maxItemsPerSearch": 50}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~fotocasa-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"locations": ["Madrid"], "operation": "buy", "propertyType": "homes", "maxItemsPerSearch": 50}'
AI agents and MCP
Apify's MCP server offers this Actor as a tool to Claude, Cursor, VS Code and any other MCP client. Connect https://mcp.apify.com?tools=hyperbach/fotocasa-scraper and ask, for example: "Get 50 homes for sale in Madrid from Fotocasa with the price, surface, rooms and agency". The agent fills the input from the table above and reads the rows from the run's dataset. The input names are the ones in the table above. An agent or a person can add feedback to any run and say what was needed and not delivered: a missing field, a wrong or empty result, the Actor switched from or to, and why. The run returns the same rows at the same price, and a person reads every note.
n8n, Make and Zapier
The Apify node in n8n, the Apify app in Make and the Apify integration in Zapier run this Actor on a schedule or from a trigger and read its dataset. A webhook on the run's end (Integrations on the Actor page) sends the rows on to your own endpoint. Nothing to install on our side.
Support
Disagree with a charge? Write to apify@hyperbach.com with the run ID. We will ask Apify to compensate you, and the charge comes back to your Apify account as platform credit.
Did it do the job? A short review on the Store, at any rating, helps the next buyer choose.
See also
- Zillow Scraper — Zillow listings for sale, for rent and sold, by ZIP, city or search URL, with the Zestimate, and a property's price history.
- Redfin Scraper — Redfin homes for sale, sold and for rent by search URL, city or ZIP code, with the price, beds, baths, square feet, days on market and the MLS id.
- Immobiliare.it Scraper — Immobiliare.it homes for sale and for rent by search URL or place name, with the price, surface, rooms, the address and coordinates, and the agency.
- StreetEasy Scraper — StreetEasy NYC rentals and sales by search link, listing link or neighborhood, with the price, net effective rent, beds, baths, square feet, days on market, the building and the agents.
- Rightmove Scraper — Rightmove UK homes to buy or to rent by search link, listing link or place name, with the price, beds, baths, type, tenure, size, key features, floorplans and the agent branch.
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.