# Fotocasa Scrape- LowCost | HiQuality (`scraper_gump/fotocasa-scraper`) Actor

▎ Reliable Fotocasa data, at a fair price. ▎ We built the most efficient scraper for Fotocasa because we believe quality data shouldn't cost a fortune. No captchas, no browser overhead — just ▎ clean, structured data that works. ▎ Questions or ideas? → info@inmocalc.com

- **URL**: https://apify.com/scraper\_gump/fotocasa-scraper.md
- **Developed by:** [SMY](https://apify.com/scraper_gump) (community)
- **Categories:** Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

Extract property listings from Fotocasa — no browser, no captchas, clean JSON in seconds.

> 👋 **Hola equipo** — este scraper es para vosotros, usadlo con cariño.
>
> Questions or issues? Reach us at **info@inmocalc.com**

---

### What it does

Two modes in one actor:

| Mode | When to use it |
|---|---|
| **Search** | Get all listings in an area — an entire city, page after page |
| **Find location code** | Look up the area code you need before searching |

Fill in one, leave the other empty. Search is the default — just hit Start and you get Madrid Capital homes for sale out of the box.

---

### Why this one?

Fotocasa sits behind Imperva's anti-bot protection, which trips up most scrapers. We call the same private mobile API the Fotocasa Android app uses, so there's no browser overhead and no HTML parsing — just clean, structured data at a price that makes sense.

---

### Mode 1 — Search

Get all listings in an area matching your filters.

#### How to use it

**Step 1 — Fill in the fields**

| Field | What to enter |
|---|---|
| **Location code** | The code for the area you want to scrape — see below |
| **Transaction type** | `Sale`, `Rent`, `Transfer`, `Share`, `Rent with option to buy` or `Holiday rental` |
| **Property type** | `Homes` for flats and houses, or garages, land, offices, etc. |

Everything else has sensible defaults. Leave the filters blank to get everything.

**Step 2 — Hit Start**

The scraper runs page by page and saves results to the dataset as it goes. You can watch data come in before it finishes.

**Step 3 — Download your results**

When done, go to **Storage → Dataset** and export as CSV, JSON or Excel.

#### How to find a location code

Fotocasa areas are identified by a `combinedLocationIds` string — a comma-separated code like `724,14,28,173,0,28079,0,0,0`.

> ⚠️ Use the **full** string, not just the municipal number. A bare code like `28079` returns results for all of Spain, not just Madrid.

**Option A — use the built-in lookup (easiest)**
Fill in the **Find location code** field (Mode 2 below) with a place name, run the actor, and copy the code you need.

**Option B — use a known code**

| Area | Location code |
|---|---|
| Madrid Capital | `724,14,28,173,0,28079,0,0,0` |
| All of Spain | `724` |

#### Output fields

Each listing includes:

| Field | Description |
|---|---|
| `property_id` | Fotocasa listing ID |
| `url_marketplace` | Direct link to the listing on Fotocasa |
| `price` | Price in € |
| `price_description` | Price as shown on the site (e.g. `1.200 €/month`) |
| `surface` | Area in m² |
| `rooms` / `bathrooms` | Bedrooms and bathrooms |
| `property_type` | `HOME`, `GARAGE`, `LAND`, etc. |
| `transaction_type` | `SALE`, `RENT`, etc. |
| `location_description` | Area / neighbourhood text |
| `latitude` / `longitude` | Coordinates for mapping |
| `orientation` | Property orientation |
| `is_development` | Whether it's a new development |
| `payment_periodicity` | For rentals — monthly, etc. |
| `agency_name` | Listing agency, if any |
| `has_tour_virtual` | Virtual tour available |
| `has_video` | Video available |
| `diff_price` | Price change vs. a previous value |
| `list_date` | Publication date |
| `photo` | Main photo URL |
| `comments` | Full listing description |

#### Limits

- **No hard per-run cap** — the scraper paginates through every available page for the area. A full city like Madrid is ~570 pages (~11,000 listings) and takes roughly 20–30 minutes with polite random delays between requests.
- **Set `Max pages`** if you only want a sample — leave it at `0` to scrape everything.
- **All filters are optional** — price, surface, rooms and bathrooms can all be left blank.

---

### Mode 2 — Find location code

Not sure what location code to use? Run this mode first.

**How to use it:** fill in the **Find location code** field with a place name (e.g. `madrid`, `barcelona`, `valencia`). The Search section is ignored.

#### Output

| Field | Description |
|---|---|
| `text` | Human-readable area name (e.g. `Madrid Capital, Madrid`) |
| `combinedLocationIds` | The code to copy into the Search section |
| `subtitle` | Extra area detail |

---

### Advanced — if runs start failing

Fotocasa's Imperva protection requires a token (`x-d-token`) that ships with the actor. If runs suddenly return **403** ("Pardon Our Interruption"), the token needs refreshing:

- Capture a fresh `x-d-token` from the Fotocasa Android app with mitmproxy and paste it into the **Imperva token** field in the Advanced section.
- Runs go through a residential proxy by default. To use your own proxy, set the `PROXY_URL` environment variable.

---

### Tips

- **Each run creates a new dataset** — results are saved separately per execution, so you can compare runs.
- **Leave Items per page at 20** — it's the value the app uses; the API adds a couple of promoted items on top, which the scraper filters out automatically.
- **Mode priority:** if you fill in both sections, Find location code takes priority over Search.

# Actor input Schema

## `location_query` (type: `string`):

Type a city or area name (e.g. "madrid", "barcelona", "valencia"). The scraper returns the matching location codes — copy the one you need into the Search section below.

⚠️ When this field is filled in, the Search section is ignored.
## `locations` (type: `string`):

The full Fotocasa location string (combinedLocationIds), e.g. Madrid Capital → 724,14,28,173,0,28079,0,0,0

⚠️ Use the complete comma-separated string, not just the municipal code — a bare code like 28079 returns results for all of Spain.

💡 Don't have it? Use the "Find location code" field above.
## `transaction_type` (type: `string`):

Buy, rent, or another operation.
## `property_type` (type: `string`):

The kind of property to search.
## `max_pages` (type: `integer`):

How many pages to fetch. Leave at 0 to scrape every available page (a full city can be hundreds of pages).
## `page_size` (type: `integer`):

How many listings to request per page. Leave at 20 — the API returns a couple of promoted items on top of this.
## `min_price` (type: `integer`):

Only show properties at or above this price. Leave empty for no lower bound.
## `max_price` (type: `integer`):

Only show properties at or below this price. Leave empty for no upper bound.
## `min_surface` (type: `integer`):

Only show properties with at least this many square metres. Leave empty for no lower bound.
## `max_surface` (type: `integer`):

Only show properties up to this size. Leave empty for no upper bound.
## `min_rooms` (type: `integer`):

Only show properties with at least this many rooms. Leave empty to include all.
## `min_bathrooms` (type: `integer`):

Only show properties with at least this many bathrooms. Leave empty to include all.
## `x_d_token` (type: `string`):

The actor ships with a captured Imperva token. If runs start returning 403 (Imperva "Pardon Our Interruption"), capture a fresh x-d-token with mitmproxy on the Android app and paste it here.

This is the most likely thing to break — the token may not validate from a datacenter IP even through the residential proxy.
## `device_token` (type: `string`):

Firebase device token captured from the app. The shipped default works indefinitely for a fixed device; only set this if you need to rotate it.

## Actor input object example

```json
{
  "locations": "724,14,28,173,0,28079,0,0,0",
  "transaction_type": "SALE",
  "property_type": "HOME",
  "max_pages": 0,
  "page_size": 20
}
````

# Actor output Schema

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

Dataset items — property listings or location codes.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper_gump/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 = {}

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

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Fotocasa Scrape- LowCost | HiQuality",
        "description": "▎ Reliable Fotocasa data, at a fair price. ▎ We built the most efficient scraper for Fotocasa because we believe quality data shouldn't cost a fortune. No captchas, no browser overhead — just ▎ clean, structured data that works. ▎ Questions or ideas? → info@inmocalc.com",
        "version": "0.0",
        "x-build-id": "RELnjw6XNYpHy7UAU"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scraper_gump~fotocasa-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scraper_gump-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/scraper_gump~fotocasa-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scraper_gump-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/scraper_gump~fotocasa-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scraper_gump-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "location_query": {
                        "title": "Find location code",
                        "type": "string",
                        "description": "Type a city or area name (e.g. \"madrid\", \"barcelona\", \"valencia\"). The scraper returns the matching location codes — copy the one you need into the Search section below.\n\n⚠️ When this field is filled in, the Search section is ignored."
                    },
                    "locations": {
                        "title": "Location code",
                        "type": "string",
                        "description": "The full Fotocasa location string (combinedLocationIds), e.g. Madrid Capital → 724,14,28,173,0,28079,0,0,0\n\n⚠️ Use the complete comma-separated string, not just the municipal code — a bare code like 28079 returns results for all of Spain.\n\n💡 Don't have it? Use the \"Find location code\" field above.",
                        "default": "724,14,28,173,0,28079,0,0,0"
                    },
                    "transaction_type": {
                        "title": "Transaction type",
                        "enum": [
                            "SALE",
                            "RENT",
                            "TRANSFER",
                            "SHARE",
                            "RENT_WITH_OPTION_TO_BUY",
                            "HOLIDAY_RENTAL"
                        ],
                        "type": "string",
                        "description": "Buy, rent, or another operation.",
                        "default": "SALE"
                    },
                    "property_type": {
                        "title": "Property type",
                        "enum": [
                            "HOME",
                            "GARAGE",
                            "LAND",
                            "COMMERCIAL_PREMISES",
                            "OFFICE",
                            "BOX_ROOM",
                            "BUILDING"
                        ],
                        "type": "string",
                        "description": "The kind of property to search.",
                        "default": "HOME"
                    },
                    "max_pages": {
                        "title": "Max pages",
                        "minimum": 0,
                        "type": "integer",
                        "description": "How many pages to fetch. Leave at 0 to scrape every available page (a full city can be hundreds of pages).",
                        "default": 0
                    },
                    "page_size": {
                        "title": "Items per page",
                        "minimum": 1,
                        "maximum": 40,
                        "type": "integer",
                        "description": "How many listings to request per page. Leave at 20 — the API returns a couple of promoted items on top of this.",
                        "default": 20
                    },
                    "min_price": {
                        "title": "Min price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties at or above this price. Leave empty for no lower bound."
                    },
                    "max_price": {
                        "title": "Max price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties at or below this price. Leave empty for no upper bound."
                    },
                    "min_surface": {
                        "title": "Min surface (m²)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties with at least this many square metres. Leave empty for no lower bound."
                    },
                    "max_surface": {
                        "title": "Max surface (m²)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties up to this size. Leave empty for no upper bound."
                    },
                    "min_rooms": {
                        "title": "Min rooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties with at least this many rooms. Leave empty to include all."
                    },
                    "min_bathrooms": {
                        "title": "Min bathrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only show properties with at least this many bathrooms. Leave empty to include all."
                    },
                    "x_d_token": {
                        "title": "Imperva token (x-d-token) override",
                        "type": "string",
                        "description": "The actor ships with a captured Imperva token. If runs start returning 403 (Imperva \"Pardon Our Interruption\"), capture a fresh x-d-token with mitmproxy on the Android app and paste it here.\n\nThis is the most likely thing to break — the token may not validate from a datacenter IP even through the residential proxy."
                    },
                    "device_token": {
                        "title": "Device token (FCM) override",
                        "type": "string",
                        "description": "Firebase device token captured from the app. The shipped default works indefinitely for a fixed device; only set this if you need to rotate it."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
