# Real Estate Property Listings & Market Intelligence API (`kleioks/real-estate-market-scraper`) Actor

Enterprise real estate scraper and property market intelligence engine. Extracts normalized property listings, price-per-sqm metrics, surface area, room counts, energy ratings, and agency contacts for PropTech, investors, and B2B lead generation.

- **URL**: https://apify.com/kleioks/real-estate-market-scraper.md
- **Developed by:** [Akkouch Sofiane](https://apify.com/kleioks) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 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.

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

## Real Estate Property Listings & Market Intelligence API

[![Runtime](https://img.shields.io/badge/Runtime-Python_3.12_%7C_Async_HTTPX-1f2937?style=flat-square)](https://apify.com)
[![Schema Validation](https://img.shields.io/badge/Data_Contract-Pydantic_v2-0f766e?style=flat-square)](https://docs.pydantic.dev)
[![Compute Footprint](https://img.shields.io/badge/Memory_Footprint-128_MB_Min-2563eb?style=flat-square)](https://apify.com)
[![PropTech Ready](https://img.shields.io/badge/Integrations-Make_%7C_n8n_%7C_Clay_%7C_BI-4f46e5?style=flat-square)](https://apify.com)

High-throughput real estate listing and property market intelligence engine engineered for **PropTech platforms**, **real estate investment funds**, **asset managers**, and **B2B brokerage prospecting**.

Instead of relying on brittle headless browsers that consume excessive compute units and fail on layout shifts, this Actor queries structured JSON property endpoints, official municipal geocoding APIs (`api-adresse.data.gouv.fr`), and Schema.org `RealEstateListing` feeds directly over asynchronous `httpx` connections. Every record is normalized, enriched with automated **price-per-square-meter ($\text{price} / \text{m}^2$)** metrics and **DPE energy ratings**, and validated through **Pydantic v2** before storage.

***

### Core Capabilities & Architectural Advantages

| Feature | Technical Implementation | Value for PropTech & Investors |
| :--- | :--- | :--- |
| **Automated Price / $\text{m}^2$ Valuation** | Computes `pricePerSqm` across living (`surfaceArea`) and plot (`landArea`) surfaces automatically | Instant detection of undervalued properties and neighborhood pricing anomalies without post-processing |
| **Municipality & INSEE Resolution** | Resolves city names, arrondissements, and postal codes via the French National Address Base (BAN) | Eliminates ambiguous location matching across metropolitan areas (`Paris`, `Lyon`, `Bordeaux`, `Nice`, etc.) |
| **DPE Energy Rating Enrichment** | Concurrent asynchronous lookup of official Energy Performance (`A` to `G` class) | Critical for evaluating renovation CapEx and regulatory rental compliance (*passoires thermiques* F/G) |
| **Agency & Brokerage Attribution** | Extracts agency name, branch code, direct phone number (`agentPhone`), and canonical listing URL | Ready-to-use B2B lead lists for mortgage brokers, SaaS vendors, renovation contractors, and syndics |
| **Universal Direct URL Parser** | Parses Schema.org JSON-LD (`RealEstateListing`, `Apartment`, `SingleFamilyResidence`, `Offer`) | Allows on-demand ingestion of custom brokerage or developer pages alongside city-wide searches |
| **Low-Overhead HTTPX Engine** | Runs comfortably inside a `128 MB`–`256 MB` container without Chromium overhead | Up to **15x lower Apify Compute Unit consumption** compared to browser-based scrapers |

***

### High-ROI Use Cases

#### 1. Automated Deal Sourcing & Undervalued Asset Detection

Configure scheduled runs across target municipalities with strict `maxPrice`, `minSurfaceArea`, and `minRooms` thresholds. Pipe the output Dataset into **Make**, **n8n**, or **Airtable** to trigger instant Slack or email alerts whenever a listing drops below your target `pricePerSqm` benchmark or carries an `F`/`G` energy rating suitable for value-add renovation.

#### 2. B2B Lead Generation for Real Estate Service Providers

Extract active real estate agencies (`agentOrAgency`), direct branch phone numbers (`agentPhone`), and active inventory volumes by postal code. Ideal for PropTech SaaS sales teams, property photography studios, energy audit firms, and commercial insurance brokers building hyper-targeted outbound campaigns in **Clay** or **HubSpot**.

#### 3. Quantitative Market Research & Valuation Indexes

Aggregate thousands of standardized property records (`price`, `pricePerSqm`, `surfaceArea`, `rooms`, `bedrooms`, `latitude`, `longitude`) into **BigQuery**, **Snowflake**, or **Power BI** to monitor real-time supply levels, price dispersion, and asset-class breakdowns (`apartment`, `house`, `commercial`, `land`).

***

### Input Configuration Reference

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `locations` | `array<string>` | `["Paris", "Lyon", "Bordeaux"]` | Target cities, municipalities, or postal codes to query (e.g., `"Paris"`, `"69006"`, `"Bordeaux"`, `"Marseille"`, `"Nice"`). |
| `propertyTypes` | `array<string>` | `["apartment", "house", "commercial"]` | Filter by normalized asset class: `"apartment"`, `"house"`, `"commercial"`, or `"land"`. |
| `transactionType` | `string` | `"sale"` | Filter by deal type: `"sale"` (acquisition), `"rent"` (leasing), or `"all"`. |
| `minPrice` | `integer` | `50000` | Minimum listing price threshold in local currency (`0` disables the minimum filter). |
| `maxPrice` | `integer` | `0` | Maximum listing price threshold in local currency (`0` disables the maximum limit). |
| `minSurfaceArea` | `integer` | `15` | Minimum floor area in square meters ($\text{m}^2$). |
| `minRooms` | `integer` | `1` | Minimum number of main rooms (*pièces principales*). |
| `targetUrls` | `array<string>` | `[]` | Optional list of direct property or brokerage URLs to parse via Schema.org JSON-LD. |
| `maxResults` | `integer` | `25` | Maximum number of validated listings to extract per target location (`1`–`500`). |

#### Example Input JSON

```json
{
  "locations": [
    "Paris",
    "Lyon",
    "Bordeaux"
  ],
  "propertyTypes": [
    "apartment",
    "house"
  ],
  "transactionType": "sale",
  "minPrice": 150000,
  "maxPrice": 950000,
  "minSurfaceArea": 30,
  "minRooms": 2,
  "targetUrls": [],
  "maxResults": 25
}
```

***

### Output Dataset Schema Reference

Every item pushed to the default Apify Dataset conforms strictly to `.actor/dataset_schema.json`:

| Field | Type | Description |
| :--- | :--- | :--- |
| `propertyId` | `string` | Deterministic unique identifier for deduplication across runs. |
| `propertyTitle` | `string` | Normalized headline of the property listing. |
| `price` | `number` | Total listed price in local currency. |
| `pricePerSqm` | `number \| null` | Automatically calculated price per square meter ($\text{price} / \text{surfaceArea}$). |
| `currency` | `string` | ISO 4217 currency code (`EUR`). |
| `location` | `string` | Complete formatted address string (street, postal code, city). |
| `city` | `string \| null` | Normalized municipality name. |
| `postalCode` | `string \| null` | Postal or ZIP code. |
| `country` | `string` | ISO country code (`FR`). |
| `surfaceArea` | `number \| null` | Living or commercial floor area in square meters ($\text{m}^2$). |
| `landArea` | `number \| null` | Plot or land area in square meters ($\text{m}^2$), when applicable. |
| `rooms` | `integer \| null` | Total number of main rooms. |
| `bedrooms` | `integer \| null` | Number of bedrooms. |
| `propertyType` | `string` | Normalized asset category (`apartment`, `house`, `commercial`, `land`). |
| `transactionType` | `string` | Normalized transaction type (`sale` or `rent`). |
| `energyRating` | `string \| null` | Official DPE energy performance class (`A` through `G`). |
| `agentOrAgency` | `string` | Name of the listing real estate agency or brokerage branch. |
| `agentPhone` | `string \| null` | Direct telephone number of the listing agency branch. |
| `agentEmail` | `string \| null` | Public contact email of the agency, when available. |
| `latitude` | `number \| null` | WGS84 geographic latitude coordinate. |
| `longitude` | `number \| null` | WGS84 geographic longitude coordinate. |
| `listingUrl` | `string` | Canonical URL to the full property listing. |
| `sourcePlatform` | `string` | Identifier of the upstream data source (`laforet-immo-api` or `direct-jsonld`). |
| `listedAt` | `string \| null` | ISO 8601 publication timestamp of the listing. |
| `scrapedAt` | `string` | ISO 8601 UTC timestamp of extraction. |

#### Sample Output Record

```json
{
  "propertyId": "lf-53007812",
  "propertyTitle": "Appartement Paris 3 pièce(s) 64.50 m2",
  "price": 585000.0,
  "pricePerSqm": 9069.77,
  "currency": "EUR",
  "location": "75015, PARIS",
  "city": "Paris",
  "postalCode": "75015",
  "country": "FR",
  "surfaceArea": 64.5,
  "landArea": null,
  "rooms": 3,
  "bedrooms": 2,
  "propertyType": "apartment",
  "transactionType": "sale",
  "energyRating": "D",
  "agentOrAgency": "Laforêt PARIS 15 CONVENTION",
  "agentPhone": "0145321010",
  "agentEmail": null,
  "latitude": 48.839612,
  "longitude": 2.296145,
  "listingUrl": "https://www.laforet.com/agence-immobiliere/paris15convention/acheter/paris-15/appartement-3-pieces-53007812",
  "sourcePlatform": "laforet-immo-api",
  "listedAt": "2026-10-30T14:20:00+00:00",
  "scrapedAt": "2026-10-31T22:55:00.114209+00:00"
}
```

***

### Programmatic Usage (Python SDK)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_API_TOKEN")

run_input = {
    "locations": ["Paris", "Lyon", "Bordeaux"],
    "propertyTypes": ["apartment", "house"],
    "transactionType": "sale",
    "minPrice": 150000,
    "minSurfaceArea": 30,
    "maxResults": 50,
}

run = client.actor("kleioks/real-estate-market-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(
        f"[{item['city']} {item['postalCode']}] {item['propertyTitle']} — "
        f"{item['price']:,.0f} {item['currency']} ({item['pricePerSqm']} €/m²) | "
        f"DPE: {item['energyRating']} | Agency: {item['agentOrAgency']} ({item['agentPhone']})"
    )
```

***

### No-Code, Make, n8n, Clay & AI Agent (MCP) Integrations

#### 1. Make.com & n8n Automated Deal-Sourcing Alerts

1. Schedule the **Apify Node** in **n8n** or **Make.com** to run every morning across your target cities (`Paris`, `Lyon`, `Bordeaux`, `Nice`, `Nantes`).
2. Add a router condition filtering properties where `pricePerSqm` is 15% below your neighborhood threshold or where `energyRating` is `"F"` or `"G"` (*passoires thermiques* with high negotiation margin).
3. Send instant deal cards with `listingUrl`, `price`, `surfaceArea`, and `agentPhone` to **Slack**, **Telegram**, **Airtable**, or **Notion**.

#### 2. Clay.com Real Estate Agency B2B Prospecting

Import the dataset directly into **Clay** using `agentOrAgency`, `agentPhone`, `city`, and `postalCode` to build segmented outbound lists of active real estate brokerages for PropTech SaaS, mortgage brokerage partnerships, or renovation services.

#### 3. Model Context Protocol (MCP) for Claude, Cursor & AI Agents

Connect this Actor to **Claude Desktop**, **Cursor**, or custom PropTech AI assistants via the official Apify MCP server:

```json
{
  "mcpServers": {
    "apify-real-estate": {
      "command": "npx",
      "args": [
        "-y",
        "@apify/actors-mcp-server",
        "--actors",
        "kleioks/real-estate-market-scraper"
      ],
      "env": {
        "APIFY_TOKEN": "YOUR_APIFY_API_TOKEN"
      }
    }
  }
}
```

***

### Frequently Asked Questions (FAQ)

#### How does this Real Estate scraper calculate Price per Square Meter ($\text{price}/\text{m}^2$)?

Every extracted property record is validated through **Pydantic v2**, which automatically divides the listed `price` by the verified `surfaceArea` (Carrez or living floor area) and rounds `pricePerSqm` to two decimal places—delivering ready-to-analyze valuation metrics with zero spreadsheet formulas.

#### Can I filter properties by Energy Performance Rating (DPE A to G)?

Yes. The Actor asynchronously enriches listings with their official **DPE class (`A` through `G`)** (`energyRating`), allowing institutional investors and *marchands de biens* to identify thermal-renovation opportunities (`F` and `G` ratings) immediately.

#### Can I scrape custom real estate agency URLs in addition to city searches?

Yes. Any URL passed in `targetUrls` is parsed using a universal **Schema.org JSON-LD** (`RealEstateListing`, `Apartment`, `SingleFamilyResidence`, `Offer`) and contact extractor.

***

### Complete B2B Intelligence Suite by Kleioks

Combine this Actor with our specialized B2B data engines on the Apify Store to build end-to-end GTM, RevOps, and market research pipelines:

| Actor | Primary B2B Use Case | Store Link |
| :--- | :--- | :--- |
| **Real Estate Market Intelligence API** | Normalized property listings, automated price/m² valuation, DPE ratings & agency contacts | [Open on Apify Store](https://apify.com/kleioks/real-estate-market-scraper) |
| **Google Maps B2B Lead Machine** | High-speed local business lead extractor (phone, website, rating & missing-website signals) | [Open on Apify Store](https://apify.com/kleioks/google-maps-b2b-lead-machine) |
| **Multi-ATS Career Jobs API** | Track real-time hiring intent & tech-stack signals across Greenhouse, Lever, Ashby & Workable | [Open on Apify Store](https://apify.com/kleioks/multi-ats-jobs-scraper) |
| **Reddit B2B Buying Intent Scraper** | Monitor competitor churn, software recommendations & high-intent buyer threads on Reddit | [Open on Apify Store](https://apify.com/kleioks/reddit-b2b-scraper) |
| **B2B Social Leads & Intent Extractor** | Discover SaaS founders, developers & decision-makers across Bluesky, GitHub & Hacker News | [Open on Apify Store](https://apify.com/kleioks/b2b-social-leads-scraper) |
| **Influencer & Creator Discovery API** | Extract TikTok, Instagram & YouTube creator profiles, engagement rates & verified PR emails | [Open on Apify Store](https://apify.com/kleioks/influencer-creator-discovery) |

# Actor input Schema

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

List of cities, municipalities, or postal codes to query (e.g., 'Paris', '75015', 'Lyon', 'Bordeaux', 'Marseille', 'Nice', 'Nantes', 'Toulouse').

## `propertyTypes` (type: `array`):

Filter results by normalized real estate asset class: 'apartment', 'house', 'commercial', or 'land'.

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

Select whether to extract property sales ('sale'), rentals ('rent'), or both ('all').

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

Exclude properties listed or transacted below this price threshold (0 = no minimum).

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

Exclude properties listed or transacted above this price threshold (0 = no maximum limit).

## `minSurfaceArea` (type: `integer`):

Minimum living or commercial floor area in square meters (m²).

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

Minimum number of main rooms (pièces principales).

## `targetUrls` (type: `array`):

Optional list of direct property listing URLs or real estate agency pages. Automatically parses Schema.org JSON-LD (RealEstateListing, Offer, Apartment, SingleFamilyResidence), OpenGraph tags, and contact details.

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

Maximum number of normalized property records to extract per target location.

## Actor input object example

```json
{
  "locations": [
    "Paris",
    "Lyon",
    "Bordeaux"
  ],
  "propertyTypes": [
    "apartment",
    "house",
    "commercial"
  ],
  "transactionType": "sale",
  "minPrice": 50000,
  "maxPrice": 0,
  "minSurfaceArea": 15,
  "minRooms": 1,
  "targetUrls": [],
  "maxResults": 25
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing validated real estate property records, pricing metrics, and agency intelligence.

# 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": [
        "Paris",
        "Lyon",
        "Bordeaux"
    ],
    "propertyTypes": [
        "apartment",
        "house",
        "commercial"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kleioks/real-estate-market-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": [
        "Paris",
        "Lyon",
        "Bordeaux",
    ],
    "propertyTypes": [
        "apartment",
        "house",
        "commercial",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("kleioks/real-estate-market-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": [
    "Paris",
    "Lyon",
    "Bordeaux"
  ],
  "propertyTypes": [
    "apartment",
    "house",
    "commercial"
  ]
}' |
apify call kleioks/real-estate-market-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kleioks/real-estate-market-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/SW1CLCYcObhbnKruD/builds/fjcg7GEfzMPeaVqvD/openapi.json
