# Fotocasa Scraper: Spain Property Listings & Prices (`scrapemint/fotocasa-scraper`) Actor

Homes for sale and rent on fotocasa.es for any city or search URL: price and price per m², size, rooms, bathrooms, floor, condition, address, GPS, features, agency name and phone, photos and description. Pages to the end of any search. $0.0015 per listing.

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

## Pricing

$1.50 / 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 Property Listings & Prices

Property listings from **fotocasa.es**, one of Spain's largest property portals, for sale and for rent: **price and price per m²**, price reduction, size, bedrooms, bathrooms, **floor**, **condition**, street, neighbourhood, district, city, province, postcode, **GPS coordinates**, features (lift, parking, terrace, pool, air conditioning...), the **agency's name and phone number**, all photos and the full listing description.

Search by city or province, or paste any Fotocasa search URL with your filters, drawn zones or neighbourhoods. Fotocasa lets you page to the end of every search (Madrid alone has 12,000+ homes for sale), 100 listings per request.

No Fotocasa account, no API key, no proxy. $0.0015 per listing, no start fee.

### What you get per listing

- `listingId`, `url`, `operation` (sale or rent)
- `price`, `priceCurrency`, `priceReduction`, `pricePerM2`
- `sizeM2`, `rooms`, `bathrooms`, `floor`, `floorLabel`, `propertySubtype`, `condition`
- `hasElevator`, `hasParking`, `hasTerrace`, `hasBalcony`, `hasGarden`, `hasPool`, `hasAirConditioning`, `hasHeating`, `isNewBuild`
- `street`, `neighbourhood`, `district`, `city`, `province`, `region`, `zipCode`, `latitude`, `longitude`
- `advertiserName`, `advertiserPhone`, `advertiserUrl`, `advertiserId`
- `publishedAt`, `isHighlighted`, `hasVirtualTour`, `photoCount`, `photos`
- `description`

### Example input

Flats to rent in Sevilla and Málaga under €1,500 with 2+ bedrooms, newest first:

```json
{
  "locations": ["Sevilla", "Málaga"],
  "operation": "rent",
  "maxPrice": 1500,
  "minRooms": 2,
  "sortBy": "newest"
}
```

Every home for sale in Madrid under €400,000:

```json
{
  "locations": ["Madrid"],
  "maxPrice": 400000,
  "maxItemsPerSearch": 5000
}
```

A search URL copied from fotocasa.es (neighbourhoods, drawn areas and any filter work):

```json
{
  "searchUrls": ["https://www.fotocasa.es/es/comprar/viviendas/barcelona-capital/todas-las-zonas/l?maxPrice=600000&minRooms=3"]
}
```

### Example output

```json
{
  "listingId": 189316512,
  "url": "https://www.fotocasa.es/es/comprar/vivienda/madrid/aire-acondicionado-calefaccion-amueblado/189316512/d",
  "operation": "sale",
  "price": 369000,
  "priceCurrency": "EUR",
  "priceReduction": 40000,
  "pricePerM2": 6150,
  "sizeM2": 60,
  "rooms": 2,
  "bathrooms": 2,
  "floor": 0,
  "floorLabel": "ground floor",
  "propertySubtype": "flat",
  "condition": "very good",
  "hasAirConditioning": true,
  "street": "Calle de Los Relatores, Centro",
  "neighbourhood": "Embajadores - Lavapiés",
  "district": "Centro",
  "city": "Madrid Capital",
  "zipCode": "28012",
  "latitude": 40.41317,
  "longitude": -3.7032464,
  "advertiserName": "ENGEL & VÖLKERS MADRID",
  "advertiserPhone": "+34912774500",
  "publishedAt": "2026-04-08T11:16:19.933Z",
  "photoCount": 21,
  "description": "Engel&Völkers comercializa este acogedor apartamento de 60 m2 ..."
}
```

### Uses

- **Investors and analysts:** price per m² by neighbourhood, rental yields (run sale and rent for the same area), price cuts
- **Agencies and proptech:** competitor stock, new listings every day with **Newest first** on a schedule, agency phone numbers for outreach
- **Relocation and tenants:** every flat that matches, with coordinates for mapping
- **Market research:** stock, condition and size mix across Spanish cities and provinces

### Pricing

- **$0.0015** per listing, description, photos and phone included
- No start fee. A search with no results is free.

### Notes

- Locations are matched to Fotocasa's own place pages: a name like "Sevilla" is tried as the town, then "-capital", then "-provincia". For a neighbourhood or a drawn area, paste the search URL.
- Features such as `hasElevator` are `true` when the listing states them and `null` when it does not say.
- `floor` is a number (0 is ground floor, -1 basement); floors 15 and up show as `floorLabel: "15th floor or higher"`.
- A listing that appears in two of your searches is kept once.

# Actor input Schema

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

One search per city, town or province in Spain, e.g. Madrid, Barcelona, Sevilla, Marbella, Valencia provincia, España.

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

Listings for sale or for rent.

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

What kind of property to search.

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

Search pages copied from fotocasa.es with your area and filters set, including drawn zones and neighbourhoods. Filters below do not apply to these.

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

Optional. For rent this is the monthly rent.

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

Optional. For rent this is the monthly rent.

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

Optional, e.g. 2.

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

Optional, e.g. 2.

## `minSizeM2` (type: `integer`):

Optional.

## `maxSizeM2` (type: `integer`):

Optional.

## `sortBy` (type: `string`):

Order of results. Newest first with a schedule collects new listings as they appear.

## `includeDescription` (type: `boolean`):

Adds the advertiser's full listing text. Same price either way.

## `maxItemsPerSearch` (type: `integer`):

Stop each search after this many listings. Fotocasa lets you page to the end of every search, 100 listings per request.

## Actor input object example

```json
{
  "locations": [
    "Madrid"
  ],
  "operation": "buy",
  "propertyType": "homes",
  "searchUrls": [],
  "sortBy": "relevance",
  "includeDescription": true,
  "maxItemsPerSearch": 300
}
```

# Actor output Schema

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

Price, size, rooms, floor, condition, address, coordinates, features, advertiser and phone, photos and description.

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

Listings on Fotocasa and listings saved per search, the search URL used, and any searches that failed.

# 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("scrapemint/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 = { "locations": ["Madrid"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapemint/fotocasa-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 '{
  "locations": [
    "Madrid"
  ]
}' |
apify call scrapemint/fotocasa-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapemint/fotocasa-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/phfkyeGdHpKbYGlKR/builds/21FFwLNnEs78s3zs5/openapi.json
