# Fotocasa Scraper: Spain Housing Prices, €/m² & Market Report (`precious_bathmat/fotocasa-housing-market`) Actor

Scrape Fotocasa.es homes for sale or rent in any Spanish city, town or province: price, €/m², m², rooms, district, neighbourhood, price cuts, days listed, agency. Plus a market report with best-value homes. No login.

- **URL**: https://apify.com/precious_bathmat/fotocasa-housing-market.md
- **Developed by:** [Mariam Ahmed](https://apify.com/precious_bathmat) (community)
- **Categories:** Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Fotocasa Scraper: Spain Housing Prices, €/m² & Market Report

Scrape **Fotocasa.es**, one of Spain's biggest property portals, with no login and no API key, and get a **housing market report for every city**:

- **Every home for sale or to rent**: price, **€/m²**, m², rooms, bathrooms, type, district, neighbourhood, postcode, coordinates (agency listings), features (lift, terrace, parking, pool, air conditioning...), photos, link
- **Price cuts and time on market**: how much the price was cut, the price before, and how many days the home has been listed
- **Any Spanish place**: cities ("Madrid", "Valencia"), towns ("Marbella", "Sitges"), provinces ("Málaga provincia"), or **paste any Fotocasa search link** (a district, a drawn area, any filters)
- **Filters**: for sale or to rent, price range, minimum rooms, Fotocasa's order or newest first
- **Market report per search**: median price and €/m² with the middle half, by rooms, district and neighbourhood, share with price cuts and the typical cut, days listed, new listings, private vs agency, **best-value homes** (under 80% of their neighbourhood's €/m²), top agencies

### What does this Fotocasa scraper do?

```
Fotocasa · Madrid · for sale · 12,071 homes
 Median 599,000 € (395,000 – 1,105,000 €) · 7,353 €/m² · 90 m²
 Typical home listed 79 days · 30% have cut their price (median -5.8%)
 Barrio de Salamanca 10,869 €/m² · Centro 7,739 €/m²
 56 best-value homes under 80% of their neighbourhood's €/m²
```

1. Enter **Spanish cities, towns or provinces**, or paste **Fotocasa search links**.
2. Pick **for sale or to rent**, **price range**, **minimum rooms**.
3. You get **one row per home** and **one market report per search**.

```mermaid
flowchart LR
    A[Cities, towns,<br/>provinces] --> C[Fotocasa<br/>search]
    B[Fotocasa links<br/>districts, filters] --> C
    C --> D[Homes<br/>price, €/m², rooms,<br/>neighbourhood, cuts]
    D --> E[Market report<br/>€/m² by area,<br/>days listed, best value]
```

### Who is it for?

- **Property investors**: €/m² by neighbourhood, homes priced under their area, sellers who are cutting prices
- **Estate agents and agencies**: the market in your patch, how long homes sit, which agencies list the most
- **Buyers and renters**: what a fair price is in each district before you make an offer
- **Proptech, banks and valuers**: a fresh price sample for any Spanish city, with coordinates for mapping
- **Analysts and journalists**: asking prices and rents across Spain, by city, district and size

### What data do you get?

**Listings** (dataset, one row per home)

| Field | What it tells you |
|---|---|
| `id`, `url`, `operation` | The home, for sale or to rent |
| `price`, `pricePeriod`, `pricePerSqm` | Price in euros (monthly when renting) and per m² |
| `priceReducedBy`, `priceBeforeReduction` | The price cut, and the price before it |
| `surfaceSqm`, `rooms`, `bathrooms`, `propertyType` | Size and type |
| `district`, `neighborhood`, `zipCode`, `municipality`, `province`, `region` | Where |
| `latitude`, `longitude` | Map position (agency listings) |
| `daysListed`, `daysSinceUpdate` | Time on market |
| `amenities`, `furnished`, `photos`, `hasVideo`, `hasVirtualTour` | Features |
| `sellerType`, `agency`, `agencyUrl` | Private seller or agency |
| `isNewConstruction`, `isBankOwned`, `isAuction`, `isOccupied`, `rentedWithTenants`, `bareOwnership`, `isPromoted` | Special situations |
| `vsAreaPercent`, `comparedWith`, `areaMedianPricePerSqm`, `bestValue` | €/m² against the neighbourhood (or district) median |
| `description` | With **Descriptions** on |

**Report** (`REPORTS`, one per search)

| Field | What it tells you |
|---|---|
| `totalListings`, `listingsRead` | Fotocasa's count for the search, and how many were read |
| `medianPrice`, `price25`, `price75`, `medianPricePerSqm`, `pricePerSqm25`, `pricePerSqm75`, `medianSurfaceSqm` | Prices |
| `byRooms`, `byDistrict`, `byNeighborhood`, `byPropertyType` | Median price and €/m² by group |
| `medianDaysListed`, `listedOver180DaysPercent`, `newLast7Days`, `newLast30Days` | Time on market |
| `priceReducedPercent`, `medianReduction`, `medianReductionPercent`, `biggestReductions` | Price cuts |
| `bestValue`, `bestValueCount` | Homes under 80% of their area's €/m² |
| `privateSellerPercent`, `newConstructionPercent`, `bankOwnedPercent`, `amenitiesPercent`, `topAgencies` | The market's make-up |

### Example: 3 October 2026

Six markets, homes for sale, 300 listings each: **1,800 listings and 6 reports in 96 seconds**.

| City | Homes for sale | Median price (middle half) | €/m² | Days listed | Price cut |
|---|---|---|---|---|---|
| Madrid | 12,071 | 599,000 € (395,000 – 1,105,000) | 7,353 | 79 | 30% (-5.8%) |
| Barcelona | 14,393 | 562,000 € (400,500 – 851,250) | 6,367 | 114 | 27% (-6.7%) |
| Marbella | 8,651 | 695,000 € (429,000 – 1,492,500) | 4,953 | 117 | 24% (-6.4%) |
| Valencia | 3,774 | 375,000 € (270,000 – 546,000) | 3,938 | 89 | 30% (-7.1%) |
| Málaga | 4,481 | 367,000 € (285,000 – 565,000) | 3,893 | 86 | 38% (-6.1%) |
| Sevilla | 3,479 | 295,250 € (197,000 – 448,250) | 3,113 | 80 | 34% (-5.6%) |

- **Barcelona to rent**: median **1,528 € a month**, **27.50 €/m²**; Ciutat Vella 33.10 €/m², Eixample 30.60 €/m².
- **Málaga province, 3,000 homes in 2 minutes 3 seconds**: Málaga city, Marbella, Estepona and Mijas lead.

### Pricing

**$0.001 per listing** and **$0.02 per search report**.

- 300 homes with a report: **$0.32**
- The run above (1,800 homes, 6 reports): **$1.92**
- 3,000 homes with a report: **$3.02**

Turn off reports to pay for listings only.

### Good to know

- **Order**: by default listings come in Fotocasa's own order, a mix of new and older homes, so the report is a fair sample of the market. **Newest first** gives the latest listings for a daily feed (days listed and price cuts are then small).
- **The report covers the listings read**; `totalListings` is Fotocasa's count for the whole search. Read more listings for a fuller picture (up to 10,000 per search).
- **Best value** = €/m² under 80% of the median of the same neighbourhood (or district, or the whole search) with at least 5 homes to compare. Auctions, bare ownership, occupied homes and homes rented with tenants are left out of prices.
- **Places**: provincial capitals, towns and provinces work by name ("Madrid", "Marbella", "Málaga provincia", "San Sebastián", "Ibiza"). For a district or a drawn area, paste the Fotocasa link. A pasted link keeps its own filters.
- **Privacy**: private sellers are not named and their homes carry no coordinates. Phone numbers are not collected; emails and phone numbers in descriptions are hidden. Agencies are named.
- Data comes from **Fotocasa.es's public search pages**. **Not affiliated with Fotocasa or Adevinta.**

### Input

| Field | Meaning |
|---|---|
| **Locations** | Spanish cities, towns or provinces |
| **For sale or to rent** | Comprar or alquiler |
| **Price from / to** | € (monthly when renting) |
| **Rooms from** | Minimum bedrooms |
| **Order** | Fotocasa's order (default) or newest first |
| **Fotocasa search links** | Any search link from fotocasa.es |
| **Listings per search** | 1 to 10,000 (default 300) |
| **Descriptions** | Add the full description text |
| **Reports** | On by default |

### Integrations

Export to JSON, CSV, Excel or Google Sheets, or connect through the Apify API, webhooks, Make, Zapier and n8n. **Schedule it weekly** to track prices and price cuts in your markets.

# Actor input Schema

## `locations` (type: `array`):

Spanish cities, towns or provinces, e.g. "Madrid", "Barcelona", "Marbella", "Valencia", "Málaga provincia", "San Sebastián". One search each.

## `operation` (type: `string`):

Homes for sale or to rent.

## `minPrice` (type: `integer`):

Only homes priced at least this (monthly rent when renting).

## `maxPrice` (type: `integer`):

Only homes priced at most this.

## `minRooms` (type: `integer`):

Only homes with at least this many bedrooms.

## `sort` (type: `string`):

Fotocasa's own order mixes new and older listings, so reports describe the whole market. Newest first gives the latest listings.

## `searchUrls` (type: `array`):

Optional: paste search links from fotocasa.es (a district, a drawn area, any filters). The link's own filters win; the price and room filters above fill in what the link does not set.

## `maxListingsPerSearch` (type: `integer`):

Most listings to read per location or link (about 30 per page).

## `includeDescriptions` (type: `boolean`):

Add each listing's full description text (contact details hidden).

## `includeReports` (type: `boolean`):

One market report per search: median price and €/m², by rooms, district and neighbourhood, price cuts, days listed, new listings, best-value homes, top agencies.

## Actor input object example

```json
{
  "locations": [
    "Madrid"
  ],
  "operation": "sale",
  "sort": "relevance",
  "maxListingsPerSearch": 300,
  "includeDescriptions": false,
  "includeReports": true
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per home: price, €/m², m², rooms, bathrooms, district and neighbourhood, price cut, days listed, agency, features, link.

## `reports` (type: `string`):

Per search: median price and €/m², by rooms, district and neighbourhood, price cuts, days listed, best-value homes, agencies.

## `reportsCsv` (type: `string`):

One flat row per search.

## `summary` (type: `string`):

Requests, problems and the limits of the data.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locations": [
        "Madrid"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/fotocasa-housing-market").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "locations": ["Madrid"] }

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/fotocasa-housing-market").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locations": [
    "Madrid"
  ]
}' |
apify call precious_bathmat/fotocasa-housing-market --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/fotocasa-housing-market"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zdH6FM84uAcOiTb0X/builds/2xiiQyAcIXStRQy0Q/openapi.json
