# Bien'ici Scraper 🔥 French Real Estate & Rentals 🏠 (`memo23/bienici-scraper`) Actor

Scrape French real estate from Bien'ici — apartments, houses, and rentals in every French city. Price, price/m2, surface, rooms, DPE energy rating, photos, GPS, and agency contact. Paste a Bien'ici search URL or filter by city, type, and price. JSON, CSV, Excel, or API.

- **URL**: https://apify.com/memo23/bienici-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

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

## Bien'ici Scraper — French Real Estate & Rentals

Scrape French real estate listings from [Bien'ici](https://www.bienici.com/) — the map-based property portal used by millions across France. Apartments, houses, and rentals in every French city, with price, price/m², surface, rooms, DPE energy rating, photos, GPS, and agency contact.

### Why use this scraper

- **JSON API, not HTML scraping** — Bien'ici is a map-based SPA; this actor calls its internal JSON endpoints directly, so the data is structured and reliable
- **No anti-bot, no proxy needed** — runs fast from any IP
- **Whole country** — every French city, both sales (achat) and rentals (location)
- **Full details** — photo gallery, DPE/GHG energy ratings, rooms, agency name, phone, and email-available flag
- **GPS coordinates** — approximate lat/lng for every listing (blurred ~50–100 m by the site for privacy)

### Supported inputs

- **Start URL** — paste a Bien'ici search URL (e.g. `https://www.bienici.com/recherche/achat/paris-75000/appartement`) or a single listing URL (`https://www.bienici.com/annonce/ag754691-538488038`)
- **Filters** — transaction type (buy/rent), city slugs, property types, price/surface/rooms bands, new builds only, sort order

### Input configuration

| Field | Type | Description |
|---|---|---|
| `startUrl` | string | Bien'ici search or listing URL |
| `filterType` | select | `buy` (achat) / `rent` (location) |
| `locationNames` | string\[] | City slugs, e.g. `["paris-75000"]`, `["lyon-69000"]`. Bare names (`"paris"`) also work. Empty = all France |
| `propertyTypes` | string\[] | API codes: `flat`, `house`, `parking`, `terrain`, `building`, `castle`, `loft`, `office`, `premises`, `shop`, `townhouse`, `annexe`, `others`, `programme`, `residence` |
| `minPrice` / `maxPrice` | integer | Price band in euros (sale price, or monthly rent for rentals) |
| `minSurface` / `maxSurface` | integer | Surface band in m² |
| `minRooms` / `maxRooms` | integer | Room count band |
| `newProperty` | boolean | New builds only (programme / VEFA) |
| `includeOffMarket` | boolean | Include sold/rented listings (default: on-market only) |
| `sortBy` | string | `publicationDate` (default) or `relevance` |
| `sortOrder` | string | `desc` (default) / `asc` |
| `fetchFullDetails` | boolean | Fetch the detail page for each listing (default: false) |
| `maxItems` | integer | Max listings to save (default: 100, free plan: 5) |
| `proxy` | object | Optional proxy (usually unnecessary) |

### Output fields

`id`, `url`, `title`, `adType`, `adTypeFR`, `propertyType`, `reference`, `price`, `priceWithoutFees`, `pricePerSquareMeter`, `surfaceArea`, `roomsQuantity`, `city`, `postalCode`, `departmentCode`, `districtName`, `latitude`, `longitude`, `energyClassification`, `greenhouseGazClassification`, `hasPool`, `isInCondominium`, `newProperty`, `isExclusiveSaleMandate`, `feesChargedTo`, `photo`, `photos`, `description`, `publicationDate`, `modificationDate`, `priceHasDecreased`, `isBienIciExclusive`, `adCreatedByPro`, `agencyName`, `contactName`, `agencyPhone`, `hasEmail`, `source`

> `priceWithoutFees`, `roomsQuantity`, `energyClassification`, `greenhouseGazClassification`, `photos`, `description`, and the agency contact fields are only populated when `fetchFullDetails` is on.

### Use cases

- **Market research** — track sale prices and rents across French cities and arrondissements
- **Lead generation** — extract agency names and phone numbers for outreach
- **Investment analysis** — compare price/m², DPE energy ratings, and locations
- **Relocation** — find rentals by city, surface, and room count
- **New-build tracking** — monitor VEFA programmes with the `newProperty` filter
- **Data enrichment** — feed property data into CRM or analytics pipelines

### How it works

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-bienici.png)

1. The actor calls Bien'ici's internal JSON API (`/realEstateAds.json`) with a `filters` JSON payload — the same call the website's map makes
2. Search results return listing cards with price, location, surface, and a thumbnail
3. When `fetchFullDetails` is on, each listing is enriched via the detail API (`/realEstateAd.json`) with the full description, photo gallery, DPE/GHG ratings, rooms, and agency contact
4. Results are pushed to the dataset as structured JSON, deduplicated by listing id

### Pricing

This actor uses pay-per-event pricing. You are charged per listing saved to the dataset. The free tier lets you try it with 5 items per run.

### ⚠️ Disclaimer

This scraper is for educational and research purposes only. Bien'ici is a trademark of its respective owner. This actor is not affiliated with or endorsed by Bien'ici. Users are responsible for complying with Bien'ici's terms of service and applicable data protection laws (including the GDPR for any processing of personal data such as agency contact details).

### SEO Keywords

bienici scraper, bien'ici scraper, french real estate scraper, france property scraper, paris apartments, lyon real estate, marseille property, french rentals, appartement achat, location appartement, DPE energy rating, immobilier france, bienici api, bienici data extraction

# Actor input Schema

## `startUrl` (type: `string`):

A Bien'ici search URL (e.g. https://www.bienici.com/recherche/achat/paris-75000/appartement) or a single listing URL (https://www.bienici.com/annonce/ag754691-538488038). Optional — overrides the filters below when set.

## `filterType` (type: `string`):

Buy (for sale) or rent. Ignored when startUrl is a search URL.

## `locationNames` (type: `array`):

City slugs to search, e.g. \["paris-75000"] or \["lyon-69000", "marseille-13000"]. Bare city names ("paris") also work. Leave empty to search all of France.

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

Property types to include (API codes). Valid values: flat (apartment), house (maisonvilla), parking, terrain, building, castle, loft, office, premises, shop, townhouse, annexe, others, programme (new build), residence. Defaults to all. Ignored when startUrl is a search URL.

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

Minimum price in euros (sale price, or monthly rent for rentals).

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

Maximum price in euros (sale price, or monthly rent for rentals).

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

Minimum surface area in m².

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

Maximum surface area in m².

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

Minimum number of rooms.

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

Maximum number of rooms.

## `newProperty` (type: `boolean`):

Only new-build listings (programme / VEFA).

## `includeOffMarket` (type: `boolean`):

Include listings that are off the market (sold/rented). Default: on-market only.

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

Sort field. The site uses "publicationDate" (newest first) and "relevance".

## `sortOrder` (type: `string`):

Sort direction.

## `fetchFullDetails` (type: `boolean`):

Open each listing and save the full record: description, photo gallery, DPE/GHG energy ratings, rooms, and agency contact (name, phone, email-available flag). Slower.

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

Maximum listings to save. The effective limit also respects the run budget and the free-tier cap (5 for free users).

## `proxy` (type: `object`):

Optional proxy. The Bien'ici API has no anti-bot, so a proxy is usually unnecessary.

## Actor input object example

```json
{
  "startUrl": "https://www.bienici.com/recherche/achat/paris-75000/appartement",
  "filterType": "buy",
  "locationNames": [
    "paris-75000"
  ],
  "newProperty": false,
  "includeOffMarket": false,
  "sortBy": "publicationDate",
  "sortOrder": "desc",
  "fetchFullDetails": false,
  "maxItems": 100,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

The scraped Bien'ici property listings in the default dataset.

# 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 = {
    "startUrl": "https://www.bienici.com/recherche/achat/paris-75000/appartement",
    "locationNames": [
        "paris-75000"
    ],
    "maxItems": 100,
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/bienici-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 = {
    "startUrl": "https://www.bienici.com/recherche/achat/paris-75000/appartement",
    "locationNames": ["paris-75000"],
    "maxItems": 100,
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/bienici-scraper").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 '{
  "startUrl": "https://www.bienici.com/recherche/achat/paris-75000/appartement",
  "locationNames": [
    "paris-75000"
  ],
  "maxItems": 100,
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call memo23/bienici-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/bienici-scraper"
        }
    }
}
```

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/8P3tJxJc85dlBoP4R/builds/Pd0aUsn9asbAbrqhR/openapi.json
