# French Syndics & Condos · ANAH Registry · By Department (`corent1robert/annuaire-syndics-coproprietes-fr`) Actor

Extract all 4,600+ syndics and 635,000+ French condos from the national ANAH registry. Filter by department — get SIRET, APE code, condo stats. Optional director enrichment. No login needed.

- **URL**: https://apify.com/corent1robert/annuaire-syndics-coproprietes-fr.md
- **Developed by:** [Corentin Robert](https://apify.com/corent1robert) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 syndic without director emails

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

## French Syndics & Condos · ANAH Registry · By Department

Extract all **4,600+ syndics** and **635,000+ French condominiums** from the official national condo registry (ANAH). Filter by department, choose between a syndic-level or condo-level export, and optionally enrich each syndic with company directors from the official French business register.

**No login. No API key. Public data.**

***

### What it collects

#### Syndic fields (always included)

| Field | Description |
|---|---|
| `syndicName` | Legal name of the syndic company |
| `syndicSiret` | 14-digit SIRET number |
| `syndicSiren` | 9-digit SIREN |
| `syndicCodeApe` | NAF/APE activity code (e.g. 6831Z) |
| `syndicCommune` | City of the registered office |
| `syndicDepartment` | INSEE department code |
| `syndicRegion` | French region slug |
| `syndicKind` | `professionnel` / `bénévole` / `non connu` |
| `syndicIsCooperatif` | True if cooperative syndic |
| `syndicTotalCopros` | Number of condos managed |
| `syndicTotalLots` | Total lots across all managed condos |
| `syndicTotalLotsHabBurCom` | Lots — housing + offices + commercial |
| `syndicTotalLotsHabitation` | Residential lots only |
| `syndicTotalLotsStationnement` | Parking lots |

#### Director enrichment (optional — `enrichWithDirectors: true`)

One call per syndic to the official French company register. No API key required.

| Field | Description |
|---|---|
| `syndicAdresse` | Full registered office address |
| `syndicCodePostal` | Postal code |
| `syndicLatitude` / `syndicLongitude` | GPS coordinates |
| `syndicNatureJuridique` | Legal form code (e.g. `5499` = SARL) |
| `syndicCategorieEntreprise` | `PME` / `ETI` / `GE` |
| `syndicTrancheEffectif` | Headcount band |
| `syndicDateCreation` | Company creation date |
| `dirigeants` | All directors: `{ nom, prenoms, qualite, anneeNaissance, typeDirigeant }` |
| `dirigeant1Nom` | First director last name (flat, for Excel/CRM) |
| `dirigeant1Prenoms` | First director first name(s) |
| `dirigeant1Qualite` | Role (e.g. Gérant, Président) |
| `dirigeant1AnneeNaissance` | First director birth year |

#### Condo fields (mode `syndics_with_copros`)

| Field | Description |
|---|---|
| `coproName` | Condo name |
| `coproAddress` | Street address |
| `coproPostalCode` | Postal code |
| `coproCommune` | City |
| `coproImmatriculation` | ANAH immatriculation number (e.g. AA3275369) |
| `coproTotalLots` | Total lots |
| `coproLotsHabitation` | Residential lots |
| `coproLotsStationnement` | Parking lots |
| `coproSourceUrl` | URL of the ANAH condo fiche |

***

### Important / Limitations

- Data comes from the **Registre National des Copropriétés** managed by ANAH. Syndics are legally required to register their condos, but completeness varies.
- The registry is **updated quarterly** by ANAH. Some fields (phone, email) are not published.
- Syndics with SIRET `non connu` will have **no director enrichment** even if `enrichWithDirectors` is enabled.
- Mode `syndics_with_copros` visits each of the 635,000+ condo fiches individually — expect **long run times** (several hours for all France). Use `departments` to limit scope.
- No proxy is required for most runs. The ANAH directory is publicly accessible without rate limits in typical usage.

***

### Quick start

1. Open the Actor in the Apify Console.
2. Choose a **mode**: *Syndics only* for a fast list of syndics, or *Syndics + condos* for one row per condo.
3. Optionally enter **department codes** (e.g. `75`, `06`, `13`). Leave empty for all France.
4. Enable **Director enrichment** if you need contact names for outreach.
5. Click **Start**. Download your dataset as JSON, CSV, or Excel.

***

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `syndics` | `syndics` or `syndics_with_copros` |
| `departments` | string\[] | `[]` | INSEE department codes. Empty = all France |
| `maxSyndics` | integer | `50` | Stop after N syndics. `0` = no limit |
| `enrichWithDirectors` | boolean | `false` | Add directors from the official company register |
| `proxyConfiguration` | object | `{}` | Optional Apify proxy config |

**API-only parameters** (not shown in the Console form, accepted via JSON input):

None at this time.

#### JSON input examples

Syndics only — all of Paris:

```json
{
  "mode": "syndics",
  "departments": ["75"],
  "maxSyndics": 0
}
```

Syndics + condos — PACA region with directors:

```json
{
  "mode": "syndics_with_copros",
  "departments": ["06", "13", "83", "84"],
  "maxSyndics": 0,
  "enrichWithDirectors": true
}
```

***

### How it works

1. **Department pages** — The Actor loads each requested department page from the ANAH directory and collects commune links.
2. **Commune pages** — Each commune page lists the syndics registered in that city.
3. **Syndic fiches** — Each syndic fiche is visited to collect identity, SIRET, lot stats, and the list of managed condos.
4. **Director enrichment** (optional) — For each syndic with a known SIRET, one request is made to `recherche-entreprises.api.gouv.fr` to collect directors and registered address.
5. **Condo fiches** (mode `syndics_with_copros` only) — Each condo fiche is visited for the full address and immatriculation number.

All pages are static HTML — no browser required. The Actor uses CheerioCrawler (512 MB RAM).

***

### Output sample

#### Mode `syndics`

```json
{
  "syndicName": "A.B.S.I.S. IMMOBILIER",
  "syndicSiret": "48457182300042",
  "syndicSiren": "484571823",
  "syndicCodeApe": "6831Z",
  "syndicCommune": "BIARRITZ",
  "syndicDepartment": "64",
  "syndicRegion": "nouvelle-aquitaine",
  "syndicKind": "professionnel",
  "syndicIsCooperatif": false,
  "syndicTotalCopros": 2,
  "syndicTotalLots": 207,
  "syndicTotalLotsHabitation": 84,
  "syndicTotalLotsStationnement": 94,
  "syndicAdresse": "4 AVENUE DE PAILLET 64200 BIARRITZ",
  "syndicCodePostal": "64200",
  "syndicLatitude": "43.46944129",
  "syndicLongitude": "-1.549681908",
  "syndicNatureJuridique": "5499",
  "syndicCategorieEntreprise": null,
  "syndicTrancheEffectif": "02",
  "syndicDateCreation": "2021-06-04",
  "dirigeants": [
    { "nom": "RECALDE", "prenoms": "DANIELA", "qualite": "Gérant", "anneeNaissance": "1973", "typeDirigeant": "personne physique" }
  ],
  "dirigeant1Nom": "RECALDE",
  "dirigeant1Prenoms": "DANIELA",
  "dirigeant1Qualite": "Gérant",
  "dirigeant1AnneeNaissance": "1973",
  "coproprietes": [
    { "coproName": "LE PRIVE", "coproAddress": "121 av de verdun 64200 Biarritz", "coproTotalLots": 185, "coproImmatriculation": "AA3275369" }
  ],
  "syndicSourceUrl": "https://annuairedescoproprietes.fr/syndic/biarritz/absis-immobilier-/48457182300042.html",
  "scrapedAt": "2026-05-09T15:30:00.000Z"
}
```

***

### Local development

#### Prerequisites

```bash
node >= 18
npm install
```

#### Run locally

```bash
## Edit storage/key_value_stores/default/INPUT.json to set your test input
npm start

## Or pass input directly:
node src/main.js
```

The default `INPUT.json` runs department `06` with `maxSyndics: 5` for a fast smoke test.

#### Run tests

```bash
npm test
```

#### Input merge order (local dev)

If both `input.json` (repo root) and `storage/key_value_stores/default/INPUT.json` exist, the KV store input takes precedence (standard Apify local behaviour). Use `INPUT.json` in the KV store for all local runs.

***

### Also available

| Actor | Best for |
|-------|----------|
| **[French Accountants Directory Scraper](https://apify.com/corent1robert/experts-comptables-annuaire-scraper)** | Expert-comptable firms — city, nationwide, or profile URLs |
| **[Notaires.fr Directory Scraper](https://apify.com/corent1robert/notaires-fr-annuaire-scraper)** | Official notary directory |
| **[French Companies · Search & SIREN Enrich](https://apify.com/corent1robert/recherche-entreprises-scraper)** | SIREN enrichment for property-management companies |
| **[BODACC Legal Announcements](https://apify.com/corent1robert/bodacc-announcements-scraper)** | Registrations and legal events by SIREN |

Browse all: **[apify.com/corent1robert](https://apify.com/corent1robert)**

***

### Support

Contact <corentin@outreacher.fr> for custom exports, bespoke integrations, or enriched datasets tailored to your needs.

# Changelog

This Actor's version history is a separate document: https://apify.com/corent1robert/annuaire-syndics-coproprietes-fr/changelog.md

# Actor input Schema

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

Syndics only: one row per syndic with managed condos listed inside. Syndics + condos: one row per condo, syndic info repeated on each row — ideal for Excel or CRM import.

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

Paste one or more INSEE department codes (e.g. 75, 06, 13, 69). Leave empty to collect the entire country (~4,600 syndics). Two-digit codes: 06, 75. DOM-TOM: 971, 972, 974.

## `maxSyndics` (type: `integer`):

Stops after this many syndics are collected. Set to 0 to collect everything in the selected departments. Useful for quick test runs.

## `enrichWithDirectors` (type: `boolean`):

For each syndic with a known SIRET, look up the official French company register to add directors (name, role, birth year), registered address with GPS coordinates, legal form, and headcount band. No API key required.

## `proxyConfiguration` (type: `object`):

French residential proxy (default). The ANAH website blocks datacenter IPs, so keep this on.

## Actor input object example

```json
{
  "mode": "syndics",
  "departments": [
    "06"
  ],
  "maxSyndics": 5,
  "enrichWithDirectors": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# Actor output Schema

## `datasetUrl` (type: `string`):

Download the complete dataset as JSON.

## `runLogUrl` (type: `string`):

Plain-text log of all run phases and progress.

# 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": "syndics",
    "departments": [
        "06"
    ],
    "maxSyndics": 5,
    "enrichWithDirectors": false,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("corent1robert/annuaire-syndics-coproprietes-fr").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": "syndics",
    "departments": ["06"],
    "maxSyndics": 5,
    "enrichWithDirectors": False,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("corent1robert/annuaire-syndics-coproprietes-fr").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": "syndics",
  "departments": [
    "06"
  ],
  "maxSyndics": 5,
  "enrichWithDirectors": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call corent1robert/annuaire-syndics-coproprietes-fr --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,corent1robert/annuaire-syndics-coproprietes-fr"
        }
    }
}
```

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/NeDkJyUKGqXEWZzkD/builds/f30EsQI7McYl2t9Zb/openapi.json
