# French Property Sale Prices (DVF) – Sales, €/m² & Valuations (`yck69/french-property-prices`) Actor

Official French property sale prices (DVF, up to mid-2026): one clean row per sale with price per m², area statistics and trends, and automated valuations from comparable sales for any address.

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

## Pricing

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

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

## French Property Sale Prices (DVF) – Sales, €/m² & Valuations

Official **French property sale prices** from **DVF** (*Demandes de valeurs foncières*, the tax administration's record of every notarised sale), **up to mid-2026**, in three ways:

- **Sales**: one clean row per sale, with price, **price per m²**, living area, *loi Carrez* area, rooms, land, address and GPS, around an address or in any commune, postal code or department.
- **Price statistics**: median price and €/m² (with quartiles) by year, quarter, month, commune, postal code, property type or number of rooms, with **period-to-period change**.
- **Valuation**: an **estimated price range** for one or hundreds of properties, from comparable sales nearby, with the comparables listed.

From **$1 per 1,000 sales** · **$0.03 per valuation**. Free count preview.

### What data can you get?

<table>
<tr><td>📅 Sale date</td><td>💶 Price</td><td>📐 Price per m²</td></tr>
<tr><td>🏠 Property type</td><td>📏 Living area and Carrez area</td><td>🚪 Rooms</td></tr>
<tr><td>🌳 Land area</td><td>📍 Address and GPS</td><td>🏙️ Commune, postal code, department</td></tr>
<tr><td>🆕 New build or not</td><td>📊 Median prices and trends</td><td>🧮 Valuation range with comparables</td></tr>
</table>

### How to use it

1. Click **Try for free** at the top of this page.
2. Choose **sales**, **stats** or **valuation**.
3. Enter an address and radius, or communes, postal codes or departments.
4. Click **Start**.
5. Download as JSON, CSV or Excel.

### Why this Actor

- **Clean sales, not raw rows.** DVF has one row per property item, parcel and land use, and repeats the sale price on each row: an apartment sold with a cellar and a parking space is three rows with the same price. This Actor rebuilds **one row per sale** and only computes **€/m² on single-dwelling sales**, so prices per m² are right.
- **Up to date.** Built on the current official delivery (sales up to June 2026), refreshed after each half-yearly release. It doesn't depend on the per-commune archive files, which data.gouv.fr is deleting at the end of November 2026.
- **Fast.** Answers in seconds: data is pre-processed by department.
- **Valuations with a range and a confidence level**, weighting comparables by distance, recency, size, rooms and land.

### Use cases

- **Estate agents & buyers**: comparable sales around an address before setting or negotiating a price.
- **Investors**: price per m² and trends by neighbourhood, screening cities by price level.
- **Banks, insurers, proptech**: bulk valuations of a portfolio.
- **Journalists & analysts**: price trends by commune or department since 2021.

### Input examples

**Apartments sold within 500 m of an address**

```json
{ "mode": "sales", "address": "Place Bellecour, Lyon", "radiusKm": 0.5, "propertyTypes": ["apartment"], "dateFrom": "2 years" }
```

**Yearly trend of house prices in Bordeaux**

```json
{ "mode": "stats", "communes": ["Bordeaux"], "propertyTypes": ["house"], "groupBy": "year" }
```

**Price per m² by arrondissement in Paris**

```json
{ "mode": "stats", "communes": ["Paris"], "propertyTypes": ["apartment"], "dateFrom": "12 months", "groupBy": "commune" }
```

**Value an apartment**

```json
{ "mode": "valuation", "address": "8 cours Bayard, Lyon", "valuationType": "apartment", "livingArea": 65, "rooms": 3 }
```

**Bulk valuation**

```json
{
    "mode": "valuation",
    "properties": [
        { "address": "12 rue de la République, Lyon", "propertyType": "apartment", "livingArea": 80 },
        { "address": "5 chemin des Vignes, Mérignac", "propertyType": "house", "livingArea": 120, "rooms": 5, "landArea": 600 }
    ]
}
```

### Output

**Sale**

```json
{
    "saleDate": "2025-12-31",
    "saleType": "Vente",
    "price": 194135,
    "propertyType": "apartment",
    "livingArea": 31,
    "carrezArea": 29.6,
    "rooms": 2,
    "pricePerM2": 6262,
    "outbuildings": 0,
    "address": "8 CRS BAYARD",
    "postalCode": "69002",
    "commune": "Lyon 2e Arrondissement",
    "latitude": 45.74343,
    "longitude": 4.821866,
    "distanceM": 412,
    "parcelIds": ["69382000BD0087"]
}
```

**Valuation**: `estimatedPrice`, `estimatedPriceLow` / `estimatedPriceHigh` (weighted quartiles), `pricePerM2`, `confidence` (high / medium / low), `comparablesUsed`, `searchRadiusM`, `period`, and the most relevant `comparables` (date, price, area, rooms, €/m², distance, address).

**Statistics row**: `label`, `sales`, `medianPrice`, `medianPricePerM2`, `pricePerM2Q1`, `pricePerM2Q3`, `averageLivingArea`, `totalVolume`, `changePct` (for time series).

### Pricing

| Event | Price |
|---|---|
| Sale | $0.001 |
| Statistics row | $0.002 |
| Valuation (with comparables) | $0.03 |

Free: count previews, and valuations that can't be computed (not enough comparable sales or address not found).

### Good to know

- **Coverage**: all of France except **Alsace-Moselle** (Bas-Rhin, Haut-Rhin, Moselle, which use a separate land register) and **Mayotte**. Sales from July 2021 to June 2026 (five rolling years, updated every six months, with about six months' delay).
- **Living area** is the built area declared to the tax office; *loi Carrez* area is given for apartments when declared.
- **Valuations** are statistical estimates from past sales, not appraisals. They reflect prices at the sale dates and can't see condition, floor, view or renovation.
- **Reuse conditions** (décret n° 2018-1350): DVF must not be used to re-identify owners or buyers, and individual sales must not be republished in a way that lets search engines index them.
- Source: [Demandes de valeurs foncières géolocalisées](https://www.data.gouv.fr/fr/datasets/demandes-de-valeurs-foncieres-geolocalisees/) (DGFiP / Etalab).

### More Actors from this developer

### FAQ

##### Can I use it through the API, Make, Zapier or Google Sheets?

Yes. Every run can be started and read through the [Apify API](https://docs.apify.com/api/v2) (JavaScript and Python clients, CLI, MCP), and Apify integrations connect it to Make, Zapier, n8n, Google Sheets, Slack, webhooks and more.

##### Is it legal to use this data?

The Actor only reads public or official open data and doesn't log in anywhere. Check the source's licence and your local rules (for example GDPR when data concerns people) for your use case; if in doubt, ask a lawyer.

##### Something isn't working, or you need another field?

Open an issue on the **Issues** tab: feedback is read and answered.

# Actor input Schema

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

<b>Sales</b>: one row per sale with price, €/m², areas, rooms, address and GPS.<br><b>Price statistics</b>: median price and €/m² by commune, postal code, year, quarter, month, type or rooms, with trends.<br><b>Valuation</b>: an estimated price range for one or many properties, from comparable sales nearby.

## `address` (type: `string`):

Any French address, e.g. <code>12 rue de la République, Lyon</code>. Sales within the radius are returned. Also the property to value in Valuation mode.

## `radiusKm` (type: `number`):

Up to 20 km around the address.

## `latitude` (type: `number`):

Instead of an address.

## `longitude` (type: `number`):

Instead of an address.

## `communes` (type: `array`):

Names or INSEE codes, e.g. <code>Bordeaux</code>, <code>Paris</code> (all arrondissements), <code>69381</code>.

## `postalCodes` (type: `array`):

e.g. <code>75011</code>.

## `departments` (type: `array`):

e.g. <code>33</code>, <code>2A</code>. DVF doesn't cover Alsace-Moselle (57, 67, 68) or Mayotte.

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

Default: apartments and houses.

## `saleTypes` (type: `array`):

Default: regular sales and new builds (VEFA).

## `dateFrom` (type: `string`):

A date (<code>2025-01-01</code>) or a duration (<code>2 years</code>).

## `dateTo` (type: `string`):

A date or a duration.

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

Sale price.

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

Sale price.

## `minLivingArea` (type: `number`):

Built living area of the dwellings sold.

## `maxLivingArea` (type: `number`):

Built living area of the dwellings sold.

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

Main rooms (pièces principales).

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

Main rooms.

## `minLandArea` (type: `number`):

Land area sold.

## `maxLandArea` (type: `number`):

Land area sold.

## `minPricePerM2` (type: `integer`):

Only single-dwelling sales have a price per m².

## `maxPricePerM2` (type: `integer`):

Only single-dwelling sales have a price per m².

## `excludeOutliers` (type: `boolean`):

Removes sales under €1,000 (symbolic or family transfers) and prices per m² outside €300–30,000.

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

Default: distance for address searches, newest first otherwise.

## `groupBy` (type: `string`):

Time groupings include the change in median €/m² from one period to the next.

## `valuationType` (type: `string`):

Apartment or house.

## `livingArea` (type: `number`):

Required for a valuation.

## `rooms` (type: `integer`):

Optional: comparable sales with the same number of rooms count more.

## `landArea` (type: `number`):

Optional, for houses: sales with similar land count more.

## `properties` (type: `array`):

A list like <code>\[{"address": "…", "propertyType": "house", "livingArea": 120, "rooms": 5, "landArea": 600}]</code>. One valuation per item.

## `monthsBack` (type: `integer`):

Comparable sales period, counted back from the most recent data.

## `includeNewBuilds` (type: `boolean`):

New builds sell at a premium; turn on when valuing a new property.

## `maxComparables` (type: `integer`):

The most relevant comparable sales are listed with each valuation.

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

Sales, statistics rows or valuations.

## `countOnly` (type: `boolean`):

Count matching sales and give their median €/m². Nothing is charged.

## `refreshCache` (type: `boolean`):

Maintenance: rebuilds the pre-processed DVF files. Only works for the Actor's maintainer.

## Actor input object example

```json
{
  "mode": "sales",
  "address": "Place Bellecour, Lyon",
  "radiusKm": 0.5,
  "propertyTypes": [
    "apartment",
    "house"
  ],
  "saleTypes": [
    "sale",
    "new_build"
  ],
  "excludeOutliers": true,
  "groupBy": "year",
  "valuationType": "apartment",
  "monthsBack": 24,
  "includeNewBuilds": false,
  "maxComparables": 10,
  "maxResults": 20,
  "countOnly": false,
  "refreshCache": false
}
```

# Actor output Schema

## `sales` (type: `string`):

One row per sale.

## `stats` (type: `string`):

Median prices and trends.

## `valuations` (type: `string`):

Estimates with comparable sales.

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

Every field.

# 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": "sales",
    "address": "Place Bellecour, Lyon",
    "radiusKm": 0.5,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("yck69/french-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 = {
    "mode": "sales",
    "address": "Place Bellecour, Lyon",
    "radiusKm": 0.5,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("yck69/french-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 '{
  "mode": "sales",
  "address": "Place Bellecour, Lyon",
  "radiusKm": 0.5,
  "maxResults": 20
}' |
apify call yck69/french-property-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yck69/french-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/CxerIhw5zmjX3N74g/builds/4jRINF7bdk9hlLOaJ/openapi.json
