# France Building Permits Scraper (Sitadel) — Construction Leads (`capable_coach/france-building-permits`) Actor

French building permits scraper (permis de construire) on official Sitadel open data: housing and non-residential permits, prior declarations, development and demolition permits. Filter by département, commune, date, size. Company petitioners with SIREN. Construction B2B leads, no personal data.

- **URL**: https://apify.com/capable_coach/france-building-permits.md
- **Developed by:** [jules imbert](https://apify.com/capable_coach) (community)
- **Categories:** Real estate, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 building permits

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 Building Permits Scraper (Sitadel) — Construction Leads API

**Get every new French building permit as clean JSON: who is building what, where, and how big — straight from the official Sitadel open data of the French Ministry for Ecological Transition (SDES). Company petitioners come with SIREN, SIRET and official company data. No scraping, no personal data, no API key.**

Ideal for **construction B2B lead generation** (builders, roofers, window, HVAC, solar and elevator installers, concrete and materials suppliers, scaffolding, insurance, equipment rental), **property developer monitoring**, **market intelligence** and **AI agents** (works with the Apify MCP server).

🇫🇷 *Permis de construire, déclarations préalables, permis d'aménager et permis de démolir — base Sitadel en open data, enrichie avec l'API Recherche d'entreprises. Version française plus bas.*

### What you get

| Field group | Fields |
|---|---|
| **Permit** | `permitId`, `permitNumber`, `permitCategory` (housing / non_residential / development / demolition), `permitType` (PC, DP, PA, PD), `status` (authorized, started, completed, cancelled), `authorizationDate`, `worksStartDate`, `worksCompletionDate`, `filingMonth` |
| **Project** | `projectNature` (new_construction, transformation, extension…), `mainUse` (housing, offices, retail, industry, warehouse, hotel, agriculture, public_service), `housingKind`, `intendedUse` (sale, rental, own occupation), `housingUnitsCreated`, `socialRentalUnits`, `floorAreaCreatedM2`, `residentialFloorAreaCreatedM2`, `nonResidentialFloorAreaCreatedM2`, `landAreaM2`, `maxLevels`, `architectInvolved` |
| **Location of works** | `communeCode` (INSEE), `city`, `postcode`, `departmentCode`, `department`, `regionCode`, `region`, `siteAddress`, `cadastralParcels` |
| **Petitioner (legal entities only)** | `petitionerName`, `petitionerSiren`, `petitionerSiret`, `petitionerNafCode`, `petitionerLegalFormCode`, `petitionerPostcode`, `petitionerCity` |
| **Company enrichment** (optional) | `petitionerCompany`: head office address & GPS, headcount range, SME/large company category, creation date, active/ceased, number of open establishments, RGE / ESS / Qualiopi labels, link to annuaire-entreprises.data.gouv.fr |
| **Provenance** | `source`, `sourceDatasetUrl`, `sourceVintage` (monthly release), `sourceLicense`, `attribution`, `scrapedAt` |

### Use cases

- **Sales prospecting for construction trades**: every developer, SCI, social landlord or company that just got a permit for 10+ dwellings or 1,000+ m² in your area.
- **Weekly lead alerts**: schedule the Actor monthly (Sitadel is updated monthly) with your départements and size thresholds, and send the dataset to Google Sheets, HubSpot, Slack or Make/Zapier with Apify integrations.
- **Developer and competitor tracking**: filter by NAF code `41.10` (property developers) or by name keyword (e.g. `NEXITY`).
- **Market research**: new housing supply by commune, social housing share, building types.
- **AI agents**: a typed, flat schema an LLM can call through the Apify MCP server ("which developers got permits for 50+ flats in Lyon this quarter?").

### Input example

```json
{
  "permitCategories": ["housing", "non_residential"],
  "departments": ["69"],
  "authorizedWithinDays": 180,
  "petitionerType": "legal_entities",
  "minHousingUnits": 10,
  "enrichCompanies": true,
  "maxResults": 500
}
```

| Input | Meaning |
|---|---|
| `permitCategories` | `housing`, `non_residential`, `development` (permis d'aménager), `demolition` (permis de démolir) |
| `departments` / `communeCodes` | Département codes (`75`, `2A`, `971`) or INSEE commune codes (`69123` = Lyon). Empty = all of France |
| `authorizedWithinDays`, `authorizedFrom`, `authorizedTo` | Authorization date window |
| `petitionerType` | `legal_entities` (default, B2B leads) or `all` (projects of private individuals are included **at commune level only**) |
| `status` | `any`, `authorized`, `started`, `completed`, `cancelled` |
| `minHousingUnits`, `minFloorAreaM2` | Size thresholds |
| `petitionerNafPrefixes` | Activity codes of the petitioner, e.g. `41.10`, `68.20`, `84.11` |
| `keyword` | Text in petitioner name or city |
| `enrichCompanies` | Add official company data (default `true`) |

### Output example

```json
{
  "permitId": "DP-07510626V0330",
  "permitCategory": "housing",
  "permitType": "DP",
  "status": "authorized",
  "authorizationDate": "2026-09-02",
  "projectNature": "transformation",
  "housingKind": "apartment_building",
  "housingUnitsCreated": 5,
  "city": "PARIS 06",
  "postcode": "75006",
  "siteAddress": "60 RUE MADAME",
  "petitionerType": "legal_entity",
  "petitionerName": "FONCIERE JEAN BART",
  "petitionerSiren": "924930001",
  "petitionerNafCode": "68.31Z",
  "petitionerCompany": { "companyCategory": "PME", "creationDate": "2024-03-25", "headOfficeAddress": "250 B RUE DU FAUBOURG SAINT-HONORE 75008 PARIS", "status": "active" },
  "sourceLicense": "Licence Ouverte / Open Licence v2.0 (Etalab)",
  "attribution": "Source : SDES, base Sitadel des autorisations d'urbanisme (millésime 2026-09) — Licence Ouverte v2.0"
}
```

### Pricing

Pay per event, with discounts on paid Apify plans and no platform-usage fee on top:

| Apify plan | Per permit | Per 1,000 |
|---|---|---|
| Free | $0.0025 | $2.50 |
| Starter (Bronze) | $0.00225 | $2.25 |
| Scale (Silver) | $0.001875 | $1.88 |
| Business (Gold) and above | $0.0015 | $1.50 |

Plus **$0.0003 per run start** (check the Pricing tab for the current price). You only pay for permits that match your filters; `maxResults` caps the cost. No browser, no proxy, so runs are fast and cheap: 100 enriched permits take about 15–30 seconds.

### Data freshness and coverage

- Source: **Sitadel open data**, published monthly by SDES (service statistique du ministère de la Transition écologique), usually around the end of the month, with a 1–2 month lag between authorization and publication.
- Coverage: permits and prior declarations **creating housing or floor area**, development permits and demolition permits authorized since 2013 (France incl. overseas départements). By rule of the source, refused applications, pending applications and extensions of houses without new dwelling or floor area are not published.
- A few authorization dates are mis-keyed at source (future dates). They are excluded when after `authorizedTo` (default: today).

### Legal: source, licence and personal data

- Data © **SDES — Ministère de la Transition écologique**, base Sitadel, published under the **Licence Ouverte / Open Licence v2.0 (Etalab)**, which allows free commercial reuse provided the source and date are credited. Every record carries `source`, `sourceVintage` and `attribution` — keep them when you republish.
- Company enrichment: **API Recherche d'entreprises** (DINUM / annuaire-entreprises.data.gouv.fr), built on SIRENE (INSEE) and RNE (INPI) open data, Licence Ouverte v2.0.
- **No personal data**: Sitadel itself never publishes the names of private individuals. This Actor goes further: for permits not filed by a legal entity it drops the street address and cadastral parcels and only keeps the commune and postcode. Directors' names from company registers are never included. You remain responsible for GDPR compliance when you contact companies (B2B prospecting rules, opt-out).
- This Actor is not affiliated with or endorsed by the French administration.

### Integrations and API

- **API**: run the Actor and read results over HTTP or with the Apify Python and JavaScript clients (see the **API** tab for ready-made code).
- **Schedules**: run it daily or weekly from Apify schedules.
- **Integrations**: send results to Google Sheets, Slack, e-mail, Airtable or a webhook, or connect it to Make, Zapier or n8n.
- **AI agents**: available as a tool through the Apify MCP server.

### FAQ

**Is this a French building permits API?** Yes: run the Actor through the Apify API (HTTP, Python, JavaScript) or from Make, Zapier or n8n, and get permits as JSON, CSV or Excel. It reads the official Sitadel open data, so there is no website scraping involved.

**Is there an official API?** Yes — this Actor uses the official DiDo API of SDES; it does not scrape any website.

**Can I get the phone number or e-mail of the petitioner?** No. They are not published in open data, and this Actor does not collect personal contact data.

**How often should I run it?** Monthly is enough (the source is monthly). Use `authorizedWithinDays: 60` on a monthly schedule to get only new permits.

***

### Other Actors by the same developer

- [France Public Tenders Scraper (BOAMP)](https://apify.com/capable_coach/france-public-tenders): French public procurement notices.
- [France New Companies (BODACC + SIRENE)](https://apify.com/capable_coach/france-new-companies): newly registered French companies.
- [French Jobs Scraper (Emploi France)](https://apify.com/capable_coach/emploi-france-aggregator): open-licence French job offers.

### 🇫🇷 En français

**Permis de construire en open data (base Sitadel du SDES), prêts pour la prospection B2B du BTP.** Filtrez par département, commune, date d'autorisation, nombre de logements, surface ou code NAF du pétitionnaire. Les pétitionnaires personnes morales sont fournis avec SIREN/SIRET, enrichis par l'API Recherche d'entreprises (siège, effectif, catégorie, date de création). Les projets de particuliers ne sont jamais nominatifs et sont ramenés à la commune. Source : SDES, base Sitadel — Licence Ouverte v2.0.

# Actor input Schema

## `permitCategories` (type: `array`):

Which Sitadel files to query. housing = permits/declarations creating dwellings; non_residential = offices, shops, warehouses, industry, farms, public buildings; development = permis d'aménager (land subdivisions); demolition = permis de démolir.

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

French département codes of the works location, e.g. 75, 92, 69, 13, 2A, 971. Leave empty for all of France.

## `communeCodes` (type: `array`):

INSEE commune codes (not postcodes), e.g. 69123 for Lyon, 33063 for Bordeaux, 75056 for Paris. Overrides départements when set.

## `authorizedWithinDays` (type: `integer`):

Keep permits authorized in the last N days. Sitadel is published monthly with a 1–2 month lag, so 90–180 days is a good window. 0 = no limit. Ignored if 'Authorized from' is set.

## `authorizedFrom` (type: `string`):

Optional start date of authorization.

## `authorizedTo` (type: `string`):

Optional end date of authorization (default: today).

## `petitionerType` (type: `string`):

legal_entities = only permits filed by companies, SCIs, developers, social landlords, public bodies (with SIREN, name and site address). all = also include permits filed by private individuals, which are returned at commune level only (no name, no street address, no parcel), to respect GDPR.

## `status` (type: `string`):

Filter by the latest known status of the permit.

## `minHousingUnits` (type: `integer`):

Housing permits only. E.g. 10 to target developers of apartment buildings.

## `minFloorAreaM2` (type: `integer`):

Minimum total floor area created (residential + non-residential).

## `petitionerNafPrefixes` (type: `array`):

Keep petitioners whose activity code starts with one of these, e.g. 41.10 (property developers), 68.20 (SCI / letting), 68.10, 84.11 (local authorities).

## `keyword` (type: `string`):

Optional case-insensitive filter, e.g. NEXITY, BOUYGUES, HABITAT.

## `enrichCompanies` (type: `boolean`):

Add official company data (head office address, headcount range, category, creation date, status, RGE/ESS labels) from the government API Recherche d'entreprises. Directors' names are never included.

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

Maximum permits returned (all categories combined).

## Actor input object example

```json
{
  "permitCategories": [
    "housing",
    "non_residential"
  ],
  "departments": [
    "75",
    "92",
    "93",
    "94"
  ],
  "authorizedWithinDays": 120,
  "petitionerType": "legal_entities",
  "status": "any",
  "minHousingUnits": 0,
  "minFloorAreaM2": 0,
  "enrichCompanies": true,
  "maxResults": 100
}
```

# Actor output Schema

## `permits` (type: `string`):

No description

## `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 = {
    "permitCategories": [
        "housing",
        "non_residential"
    ],
    "departments": [
        "75",
        "92",
        "93",
        "94"
    ],
    "authorizedWithinDays": 120,
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("capable_coach/france-building-permits").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 = {
    "permitCategories": [
        "housing",
        "non_residential",
    ],
    "departments": [
        "75",
        "92",
        "93",
        "94",
    ],
    "authorizedWithinDays": 120,
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("capable_coach/france-building-permits").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 '{
  "permitCategories": [
    "housing",
    "non_residential"
  ],
  "departments": [
    "75",
    "92",
    "93",
    "94"
  ],
  "authorizedWithinDays": 120,
  "maxResults": 100
}' |
apify call capable_coach/france-building-permits --silent --output-dataset

```

## MCP server setup

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

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/bM9EesjxPFwA6rDDy/builds/ypGnEVj3TTlM3xBvi/openapi.json
