# France Real Estate Sold Prices (DVF): €/m², Sales & Trends (`euroscrape/france-property-prices`) Actor

Every real property sale registered by the French State (DVF): price, €/m², surface, rooms, address and GPS for houses and apartments in any city, 2021-2025. Median prices, year-by-year trends, most active streets, and alerts on new sales.

- **URL**: https://apify.com/euroscrape/france-property-prices.md
- **Developed by:** [EuroScrape](https://apify.com/euroscrape) (community)
- **Categories:** Real estate, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 property sales

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/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

## France Real Estate Sold Prices (DVF): €/m², Sales & Trends

**Every real property sale registered by the French State, for any city — with the actual price paid, not an estimate.** DVF ("Demandes de valeurs foncières") is the official record of notarized sales. This Actor turns it into clean, filterable data: one row per sale, with €/m², surface, rooms, full address and GPS coordinates.

![Real sold prices and €/m² for any French city, from official records](https://raw.githubusercontent.com/EuroScrape/apify-actors/main/assets/demo-france-property-prices.gif)

- 🏠 **Real prices**: what buyers actually paid, from notary records — the ground truth behind every French property estimate site.
- 📍 **Any location**: city name, postal code or INSEE code. Paris, Lyon and Marseille automatically expand to all their arrondissements.
- 📈 **Free market statistics per location**: median €/m² for apartments and houses, year-by-year trend (2021-2025), share of new builds, most active streets.
- 🧮 **€/m² done right**: a DVF "sale" spreads over several rows (one per unit); the Actor regroups them and only computes €/m² on clean single-dwelling sales — the classic DVF mistake, avoided.

### ✨ Why this Actor

| | |
|---|---|
| 🗃️ **Official & complete** | Direct from the State's open-data files (Etalab), sale years 2021-2025, updated by the State about twice a year. |
| 🔍 **Real filters** | Property type, surface, price, rooms, new builds (VEFA) only / excluded. |
| 🗺️ **Mapping-ready** | Latitude/longitude on sales, plus a dedicated "Map data" dataset view. |
| 🔔 **New-sale alerts** | Schedule it with a monitor name: when the State publishes fresh sales for your area, you get them flagged `new` — with Telegram, Slack, Discord or webhook alerts. |
| 💶 **Cheap at scale** | $0.0005 per sale: a whole year of a mid-size city (about 2,500 house and apartment sales in Grenoble) costs about $1.25. Statistics are free and computed on **all** matching sales even when the dataset is capped. |

### 🎯 Use cases

- **Investors & buyers**: what was actually paid in the street you're targeting, and whether prices are rising or falling.
- **Real-estate pros**: automated comps (comparable sales) for valuations, with addresses and dates.
- **Proptech & data teams**: a clean sales feed per city, without parsing the State's multi-row CSV format yourself.
- **Journalists & analysts**: €/m² trends by city and street, from the source.

### 🚀 Examples

**Apartment sales in Grenoble, 2024-2025:**

```json
{
  "locations": ["Grenoble"],
  "years": [2024, 2025],
  "propertyTypes": ["apartment"]
}
```

**Family houses around Bordeaux, filtered:**

```json
{
  "locations": ["Bordeaux", "33110", "33200"],
  "years": [2023, 2024, 2025],
  "propertyTypes": ["house"],
  "minSurface": 90,
  "minRooms": 4,
  "maxPrice": 800000
}
```

**Alert when the State publishes new sales in your area:**

```json
{
  "locations": ["Grenoble"],
  "years": [2024, 2025],
  "monitorName": "grenoble-dvf",
  "telegramBotToken": "123456:ABC…",
  "telegramChatId": "123456789"
}
```

### 📦 Output

**A sale** (real data):

```json
{
  "type": "sale",
  "location": "Grenoble",
  "saleId": "2024-463400",
  "date": "2024-01-03",
  "price": 125800,
  "propertyType": "apartment",
  "isNewBuild": false,
  "surface": 76,
  "rooms": 3,
  "pricePerM2": 1655,
  "dwellings": 1,
  "outbuildings": 0,
  "address": "8 BD ROGER SALENGRO",
  "postalCode": "38100",
  "city": "Grenoble",
  "inseeCode": "38185",
  "department": "38",
  "latitude": 45.175551,
  "longitude": 5.712367
}
```

**The free location summary** (real data, apartments in Grenoble, ≥30 m², ≥2 rooms):

```json
{
  "type": "locationSummary",
  "location": "Grenoble",
  "salesMatching": 3716,
  "apartments": { "sales": 3716, "medianPrice": 153000, "medianPricePerM2": 2381, "medianSurface": 67 },
  "byYear": [
    { "year": 2024, "sales": 1848, "apartmentMedianPricePerM2": 2389 },
    { "year": 2025, "sales": 1868, "apartmentMedianPricePerM2": 2370 }
  ],
  "mostActiveStreets": [{ "street": "CRS LIBERATION - GEN DE GAULLE", "city": "Grenoble", "sales": 118 }]
}
```

### 💰 Pricing

| Event | Price |
|---|---|
| Run start | $0.003 |
| Property sale | $0.0005 |
| Location summaries (medians, trends) | free |

1,000 sales = $0.50. Apify subscribers pay less: −10% (Starter), −20% (Scale), −30% (Business). Set a **maximum cost per run** in the run options and the Actor stops cleanly when it's reached.

### ❓ FAQ

**How fresh is the data?** DVF is published by the French State with a delay: sales appear a few months after the notary act, in two yearly releases (around April and October). Year 2025 is partial until the final release. This is the same source and freshness as every French price-estimate website.

**Why is `pricePerM2` sometimes null?** A sale can bundle several dwellings or lack a declared surface; computing €/m² there would be wrong. The Actor only computes it for single-dwelling sales with known price and surface, and the summaries use only those — that's what makes the medians trustworthy.

**Are Alsace-Moselle and Mayotte covered?** No — the State does not publish DVF for Bas-Rhin, Haut-Rhin, Moselle (separate land registry) and Mayotte. Everything else, including DOM, is covered.

**What exactly is a "sale"?** One notarized mutation (Vente or VEFA). Exchanges, expropriations and adjudications are excluded by default. Outbuildings sold alone (parkings, cellars) appear only if you add `outbuilding` to `propertyTypes`.

**Can I map the results?** Yes: sales carry latitude/longitude, and the "Map data" view exports a mapping-ready table (CSV/JSON).

### ⭐ Your feedback

If this Actor saves you time, a short review on Apify Store helps other users find it. Missing a filter or a statistic? Say it in your review: the most requested features are added first.

### 🔗 More from EuroScrape

- [French Companies Scraper (SIRENE)](https://apify.com/euroscrape/france-companies): every French company by activity, area and size, with verified websites and emails.
- [EU Public Tenders Scraper: TED, BOAMP & Awards](https://apify.com/euroscrape/eu-public-tenders): open tenders and contract awards from all of Europe (TED) and France (BOAMP, DECP), with winners per lot, values in € and daily alerts.
- [EU VAT Number Validator (VIES): Bulk Check, Proof & Alerts](https://apify.com/euroscrape/vat-validator): validate VAT numbers in bulk against the EU's official registry, with consultation proof for tax audits and alerts when a customer's number becomes invalid.
- [Impressum & Legal Notice Scraper (EU)](https://apify.com/euroscrape/company-identity): legal identity, registry numbers and VAT IDs from any website, registry-verified.
- [UK Companies House Scraper](https://apify.com/euroscrape/uk-companies): UK companies by SIC code and location, with directors, websites and emails.
- [Website Tech Stack Detector: 280+ Technologies, Leads & Signals](https://apify.com/euroscrape/website-intelligence): technologies, company identity, contacts and sales signals for any website.
- [Google Hotels Scraper: Prices from Every Booking Site](https://apify.com/euroscrape/google-hotels-prices): hotel prices for any destination and dates, with the price on every booking site, rate parity, price calendars and alerts.
- [Google Flights Scraper: Cheapest Dates, Prices & Price History](https://apify.com/euroscrape/google-flights-prices): flight prices for any route and dates, cheapest day to fly, typical price range and price-drop alerts.
- [Vinted Scraper: 26 Countries, Deals, Alerts & Seller Data](https://apify.com/euroscrape/vinted-scraper): search Vinted across 26 countries, prices with buyer fees, seller ratings and instant alerts on new listings.
- [EU Second-Hand Marketplaces Scraper: Vinted, OLX & More](https://apify.com/euroscrape/eu-marketplace-deals): one search on the top second-hand marketplaces of 18 European countries, prices in €, cheapest country and resale margin.
- [Kleinanzeigen Scraper: Deal Finder & Price-Drop Alerts](https://apify.com/euroscrape/kleinanzeigen-scraper): German classifieds with view counts, full seller details and instant alerts.
- [App Store Reviews Scraper + Google Play Reviews](https://apify.com/euroscrape/app-reviews): reviews from both stores in 58 countries, rating by version and country, alerts on new negative reviews.

# Actor input Schema

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

French cities, postal codes or INSEE codes: "Grenoble", "Paris", "38000", "33063"… Paris, Lyon and Marseille automatically cover all their arrondissements.

## `years` (type: `array`):

Sale years to load, between 2021 and 2025 (the State publishes DVF data with a few months of delay, in April and October).

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

house, apartment, commercial, land, outbuilding.

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

Keep sales with at least this living surface.

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

Keep sales up to this living surface.

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

Keep sales at or above this price.

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

Keep sales up to this price.

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

Keep dwellings with at least this many main rooms.

## `newBuild` (type: `string`):

Off-plan sales (vente en l'état futur d'achèvement).

## `maxSalesPerLocation` (type: `integer`):

Most recent first. Summary statistics still use ALL matching sales.

## `includeSummary` (type: `boolean`):

Median €/m² and price for apartments and houses, year-by-year trend, share of new builds, most active streets.

## `monitorName` (type: `string`):

Set a name and schedule the Actor (e.g. monthly): each run then flags sales it has not seen before — the State adds fresh sales about twice a year.

## `telegramBotToken` (type: `string`):

Alerts on Telegram: create a bot with @BotFather and paste its token.

## `telegramChatId` (type: `string`):

Your chat ID (send a message to your bot, then open api.telegram.org/bot<token>/getUpdates).

## `discordWebhookUrl` (type: `string`):

Alerts in a Discord channel: Channel settings → Integrations → Webhooks.

## `slackWebhookUrl` (type: `string`):

Alerts in Slack: create an Incoming Webhook for your channel.

## `webhookUrl` (type: `string`):

Receives one POST per run with the new sales (Make, Zapier, n8n…).

## `maxNotifications` (type: `integer`):

Maximum number of alert messages per run.

## Actor input object example

```json
{
  "locations": [
    "Grenoble"
  ],
  "years": [
    2024,
    2025
  ],
  "propertyTypes": [
    "house",
    "apartment"
  ],
  "newBuild": "include",
  "maxSalesPerLocation": 500,
  "includeSummary": true,
  "maxNotifications": 30
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per registered sale.

## `map` (type: `string`):

Sales with coordinates, ready for mapping.

## `runSummary` (type: `string`):

Counters for this run (items found, output, errors).

# 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": [
        "Grenoble"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("euroscrape/france-property-prices").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": ["Grenoble"] }

# Run the Actor and wait for it to finish
run = client.actor("euroscrape/france-property-prices").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": [
    "Grenoble"
  ]
}' |
apify call euroscrape/france-property-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,euroscrape/france-property-prices"
        }
    }
}
```

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/XoLFuIJRGutrAZHPU/builds/uaoFNIFVwLxOQECXI/openapi.json
