# Fotocasa Scraper - Spain Real Estate (`scrapesage/fotocasa-scraper`) Actor

Scrape Fotocasa — Spain's top real estate portal. Homes for sale or rent with prices, m², rooms, energy rating, photos, geo, full description & agency leads (name, phone, profile). Filter by city, price, size. Monitor new listings & price drops. Export JSON, CSV, Excel.

- **URL**: https://apify.com/scrapesage/fotocasa-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 property scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Fotocasa Scraper — Spain Real Estate Listings, Prices, Energy Ratings & Agency Leads

Extract **complete data from [Fotocasa](https://www.fotocasa.es)** — Spain's leading real estate portal. Get homes **for sale or for rent** with **prices, price per m², bedrooms, bathrooms, surface, energy certificate, full address with geo, every photo, the full description, and the advertising agency's name, profile and phone** — all in one clean dataset.

No login, no cookies, no browser — fast, reliable extraction by **city, filter, or pasted URL**, with a built-in **monitor mode** to track new listings and price drops.

### Why this Fotocasa scraper?

Generic "paste-a-URL" scrapers grab a handful of visible fields. This actor reads Fotocasa's own structured data and opens each listing's detail page, so it ships the **richest dataset in the category** — including the **energy performance certificate** and decoded property attributes that thin scrapers skip.

| Data | Generic scrapers | This actor |
|---|---|---|
| Price, price per m², price drops | partial | ✅ |
| Bedrooms, bathrooms, surface (m²) | partial | ✅ |
| Full address: neighborhood, district, city, province, **zip** | partial | ✅ |
| **Geo coordinates** (lat/lng) | ❌ | ✅ |
| **Energy certificate** (rating, consumption, CO₂ emissions) | ❌ | ✅ |
| Decoded features: orientation, condition, age, floor | ❌ | ✅ |
| Amenities (parking, lift, pool, terrace, A/C, heating…) | partial | ✅ |
| Full description + **all photos** (not just the cover) | partial | ✅ |
| Advertiser name, type, **phone**, profile, website | ❌ | ✅ |
| Deduplicated **agency leads** with lead score | ❌ | ✅ |
| Monitor mode (only new listings & price changes) | ❌ | ✅ |

### Use cases

- **Real estate market research & comps** — pull every listing in a city or neighborhood with price per m², surface, energy rating and listing age to build comparables and price models.
- **Lead generation for proptech & services** — each advertiser is a ready B2B lead: agency name, phone, Fotocasa profile and website, with active-listing counts and a 0–100 lead score. Perfect for CRM, mortgage, insurance, home-staging, photography and portal-tool vendors.
- **Investment & deal sourcing** — filter by price, size and advertiser, and use **monitor mode** to get alerted the moment a new listing or a price drop appears.
- **Portal & app data** — power your own search, alerts or valuation product with structured, geocoded Spanish property data.
- **Energy & sustainability analysis** — every detail page carries the official energy-efficiency rating and CO₂ emissions for energy-performance studies.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **Fotocasa Scraper**, type a **Location** (e.g. `Madrid`, `Barcelona`, `Valencia`, `Marbella`), choose **For sale / For rent** and a **Property type**, and add any filters you like.
3. Click **Start** and watch results stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

> Prefer pixel-perfect control? Apply every filter on fotocasa.es and paste the resulting URL into **Start URLs** — the scraper paginates it for you.

### Input

```json
{
    "location": "Barcelona",
    "transactionType": "buy",
    "propertyType": "homes",
    "minPrice": 150000,
    "maxPrice": 700000,
    "minRooms": 2,
    "includePropertyDetails": true,
    "includeAgencyLeads": true,
    "maxResults": 100
}
```

- **location** / **locations** — a Spanish city or area (`Madrid`, `Barcelona`, `Valencia`, `Sevilla`, `Marbella`…). Major markets resolve automatically; you can also pass a Fotocasa location slug (`madrid-capital`).
- **transactionType** — `buy`, `rent`, `rent-to-own`, `share`, or `transfer`.
- **propertyType** — `homes` (flats + houses), `new-homes`, `apartments`, `houses`, `penthouses`, `studios`, `offices`, `commercial-premises`, `land`, and more.
- **searchUrls** *(optional)* — paste any Fotocasa search/listing URL; detail (`/d`) URLs are scraped as single properties.
- **propertyUrls** *(optional)* — scrape specific listings by their detail URL.
- **Filters** — `minPrice`/`maxPrice`, `minRooms`, `minBathrooms`, `minSurface`/`maxSurface`, `onlyNewConstruction`, `onlyWithPhoto`, `onlyPriceReduced`, `advertiserType` (agencies / private), `maxAgeDays`.
- **includePropertyDetails** *(default true)* — open each listing for the energy certificate, decoded features and full photo set.
- **includeAgencyLeads** *(default true)* — also output deduplicated advertiser leads.
- **monitorMode** + **monitorKey** — output only new listings and price changes across runs.
- **maxResults** / **maxAgencyLeads** — caps per run.
- **proxyConfiguration** — defaults to Apify Residential, country **ES** (required for Fotocasa).

### Output

Two record types land in the same dataset (use the **Properties** and **Agency leads** dataset views, or filter on the `type` field).

A property record (`type: "property"`):

```json
{
    "type": "property",
    "id": 189463519,
    "url": "https://www.fotocasa.es/es/comprar/vivienda/barcelona-capital/.../189463519/d",
    "transactionType": "For sale",
    "propertyType": "Flat",
    "title": "Attic, 3 bed in Fort Pienc",
    "price": 520000,
    "currency": "EUR",
    "pricePerSqm": 6500,
    "previousPrice": null,
    "priceReduced": false,
    "rooms": 3,
    "bathrooms": 1,
    "surface": 80,
    "neighborhood": "Fort Pienc",
    "district": "Eixample",
    "city": "Barcelona",
    "province": "Barcelona",
    "zipCode": "08013",
    "latitude": 41.3984,
    "longitude": 2.1812,
    "amenities": ["Air conditioning", "Heating", "Elevator", "Furnished"],
    "energyRating": "E",
    "energyConsumption": 142.0,
    "emissionsRating": "E",
    "emissions": 30,
    "orientation": "South",
    "conservationState": "Good",
    "antiquity": "Between 30 And 50 Years",
    "floor": "6th Floor",
    "description": "Piso exterior y muy luminoso…",
    "images": ["https://static.fotocasa.es/images/ads/…?rule=original", "…"],
    "imageCount": 27,
    "listedDaysAgo": 12,
    "publishedAt": "2026-06-07T10:21:00.000Z",
    "advertiserType": "professional",
    "agencyName": "CUATRO CASAS INMOBILIARIA",
    "agencyUrl": "https://www.fotocasa.es/es/inmobiliaria-cuatro-casas/...",
    "phone": "+34932651778",
    "scrapedAt": "2026-06-19T22:34:00.000Z"
}
```

An agency lead record (`type: "agencyLead"`) carries `agencyName`, `advertiserType`, `phone`, `agencyUrl`, `agencyWebsite`, `activeListingCount`, `cities`, `neighborhoods`, `propertyTypes`, `minPrice`/`maxPrice`, `sampleListings` and a 0–100 `leadScore`.

#### What to expect (field coverage)

Fotocasa is advertiser-entered data, so a few fields are present only when the agency filled them in. Verified across Madrid and Barcelona, with **full details enabled** you can typically expect:

| Field group | Coverage |
|---|---|
| Price, price per m², rooms, baths, surface | ~100% |
| Address (neighborhood/city/province/zip) + geo | ~100% |
| Energy certificate, orientation, floor, condition, age | ~95–100% (from the detail page) |
| Amenities, full description, all photos | ~100% |
| Advertiser name, type, phone, profile | ~100% |
| Price drop / previous price | only when the advertiser dropped the price |

A blank field means the advertiser didn't publish it — not that scraping failed. Nothing is dropped, so you always get the richest dataset available.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily/weekly with **monitor mode** to capture new listings and price drops as they happen.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/fotocasa-scraper').call({
    location: 'Barcelona',
    transactionType: 'buy',
    propertyType: 'homes',
    maxResults: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new property leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search adds listings or drops prices.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find every 2-bed flat under €400k in Valencia with its energy rating and the agency's phone" and let it run the scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **global real estate & lead-gen stack** — one portal per market:

- **[Redfin Scraper](https://apify.com/scrapesage/redfin-scraper)** — US homes for sale & rent with prices and agent data.
- **[Rightmove Scraper](https://apify.com/scrapesage/rightmove-scraper)** — UK property listings, prices and agent leads.
- **[Realtor.ca Scraper](https://apify.com/scrapesage/realtor-ca-scraper)** — Canadian real estate listings and agent/brokerage leads.
- **[Immoweb Scraper](https://apify.com/scrapesage/immoweb-scraper)** — Belgium's #1 property portal with EPC and agency leads.
- **[VivaReal & ZAP Imóveis Scraper](https://apify.com/scrapesage/vivareal-zap-imoveis-scraper)** — Brazil's top real estate portals with broker leads.
- **[Property Finder Scraper](https://apify.com/scrapesage/property-finder-scraper)** — UAE/GCC listings, off-plan projects and agent leads.
- **[Crexi Scraper](https://apify.com/scrapesage/crexi-scraper)** — US commercial real estate with broker leads.
- **[Rent.com Scraper](https://apify.com/scrapesage/rent-com-scraper)** — US rental listings and property-management leads.
- **[Kleinanzeigen Scraper](https://apify.com/scrapesage/kleinanzeigen-scraper)** — Germany's #1 classifieds (incl. property) with seller leads.

### Tips

- **Focus your search** for a clean, dense table — set a `location` plus price/size filters. Use **Start URLs** when you've already dialed in a search on fotocasa.es.
- **Full details on** is the difference between a listing and an investable record — it adds the energy certificate, orientation, floor, condition and the complete photo set (one fast request per listing).
- **Agency leads**: keep `includeAgencyLeads` on to turn every search into a prospect list, ranked by lead score.
- **Recurring monitoring**: combine **monitor mode** with a [Schedule](https://docs.apify.com/platform/schedules) to track a market and only pull new listings and price drops — no duplicates.

### FAQ

**How do I scrape a specific city or area?** Type it in **Location** (`Madrid`, `Barcelona`, `Valencia`, `Marbella`…). For anything not auto-resolved, pass a Fotocasa location slug (`madrid-capital`) or paste a search URL.

**Does it need the Fotocasa API or a key?** No. This actor reads Fotocasa's public, server-rendered data and detail pages — no key, login, or browser needed.

**Can I get for-rent listings?** Yes — set `transactionType` to `rent` (or `rent-to-own`, `share`, `transfer`). Rental prices are monthly.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I monitor a market for new listings or price drops?** Turn on **monitor mode** and create a [Schedule](https://docs.apify.com/platform/schedules) (e.g. daily). The actor remembers what it has seen and outputs only new listings and price changes — add a [webhook](https://docs.apify.com/platform/integrations/webhooks) or [Zapier zap](https://docs.apify.com/platform/integrations/zapier) to push them into your CRM.

**Why residential proxy?** Fotocasa serves its data to Spanish residential IPs. The default (Apify Residential, country ES) is set for you and is strongly recommended.

**A field is empty — why?** Some advertisers don't publish a price drop, an energy rating or a website. Fields are blank only when the advertiser didn't provide that data — never because the scraper skipped it.

**Is scraping Fotocasa legal?** This actor collects publicly available data only. You're responsible for using the data in compliance with applicable laws (e.g. GDPR for personal data) and Fotocasa's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `location` (type: `string`):

A Spanish city or area to search — e.g. <code>Madrid</code>, <code>Barcelona</code>, <code>Valencia</code>, <code>Marbella</code>. Major cities are resolved automatically; you can also pass a Fotocasa location slug (e.g. <code>madrid-capital</code>) or use <b>Start URLs</b> for full control.

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

Search several locations in one run. Each is combined with the transaction, property type and filters below.

## `transactionType` (type: `string`):

What kind of deal to search.

## `propertyType` (type: `string`):

Type of property. <code>Homes</code> covers flats and houses. Choose a subtype, or use <code>New developments</code> for new construction.

## `zone` (type: `string`):

Fotocasa zone/district slug within the location. Leave as <code>todas-las-zonas</code> for all zones.

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

Paste any Fotocasa search/listing page URL — apply every filter on fotocasa.es and copy the URL here (e.g. <code>https://www.fotocasa.es/es/comprar/viviendas/barcelona-capital/todas-las-zonas/l</code>). Used in addition to the location above. Detail (<code>/d</code>) URLs are scraped as single properties.

## `propertyUrls` (type: `array`):

Scrape specific listings directly — paste Fotocasa property detail URLs (those ending in <code>/d</code>).

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

Minimum price. For rentals this is the monthly rent.

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

Maximum price. For rentals this is the monthly rent.

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

Minimum number of bedrooms.

## `minBathrooms` (type: `integer`):

Minimum number of bathrooms.

## `minSurface` (type: `integer`):

Minimum built surface in square meters.

## `maxSurface` (type: `integer`):

Maximum built surface in square meters.

## `onlyNewConstruction` (type: `boolean`):

Keep only new-build / off-plan listings.

## `onlyWithPhoto` (type: `boolean`):

Keep only listings that have at least one photo.

## `onlyPriceReduced` (type: `boolean`):

Keep only listings whose price was recently dropped.

## `advertiserType` (type: `string`):

Limit to professional (agency) or private (owner) listings.

## `maxAgeDays` (type: `integer`):

Keep only listings published within this many days. Great for monitoring fresh inventory.

## `includePropertyDetails` (type: `boolean`):

Open each listing's detail page for the energy certificate, decoded features (orientation, condition, age, floor), construction type, plot size and the full photo set. One extra request per listing.

## `includeAgencyLeads` (type: `boolean`):

Also output a deduplicated list of advertising agencies/owners as B2B leads (name, phone, profile, active-listing count, cities, price range and a 0-100 lead score).

## `maxResults` (type: `integer`):

Maximum number of property records to scrape across all searches.

## `maxAgencyLeads` (type: `integer`):

Maximum number of agency lead records to output (highest lead score first).

## `monitorMode` (type: `boolean`):

Remember listings across runs and output only NEW listings and PRICE CHANGES. Pair with Apify Schedules to track a market for fresh inventory and price drops.

## `monitorKey` (type: `string`):

Name for this monitor's memory. Use a different key per saved search you track separately.

## `proxyConfiguration` (type: `object`):

Proxy settings. Fotocasa requires Spanish residential IPs — the default (Apify Residential, country ES) is strongly recommended.

## Actor input object example

```json
{
  "location": "Madrid",
  "transactionType": "buy",
  "propertyType": "homes",
  "zone": "todas-las-zonas",
  "onlyNewConstruction": false,
  "onlyWithPhoto": false,
  "onlyPriceReduced": false,
  "advertiserType": "any",
  "includePropertyDetails": true,
  "includeAgencyLeads": true,
  "maxResults": 100,
  "maxAgencyLeads": 200,
  "monitorMode": false,
  "monitorKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped property records and optional agency lead records as JSON items in the default dataset.

# 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 = {
    "location": "Madrid"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/fotocasa-scraper").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 = { "location": "Madrid" }

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

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

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

```

## CLI example

```bash
echo '{
  "location": "Madrid"
}' |
apify call scrapesage/fotocasa-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/fotocasa-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WroVksCLI1A2JzhDG/builds/Fnw6e6Qp3WeOE5aiT/openapi.json
