# Fotocasa Scraper — Spain Real Estate & Agency Leads (MCP) (`amygraphics/fotocasa-spain-scraper`) Actor

Fotocasa scraper for all Spain: pisos, chalets & rentals in every province with price drops, m2, rooms, photos, GPS + the agency phone number. Beats the 10 000-listing cap automatically. Monitor mode: only new listings, price cuts & removed ads. MCP-ready.

- **URL**: https://apify.com/amygraphics/fotocasa-spain-scraper.md
- **Developed by:** [Zakaria el bouami](https://apify.com/amygraphics) (community)
- **Categories:** Real estate, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 Spain Real Estate Scraper — Agency Leads & Price Monitor (MCP)

Scrape **Fotocasa.es**, Spain's #1 property portal (**471 000+ live listings**), for sale or rent, in
all 50 provinces — one clean row per property, no browser, no proxies, no account.

**Find → Compare → Monitor → Alert.** Every row comes with the data buyers, exporters and agencies
actually pay for:

| What you get | Why it matters |
|---|---|
| **Agency telephone number** (`phone`) on **100 %** of listings checked | Lead generation without opening a single detail page |
| **Price-reduction flag** (`isPriceReduced`, `reducedAmount`) | Fotocasa's own "rebajado" signal — the buying opportunity |
| Full decoded specs | surface m², rooms, bathrooms, floor, age + every amenity code (pool, terrace, lift, storage, furnished…) |
| **Days on market** + original publication date | spot stale listings whose owner will negotiate |
| Location precision | province, municipality, city, **district & barrio**, zip, GPS coordinates |
| Photos & media flags | up to 25 original-size photo URLs, video, floorplans, virtual tour |
| Special situations | auctions (subasta), bare ownership, occupied, rented with tenants, VPO subsidies, new developments |

### Hard problems this Actor solves

1. **The 10 323-listing cap.** Every Fotocasa search silently stops at **page 333** (31 listings per
   page); go deeper and the site just re-serves the last page — no error, no warning. This Actor knows
   the cap, detects page rotation, and **splits the query recursively: price bands → rooms → surface**,
   merging by unique listing id. "All of Madrid province" or "Spain" is the whole market, not a sample.
   Every split and its result count is written to the run log, so you can audit coverage.
2. **Filters that really work.** Price, surface and rooms filters are honoured by Fotocasa *only* as
   query parameters — and an explicit `min*=0` makes the site answer **404**. The Actor knows both traps
   and builds clean queries (we found and fixed this on the live site before shipping).
3. **Honest monitoring.** State lives in an Apify key-value store, one history per search scope. You get
   `new`, **`price_dropped`** / `price_increased` (with `oldPrice`, delta and %), and `closed` — the last
   one only when the scan was complete and error-free, never on a failed request or a truncated scope.

### Quick examples

- **Agency leads in Barcelona** — `buy`, `barcelona-capital`, no other filter → every listing with the
  agency's name and phone number.
- **Cheap flats in Madrid** — `madrid-capital`, `maxPrice: 150000`, `minRooms: 2`.
- **Rentals in Valencia** — `operation: rent`, `valencia-capital`, `maxPrice: 1200`.
- **A whole province** — `madrid` (province) or `espana` (whole country) with `autoSplit` on.
- **Daily price-drop watch** — `mode: monitor` on a schedule: only new listings and price cuts come back.
- **Auctions & opportunities** — look at `isAuctioned`, `isOpportunity`, `isBareOwnership`,
  `isRentedWithTenants` flags in the output.

### Input tips

- `locations`: Fotocasa segments — `espana`, `madrid`, `barcelona`, `madrid-capital`,
  `barcelona-capital`, `valencia-capital`, `madrid-capital/chamberi`… spaces and accents are fine.
- `propertyType`: `viviendas` (homes, default) or a specific segment (`pisos`, `chalets`, `aticos`,
  `locales`, `garajes`, …).
- `addedWithinDays`: with "newest first" sorting the Actor stops as soon as it reaches older ads —
  perfect for cheap incremental runs.
- `maxResults`: global cap on rows returned (and billed); the run stops cleanly when reached.
- `stateKey`: leave empty; the monitor history key is derived from your search scope.

### Automation, MCP & scheduling

- **Schedule**: run `monitor` daily (or hourly). Unchanged listings are not returned and not charged —
  only the deltas land in your dataset.
- **Integrations**: pipe the dataset to Google Sheets, Airtable, Slack, n8n, Zapier or your own API in
  one click through the Apify platform.
- **MCP-ready for AI agents**: exposed through Apify's Model Context Protocol server as
  `amygraphics/fotocasa-spain-scraper`, so agents (Claude, Cursor, VS Code, custom agents) can find and
  run it — and pay autonomously (this Actor is **whitelisted for agentic payments**, x402 / AGI).

```json
{
  "mcpServers": {
    "apify": { "url": "https://mcp.apify.com?tools=amygraphics/fotocasa-spain-scraper" }
  }
}
```

Ask it things like:

- *"Find flats for sale in Madrid under €200 000 with at least 3 rooms and give me the agencies' phones."*
- *"Which listings in Barcelona dropped their price? Set it up to run every morning."*
- *"Get me every chalet for sale in the province of Madrid with a pool."*

### Pricing

Pay-per-event: **$0.001** start + **`$0.002` per property** (`property-extracted`) — **$2 per 1 000
listings**, cheaper than every pay-per-event Fotocasa Actor in the Store. Monitor mode only charges for
new, changed and closed listings.

### Notes & fair use

Publicly available listing data from Fotocasa search pages. Agency names and phone numbers are
**business contact data the agencies publish on their own adverts** — if you use them for outreach,
that outreach is your responsibility: follow your local e-mail/phone marketing rules (EU GDPR +
ePrivacy for individuals), Fotocasa's terms, and keep request rates polite (the Actor throttles itself
and retries `429`/`5xx` with backoff).

***

### En español (breve)

**Scraper de Fotocasa para toda España**: venta y alquiler, cualquier provincia, ciudad o barrio.
Cada fila incluye **el teléfono de la agencia**, si el precio está **rebajado** (con el importe),
superficie, habitaciones, baños, fotos, GPS, días en el mercado y los códigos de características
(piscina, terraza, ascensor, amueblado…). Fotocasa corta **en silencio** cada búsqueda en la página 333
(10 323 anuncios): este Actor lo detecta y **divide la búsqueda por precio → habitaciones → superficie**
para que el mercado completo esté cubierto. **Modo monitor**: sólo anuncios nuevos, bajadas de precio
y retirados. **2 $ por 1 000 anuncios.**

#### Palabras clave

Fotocasa scraper · API alternativa a Fotocasa · pisos Madrid · España inmobiliaria · alquiler España ·
teléfonos de agencias · price monitor · bajadas de precio · datos inmobiliarios España · agente IA
inmobiliario · MCP inmobiliaria.

# Actor input Schema

## `mode` (type: `string`):

search = extract every matching listing. monitor = compare with the previous run and return only what is new, changed (price cuts included) or gone — ideal for a daily schedule.

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

Buy (comprar) or rent (alquiler).

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

One location per item, as Fotocasa writes it in its URLs: country 'espana', province 'madrid' or 'barcelona', city 'madrid-capital', 'barcelona-capital', 'valencia-capital', or a barrio 'madrid-capital/chamberi'. Spaces and accents are fine ('Madrid Capital' → madrid-capital).

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

Fotocasa type segment. 'viviendas' = homes in general (recommended).

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

Optional.

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

Optional. Also the first splitting dimension when a search is capped.

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

Optional.

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

Optional.

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

Optional.

## `maxRooms` (type: `integer`):

Optional.

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

Newest first is recommended (used for monitoring); price sorting works for market scans.

## `addedWithinDays` (type: `integer`):

Optional. With 'newest first' sorting the Actor stops as soon as it reaches older listings — cheap incremental runs.

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

Global cap on rows returned (and charged).

## `autoSplit` (type: `boolean`):

Recommended. Fotocasa cuts every search at 10 323 listings (page 333) without warning; the Actor splits such searches by price → rooms → surface and merges the results.

## `includeImages` (type: `boolean`):

Up to 25 original-size photo URLs per listing.

## `onlyChanges` (type: `boolean`):

Monitor mode only. Unchanged listings are not returned and not charged.

## `detectClosed` (type: `boolean`):

Monitor mode only. Listings that disappeared from Fotocasa are returned once with changeType='closed'. Only when the scan was complete and error-free.

## `stateKey` (type: `string`):

Leave empty: derived from your search scope, so each search keeps its own history.

## Actor input object example

```json
{
  "mode": "search",
  "operation": "buy",
  "locations": [
    "madrid-capital",
    "barcelona-capital",
    "valencia-capital"
  ],
  "propertyType": "viviendas",
  "minPrice": null,
  "maxPrice": null,
  "minSurface": null,
  "maxSurface": null,
  "minRooms": null,
  "maxRooms": null,
  "sort": "newest",
  "addedWithinDays": null,
  "maxResults": 20,
  "autoSplit": true,
  "includeImages": true,
  "onlyChanges": true,
  "detectClosed": true,
  "stateKey": ""
}
```

# Actor output Schema

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

No description

# 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 = {
    "mode": "search",
    "operation": "buy",
    "locations": [
        "madrid-capital"
    ],
    "propertyType": "viviendas",
    "sort": "newest",
    "maxResults": 20,
    "autoSplit": true,
    "includeImages": true,
    "onlyChanges": true,
    "detectClosed": true,
    "stateKey": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("amygraphics/fotocasa-spain-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 = {
    "mode": "search",
    "operation": "buy",
    "locations": ["madrid-capital"],
    "propertyType": "viviendas",
    "sort": "newest",
    "maxResults": 20,
    "autoSplit": True,
    "includeImages": True,
    "onlyChanges": True,
    "detectClosed": True,
    "stateKey": "",
}

# Run the Actor and wait for it to finish
run = client.actor("amygraphics/fotocasa-spain-scraper").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 '{
  "mode": "search",
  "operation": "buy",
  "locations": [
    "madrid-capital"
  ],
  "propertyType": "viviendas",
  "sort": "newest",
  "maxResults": 20,
  "autoSplit": true,
  "includeImages": true,
  "onlyChanges": true,
  "detectClosed": true,
  "stateKey": ""
}' |
apify call amygraphics/fotocasa-spain-scraper --silent --output-dataset

```

## MCP server setup

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

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/d2KNunj4MYOiPBIWi/builds/fkAP71lGmUO2gjvWy/openapi.json
