# France Building Permits Scraper (`automation-lab/france-building-permits-scraper`) Actor

🏗️ Export official French SITADEL permits with addresses, applicants, cadastral parcels, project details, housing counts, and floor areas.

- **URL**: https://apify.com/automation-lab/france-building-permits-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## France Building Permits Scraper

Export official French building permits and planning authorizations from the SDES SITADEL public data service.

Turn national permit files into structured JSON, CSV, Excel, XML, or API-ready records without downloading and processing million-row source files yourself.

Use it to discover construction projects, refresh a property intelligence database, monitor local development, or build a repeatable lead pipeline.

### What does France Building Permits Scraper do?

The Actor reads the official anonymous SDES DiDo API and normalizes four SITADEL datasets:

- 🏠 Residential construction authorizations
- 🏢 Non-residential construction authorizations
- 🗺️ Development authorizations
- 🧱 Demolition authorizations

It streams pages rather than loading the full national corpus into memory.

You choose the datasets, filters, and maximum number of records.

Every output row retains the complete official record in `raw` for advanced analysis.

### Who is it for?

#### Contractors and construction suppliers

Find newly authorized projects by department and municipality.

Use addresses, project types, housing counts, and applicant names to prioritize outreach.

#### Developers and architects

Track local pipelines, authorization activity, planned floor area, and project destinations.

#### Proptech and data teams

Schedule monthly ingestion from a stable official source.

Keep a warehouse synchronized without maintaining a custom SITADEL downloader.

#### Researchers and public-sector analysts

Export bounded samples or targeted geographic slices for market, housing, and planning studies.

### Why use this Actor?

- ✅ Official France-wide SDES source
- ✅ No account, login, API key, or browser automation
- ✅ Four planning authorization datasets in one interface
- ✅ Stable English field names plus raw French source codes
- ✅ SIREN and SIRET included when publicly available
- ✅ Bounded pagination for predictable runs
- ✅ Ready for schedules, webhooks, APIs, and cloud storage integrations

### What France building permit data can I extract?

| Field | Description |
|---|---|
| `permitType` | Housing, non-residential, development, or demolition dataset |
| `permitReference` | Official authorization reference |
| `permitTypeCode` | Raw SITADEL authorization type code |
| `statusCode` | Raw official status code |
| `filingDate` | Filing date when available |
| `authorizationDate` | Real authorization date |
| `completionDate` | Completion/declaration date when available |
| `departmentCode` | INSEE department code |
| `municipalityCode` | INSEE municipality code |
| `address` | Normalized project-site address |
| `cadastralParcels` | Cadastral section and parcel identifiers |
| `applicantName` | Public applicant or organization name |
| `applicantSiren` | Public SIREN identifier |
| `applicantSiret` | Public SIRET establishment identifier |
| `projectNature` | Declared or completed project nature |
| `housingCreated` | Number of housing units created |
| `landAreaSqm` | Land area in square metres |
| `residentialFloorAreaCreatedSqm` | Residential floor area created |
| `nonResidentialFloorAreaCreatedSqm` | Non-residential floor area created |
| `raw` | Complete source record for fields not normalized yet |

### How to scrape French building permits

1. Open the Actor input page.
2. Select one or more permit datasets.
3. Optionally enter department or municipality codes.
4. Add date, status, or applicant filters if needed.
5. Set `maxItems` to control the export size.
6. Click **Start**.
7. Download the dataset or consume it through the Apify API.

Start with a small limit to validate your geography and filters.

Increase `maxPages` only when a selective filter requires a deeper source scan.

### Input

```json
{
  "permitTypes": ["housing", "nonResidential"],
  "departments": ["75"],
  "dateFrom": "2025-01-01",
  "maxItems": 500,
  "maxPages": 200
}
```

#### Input fields

| Input | Type | Default | Purpose |
|---|---|---:|---|
| `permitTypes` | array | `housing` | Official files to scan |
| `departments` | array | empty | INSEE department code filter |
| `municipalities` | array | empty | INSEE municipality code filter |
| `dateFrom` | date | empty | Earliest authorization date |
| `dateTo` | date | empty | Latest authorization date |
| `statuses` | array | empty | Raw SITADEL status codes |
| `applicantQuery` | string | empty | Applicant-name substring |
| `maxItems` | integer | 20 | Maximum saved permits |
| `maxPages` | integer | 20 | Maximum scanned pages per source |

### Output example

```json
{
  "permitType": "housing",
  "permitReference": "00115819B0023",
  "statusCode": "3",
  "authorizationDate": "2019-08-02",
  "departmentCode": "01",
  "municipalityCode": "01158",
  "municipalityName": "FARGES",
  "address": "ROUTE DE COLLONGES",
  "cadastralParcels": ["AD42"],
  "projectNature": "Construction d'une maison individuelle",
  "housingCreated": 1,
  "residentialFloorAreaCreatedSqm": 120,
  "sourceUrl": "https://data.statistiques.developpement-durable.gouv.fr/dido/api/v1/datafiles/.../rows?page=1&pageSize=100",
  "scrapedAt": "2026-07-13T00:00:00.000Z"
}
```

Actual availability varies by authorization type and source reporting.

Missing official values are represented as `null`, not invented.

### Geographic filtering

Departments use official codes such as `75`, `13`, `33`, or `2A`.

Municipalities use INSEE commune codes rather than postal codes.

Use both when you need a narrow local workflow.

The source files are ordered by the provider, so highly selective client-side filters may require multiple pages.

`maxPages` gives you an explicit safety boundary.

### Permit datasets explained

`housing` covers residential construction and contains the richest housing-unit breakdown.

`nonResidential` focuses on premises such as commercial, agricultural, industrial, and public buildings.

`development` covers planning and land-development authorizations.

`demolition` covers demolition authorizations and associated site details.

Schemas differ between official files.

The Actor maps a shared core and preserves all dataset-specific fields in `raw`.

### How much does it cost to scrape France building permits?

This Actor uses pay-per-event pricing:

- A small start charge covers run initialization.
- An item charge applies only to records saved in your dataset.
- Higher subscription tiers receive lower per-item prices.

The final cost appears before and after each run in Apify Console.

Use `maxItems` to set a hard output ceiling.

No proxy is required, keeping infrastructure overhead low.

### Scheduling a construction lead monitor

Open **Schedules** in Apify Console and create a monthly schedule.

Use a recent `dateFrom` value and the departments relevant to your territory.

Connect the resulting dataset to a webhook, Make, Zapier, Google Sheets, or your own ingestion endpoint.

Store `permitReference` in your system as the deduplication key.

Update the date range each cycle or deduplicate downstream.

### Integrations

#### Google Sheets and Excel

Export the dataset directly as CSV or XLSX for sales and research teams.

#### Webhooks

Send a run-finished webhook to your CRM or data pipeline.

#### Make and Zapier

Trigger workflows when a scheduled permit export completes.

#### Cloud storage

Use Apify integrations to copy results to supported databases and storage services.

#### Your data warehouse

Fetch JSON through the dataset API and upsert on `permitReference` plus `permitType`.

### API usage with Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/france-building-permits-scraper').call({
  permitTypes: ['housing'],
  departments: ['75'],
  maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/france-building-permits-scraper').call(run_input={
    'permitTypes': ['development'],
    'departments': ['13'],
    'maxItems': 100,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### API usage with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~france-building-permits-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"permitTypes":["housing"],"maxItems":100}'
```

Poll the returned run ID, then download items from its default dataset.

### Use with Apify MCP

Connect the Actor to Claude and AI coding tools through [Apify MCP](https://mcp.apify.com?tools=automation-lab/france-building-permits-scraper). The scoped endpoint exposes this Actor as an MCP tool and uses Apify's browser-based OAuth flow when your client connects.

#### Claude Code

Run this command in your terminal:

```bash
claude mcp add --transport http france-building-permits "https://mcp.apify.com?tools=automation-lab/france-building-permits-scraper"
```

Start Claude Code, open `/mcp`, select `france-building-permits`, and complete the Apify sign-in flow.

#### Claude Desktop, Cursor, and VS Code

Use the same Streamable HTTP server in your client's MCP configuration. In Cursor, save it as `.cursor/mcp.json`. In VS Code with GitHub Copilot, run **MCP: Open User Configuration** and add it to `mcp.json`. In Claude Desktop, add it as a custom connector; clients or Desktop versions that expose JSON configuration can use:

```json
{
  "mcpServers": {
    "france-building-permits": {
      "url": "https://mcp.apify.com?tools=automation-lab/france-building-permits-scraper"
    }
  }
}
```

On first use, authorize access in the browser. If your MCP client does not support OAuth, add a `headers` object containing `"Authorization": "Bearer <APIFY_TOKEN>"`; never commit a real token to source control.

Example prompts:

- “Export 100 recent housing permits for department 75.”
- “Find non-residential authorizations in Bouches-du-Rhône.”
- “Summarize the project types and floor area in this permit dataset.”
- “Create a CSV-ready list of applicant companies and project addresses.”

### Tips for reliable results

- Begin with `maxItems: 20` while testing.
- Use official INSEE codes, not free-text place names.
- Combine geography and dates for practical recurring exports.
- Raise `maxPages` when a narrow filter returns fewer items than expected.
- Retain `raw` if you may need source-specific fields later.
- Treat public applicant identifiers according to your applicable data-protection obligations.

### Data quality and refresh frequency

SITADEL is administrative statistical data supplied through SDES.

Fields can be corrected, delayed, incomplete, or unavailable for a particular record.

The national files are refreshed by the source, typically on a recurring release cycle.

The Actor reports what the official API returns at run time.

It does not infer missing applicant names, addresses, dates, or metrics.

### Legality: is it legal to scrape French building permit data?

The Actor accesses an anonymous official public-data API.

Public access does not remove your responsibility to use the data lawfully.

Consider GDPR, purpose limitation, direct-marketing rules, contractual obligations, and local regulations for your use case.

Avoid using personal data for harassment, discrimination, or unlawful profiling.

Consult qualified counsel when your workflow involves regulated decisions or outreach.

### FAQ

#### Does this Actor require a French government API key?

No. The supported SDES DiDo rows endpoints are publicly accessible without authentication.

#### Can I export all national records?

The source contains millions of records. Use bounded runs, geographic/date filters, schedules, and incremental ingestion rather than a single unrestricted export.

#### Why did a selective filter return few or zero items?

Filters are applied to scanned source pages. Confirm your codes and dates, then increase `maxPages` within a reasonable bound.

#### Why are some fields null?

The official dataset does not provide every field for every authorization type. The Actor preserves missing values as null.

#### Can I identify companies?

Applicant names, SIREN, and SIRET are included when the official public record provides them.

#### How do I avoid duplicate permits?

Use `permitType` and `permitReference` together as a stable downstream key.

#### Does the Actor use residential proxies?

No. It calls the official public JSON service directly.

#### Can I request another normalized source field?

The complete source object is already available in `raw`. Feature requests can promote frequently used raw fields into stable top-level properties.

### Related scrapers

Combine this Actor with other automation-lab data products:

- [France Property Risk Scraper](https://apify.com/automation-lab/france-property-risk-scraper) for environmental and property-risk context.
- [France SIRENE Company Scraper](https://apify.com/automation-lab/france-sirene-company-scraper) for applicant-company enrichment.
- [France Travail Jobs Scraper](https://apify.com/automation-lab/france-travail-jobs-scraper) for regional labor-market signals.

Only actors under the `automation-lab` account are linked here.

### Source attribution

Source: SDES, Base des permis de construire et autres autorisations d'urbanisme (SITADEL), distributed through DiDo.

Each item includes the exact page URL used for extraction.

Use attribution required by the source license and your downstream publication context.

### Support

For reproducible support, include:

- The Apify run URL
- The exact input
- The affected permit reference, if available
- Expected versus actual output

Do not include private credentials or unrelated personal data.

# Actor input Schema

## `permitTypes` (type: `array`):

Official authorization datasets to export.

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

Optional INSEE department codes, for example 75 or 13.

## `municipalities` (type: `array`):

Optional INSEE municipality codes.

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

Keep permits authorized on or after this ISO date.

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

Keep permits authorized on or before this ISO date.

## `statuses` (type: `array`):

Optional raw SITADEL status codes.

## `applicantQuery` (type: `string`):

Case-insensitive substring matched against the public applicant name.

## `maxItems` (type: `integer`):

Maximum dataset records to save.

## `maxPages` (type: `integer`):

Safety bound for selective client-side filters (100 records/page).

## Actor input object example

```json
{
  "permitTypes": [
    "housing"
  ],
  "departments": [],
  "municipalities": [],
  "maxItems": 20,
  "maxPages": 20
}
```

# Actor output Schema

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

No description

# 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 = {
    "permitTypes": [
        "housing"
    ],
    "departments": [],
    "municipalities": [],
    "maxItems": 20,
    "maxPages": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/france-building-permits-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 = {
    "permitTypes": ["housing"],
    "departments": [],
    "municipalities": [],
    "maxItems": 20,
    "maxPages": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/france-building-permits-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 '{
  "permitTypes": [
    "housing"
  ],
  "departments": [],
  "municipalities": [],
  "maxItems": 20,
  "maxPages": 20
}' |
apify call automation-lab/france-building-permits-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/UPSvoJVZzwtPrnPZJ/builds/DhUBaUZrf1Ifma2Fy/openapi.json
