# Bien'ici Property Scraper · Buy & rent France · $1/1K (`mlg14/bienici-scraper`) Actor

Search Bien'ici property listings by French city or postal code for real estate research, rental monitoring and price analysis. Buy or rent, with price, surface, rooms, energy rating and photos. $1/1K listings.

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

## Pricing

$1.00 / 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 Property Scraper

Scrape Bien'ici property listings for sale or rent across French cities and postal codes. Export search results with prices, surfaces, rooms, energy ratings, photos, agency identifiers, and approximate map coordinates as structured rows for analysis.

### What data can you extract from Bien'ici?

Each property is returned as a flat record. Fields that the listing does not disclose are left empty instead of being guessed.

| Field | Description | Example |
|---|---|---|
| `id` | Unique listing identifier. | `apimo-87239094` |
| `reference` | Listing reference supplied by the advertiser. | `1500` |
| `title` | Public listing title. | `Appartement de 125 m²` |
| `description` | Listing description text. | `Appartement avec deux chambres…` |
| `transactionType` | Sale or rental category. | `buy` |
| `propertyType` | Bien'ici property category. | `flat` |
| `price` | Advertised amount in euros; monthly for rentals. | `2250000` |
| `priceWithoutFees` | Price excluding agency fees when present. | `null` |
| `pricePerSquareMeter` | Published price per m², or calculated from price and surface. | `18180.35` |
| `agencyFeePercentage` | Agency fee rate when disclosed. | `null` |
| `feesChargedTo` | Party responsible for agency fees when disclosed. | `null` |
| `priceHasDecreased` | Whether the asking price has been reduced. | `false` |
| `surfaceArea` | Living surface in square meters. | `123.76` |
| `landSurfaceArea` | Land or plot surface when applicable. | `null` |
| `roomsQuantity` | Number of rooms. | `4` |
| `bedroomsQuantity` | Number of bedrooms. | `2` |
| `bathroomsQuantity` | Number of bathrooms. | `null` |
| `toiletQuantity` | Number of separate toilets. | `null` |
| `floor` | Floor of the unit. | `null` |
| `floorQuantity` | Total floors in the building. | `null` |
| `hasCellar` | Whether a cellar is included. | `null` |
| `cellarsOrUndergroundsQuantity` | Cellar or underground storage count. | `null` |
| `hasElevator` | Whether the building has an elevator. | `null` |
| `hasTerrace` | Whether a terrace is included. | `null` |
| `terracesQuantity` | Number of terraces. | `null` |
| `hasBalcony` | Whether a balcony is included. | `null` |
| `balconyQuantity` | Number of balconies. | `null` |
| `energyClassification` | Energy performance class. | `D` |
| `energyValue` | Energy consumption value when published. | `null` |
| `greenhouseGazClassification` | Greenhouse gas emissions class. | `D` |
| `greenhouseGazValue` | Greenhouse gas emissions value when published. | `null` |
| `city` | City or locality reported by the listing. | `Paris 7e` |
| `postalCode` | French postal code. | `75007` |
| `district` | District or neighborhood when supplied. | `Champ de Mars` |
| `departmentCode` | French department code derived from the listing location. | `75` |
| `latitude` | Approximate listing latitude; exact coordinates may be hidden. | `48.8551` |
| `longitude` | Approximate listing longitude; exact coordinates may be hidden. | `2.3033` |
| `newProperty` | Whether the property is classed as new. | `false` |
| `isInCondominium` | Whether the property belongs to a condominium. | `null` |
| `annualCondominiumFees` | Annual condominium charges when disclosed. | `null` |
| `publicationDate` | First publication date when the advertiser provides it. | `null` |
| `modificationDate` | Last modification date in ISO 8601 format. | `2026-10-15T23:16:45.312Z` |
| `photos` | Array of image URLs. | `https://file.bienici.com/photo/...` |
| `agencyName` | Agency name when present in listing data. | `null` |
| `agencyAccountId` | Seller account identifier when available. | `apimo-...` |
| `agencyPhone` | Public agency phone number when available. | `null` |
| `agencyContactName` | Public agency contact name when available. | `null` |
| `agencyAddress` | Agency address when disclosed. | `null` |
| `accountType` | Seller account category. | `agency` |
| `heating` | Heating system when provided. | `null` |
| `exposition` | Property orientation when provided. | `null` |
| `isBienIciExclusive` | Whether the listing is exclusive to the site. | `false` |
| `with3dModel` | Whether a 3D model or virtual tour is indicated. | `false` |
| `url` | Direct property page. | `https://www.bienici.com/annonce/vente/paris-7e/appartement/4-pieces/apimo-87239094` |

The examples in this table describe field formats. Values are advertiser-dependent; nulls are expected for details not included in the public search record. The actor uses the listing's available map location and does not claim an exact street address when the site blurs it.

### How to scrape Bien'ici

1. Choose a city, district, or postal code in `location`, or paste one or more search result links in `startUrls`.
2. Select sale or rental listings and, if useful, narrow by property type, price, room count, bedroom count, or surface.
3. Set `maxResults` to the number of rows needed. Keep `includeDetails` off for the fastest search-only run.
4. Start the run and inspect the resulting dataset. Download the rows as JSON or CSV for further analysis.

The actor resolves the location through Bien'ici's public suggestion data and applies filters in the listing search request. It does not download every page of the website and attempt to infer search filters afterward. When multiple URLs are supplied, results are combined and duplicate listing IDs are emitted once.

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | Array of strings | `[]` | Optional Bien'ici search URLs. The route can supply transaction, location, and property type. Use the filter fields below for additional limits. |
| `transactionType` | `buy` or `rent` | `buy` | Search properties for sale or for rent. |
| `location` | String | `Paris` | City, district, or postal code, such as `Lyon` or `75011`. |
| `propertyTypes` | Array of strings | `[]` | Values include `flat`, `house`, `loft`, `townhouse`, `castle`, `terrain`, `parking`, `building`, `shop`, `office`, and `premises`. Empty means any type. |
| `priceMin` | Integer | Empty | Minimum price in euros; monthly rent for rental searches. |
| `priceMax` | Integer | Empty | Maximum price in euros; monthly rent for rental searches. |
| `roomsMin` | Integer | Empty | Minimum number of rooms. |
| `bedroomsMin` | Integer | Empty | Minimum number of bedrooms. |
| `surfaceMin` | Integer | Empty | Minimum living surface in square meters. |
| `surfaceMax` | Integer | Empty | Maximum living surface in square meters. |
| `sortBy` | Select | `relevance` | Sort by relevance, ascending or descending price, newest, or largest surface. |
| `includeDetails` | Boolean | `false` | Request each individual public listing record for any additional contact or property details that are available. This adds one request per result. |
| `maxResults` | Integer | `100` | Total output cap. Set to `0` for up to the site search limit per URL. |
| `maxResultsPerUrl` | Integer | `0` | Per-search cap. `0` uses the site's search limit of 2,500 results. |
| `ignoreUrlFailures` | Boolean | `true` | Continue after a failed search URL. If all searches fail or return no listings, the run reports an error. |
| `proxyConfiguration` | Object | Default proxy | Optional request proxy settings. |

#### Example: Paris apartments for sale

```json
{
  "transactionType": "buy",
  "location": "Paris",
  "propertyTypes": ["flat"],
  "priceMax": 500000,
  "roomsMin": 2,
  "sortBy": "newest",
  "maxResults": 100
}
```

#### Example: Lyon rentals

```json
{
  "transactionType": "rent",
  "location": "Lyon",
  "propertyTypes": ["flat", "loft"],
  "priceMax": 1500,
  "bedroomsMin": 1,
  "maxResults": 75
}
```

If `startUrls` contains a route for a city and transaction, those route values take precedence. For other constraints, set the corresponding input properties explicitly. A route's query-string filters are not fully decoded, so provide any price, room, or surface constraints in the input.

### Output example

This is an item returned by the Paris sale golden run. The photo list is shortened here to keep the example readable.

```json
{
  "id": "apimo-87239094",
  "reference": "1500",
  "title": "Paris VIIᵉ | Champ-de-Mars | Appartement de 125 m² | Chambre de service de 10 m²",
  "transactionType": "buy",
  "propertyType": "flat",
  "price": 2250000,
  "pricePerSquareMeter": 18180.349062702004,
  "surfaceArea": 123.76,
  "roomsQuantity": 4,
  "bedroomsQuantity": 2,
  "energyClassification": "D",
  "greenhouseGazClassification": "D",
  "city": "Paris 7e",
  "postalCode": "75007",
  "district": "Champ de Mars",
  "departmentCode": "75",
  "latitude": 48.855121521939274,
  "longitude": 2.303284548300216,
  "modificationDate": "2026-10-15T23:16:45.312Z",
  "photos": [
    "https://file.bienici.com/photo/apimo-87239094_media.apimo.pro_cache_622eb51a0128ab5ff28c221fc0e4a7ee_a0219f31f2_1448-original.jpg",
    "https://file.bienici.com/photo/apimo-87239094_media.apimo.pro_cache_284f8cede55eec18cc73b4fb5f1a776c_c701b2893b_1448-original.jpg"
  ],
  "agencyAccountId": "apimo-87239094",
  "accountType": "agency",
  "url": "https://www.bienici.com/annonce/vente/paris-7e/appartement/4-pieces/apimo-87239094"
}
```

### Use cases

- **Property investors:** collect current asking prices and compare price per square meter across districts before building a shortlist.
- **Rental teams:** find active apartments by city, rent ceiling, room count, and living surface for relocation or tenant research.
- **Market analysts:** compare the visible mix of homes, apartments, land, and commercial stock across French markets.
- **Energy specialists:** group listings by published energy and greenhouse gas classifications to identify properties that may need closer review.
- **Mapping projects:** use approximate coordinates, city, postal code, and district to plot available listings at neighborhood scale.
- **Agency researchers:** review public agency identifiers and any contact details the listing exposes, while respecting applicable privacy and outreach rules.

### How much does it cost to scrape Bien'ici?

The current result event rate is **$1.00 per 1,000 listings**. The result charge scales with rows written to the dataset; it does not depend on how many optional fields happen to be populated.

- 100 listings: approximately **$0.10** in result charges.
- 1,000 listings: approximately **$1.00** in result charges.
- 5,000 listings: approximately **$5.00** in result charges.

These examples cover result events at the current rate. Your account displays any applicable execution or plan usage separately. A run that stops at `maxResults` does not continue collecting or charging result events after the cap is reached.

### Tips for best results

- Start with a city or postal code and a modest result cap to make sure the selected transaction matches your research.
- Narrow larger areas with a property type, price band, or additional URL for a nearby district. Each URL has a site-side result limit.
- Use `rent` with monthly rent limits; do not enter an annualized amount in `priceMax`.
- For active inventory, leave the on-market selection enabled. Search results can change as properties are sold, rented, or removed.
- Keep `includeDetails` disabled when price, size, rooms, location, photos, and energy data are enough. Enabling it requests the public listing record individually and can lengthen a large run.
- Use `modificationDate` as a freshness indicator when it is present. Some advertisers omit the publication date or provide a placeholder date; unavailable dates are returned as null.
- Treat `pricePerSquareMeter` as a comparison aid. The source may provide its own value; otherwise this actor calculates it from the listed price and living surface.
- For a broad city inventory, split searches by property category or price range so each request stays focused and within the site's per-search cap.

### Limits

Bien'ici's search endpoint caps a single search at approximately 2,500 listings. The actor honors that ceiling for each URL, even when `maxResults` is `0`. Use narrower searches or multiple URLs to cover a larger market. A total `maxResults` value still applies across all URLs.

Search records are public listing summaries, not full appraisal reports. Energy values, fees, floor counts, outdoor-space counts, agency phone numbers, and contact names can be absent. The optional details request may provide extra values, but it cannot recover details the advertiser or site does not expose.

Coordinates can be approximate because exact property positions may be blurred. Dates can be missing or represented by a placeholder; placeholder dates are converted to null. The scraper uses the location resolved by the site, so an ambiguous place name can select the highest-ranked matching suggestion. Use a postal code or a more specific district when needed.

Search URLs supply transaction, location, and property type when those values are encoded in the route. Query-string filters are not fully reconstructed. Put price, room, bedroom, and surface constraints in the actor input to make sure they are applied to the API request.

### Automated research workflows

Use a saved search as a repeatable starting point and set a clear row cap for each scheduled collection. Example tasks include:

- “Collect up to 100 apartments for sale in Paris below €500,000, newest first.”
- “Compare available rentals in Lyon and Bordeaux with at least two bedrooms, then export the rows as CSV.”

The output is a flat dataset, so each run can be downloaded or passed to a later reporting step without reshaping nested page markup. Keep a copy of the input alongside each export to make price and inventory comparisons reproducible.

### FAQ

#### Is it legal to collect these listings?

The scraper reads publicly accessible property listing data. You are responsible for following the site's terms, applicable law, and privacy requirements. Use public contact data only for appropriate purposes and do not use it for unsolicited or unlawful outreach.

#### Do I need to provide a proxy?

No. The actor uses its configured request proxy by default. A custom proxy can be supplied in `proxyConfiguration` when your account or network setup requires it.

#### How fast is a run?

Speed depends on the result cap, network response time, and whether `includeDetails` is enabled. Search-only runs request listings in pages. Optional per-listing details add one request for each collected property.

#### Can I schedule recurring searches?

Yes. Save the input and schedule it through your account's run scheduler. Each scheduled run produces a separate dataset that can be compared with earlier results.

#### Can I export the results to a spreadsheet?

Yes. Download the dataset as CSV or Excel-compatible output, or retrieve the structured JSON for your own reporting workflow.

#### Why are some fields empty?

Advertisers do not publish every characteristic, and some details are withheld from general search responses. Empty values mean the source did not supply that field in the data returned for the listing.

#### Why are fewer listings returned than requested?

The selected city and filters may have fewer active matches than the requested maximum. Bien'ici also limits a single search to around 2,500 listings. Try a broader filter or split a large search into several location or price segments.

### Use with AI agents (MCP)

Add this actor to any MCP client (Claude, Cursor, VS Code, n8n and others) with one URL:

`https://mcp.apify.com?tools=mlg14/bienici-scraper`

The actor returns one dataset item per Bien'ici listing (price, surface, rooms, energy rating, photos, location, URL). Set `maxResults` to keep results bounded.

**Prompt 1:** "Find apartments for sale in Paris 75011 under 600000 euros."

```json
{
  "transactionType": "buy",
  "location": "75011",
  "priceMax": 600000,
  "maxResults": 20
}
```

**Prompt 2:** "List the newest rentals in Lyon with at least 2 bedrooms."

```json
{
  "transactionType": "rent",
  "location": "Lyon",
  "bedroomsMin": 2,
  "sortBy": "newest",
  "maxResults": 20
}
```

**Prompt 3:** "Get the 20 largest properties for sale in Paris."

```json
{
  "transactionType": "buy",
  "location": "Paris",
  "sortBy": "surfaceDesc",
  "maxResults": 20
}
```

### Integrations

Download the default dataset in JSON or CSV, retrieve it through the dataset endpoint, or connect completed runs to webhook-based reporting and scheduled data workflows. The flat fields are suitable for spreadsheets, maps, market dashboards, and recurring inventory comparisons.

### Support

Open an issue on the Issues tab; we reply within 24 hours and add fields on request.

# Actor input Schema

## `startUrls` (type: `array`):

Bien'ici search result URLs; transaction, location and property type are read from the route. Example: \[{"url": "https://www.bienici.com/recherche/achat/paris-75000"}]. Leave empty to use location.

## `transactionType` (type: `string`):

Search for sale or for rent. Allowed values: buy, rent. Example: rent. Used when startUrls is empty or does not specify one. Use rent for rentals.

## `location` (type: `string`):

French city, district or postal code to search. Example: Paris, Lyon or 75011. Use when startUrls is empty.

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

Limit results to these property types. Allowed values: flat, house, loft, townhouse, castle, terrain, parking, building, shop, office, premises. Example: \["flat", "house"]. Leave empty for all types.

## `priceMin` (type: `integer`):

Minimum price in euros; for rentals the monthly rent. Example: 200000. Leave empty for no minimum.

## `priceMax` (type: `integer`):

Maximum price in euros; for rentals the monthly rent. Example: 600000. Leave empty for no maximum.

## `roomsMin` (type: `integer`):

Minimum number of rooms (pieces), an integer. Example: 3. Leave empty for no minimum.

## `bedroomsMin` (type: `integer`):

Minimum number of bedrooms (chambres), an integer. Example: 2. Leave empty for no minimum.

## `surfaceMin` (type: `integer`):

Minimum living surface in square meters, an integer. Example: 50. Leave empty for no minimum.

## `surfaceMax` (type: `integer`):

Maximum living surface in square meters, an integer. Example: 120. Leave empty for no maximum.

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

Order of results. Allowed values: relevance, priceAsc, priceDesc, newest, surfaceDesc. Example: newest. Use newest to monitor fresh listings.

## `includeDetails` (type: `boolean`):

Request each listing's public record for extra agency contact and property fields, true or false. Example: true. Leave false for fast runs; true adds one request per listing.

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

Maximum listings across the run, an integer. Example: 50. Set 0 for up to the site limit of 2,500 per URL.

## `maxResultsPerUrl` (type: `integer`):

Maximum listings from each search URL, an integer. Example: 100. Set 0 to use the site limit of 2,500 per URL.

## `ignoreUrlFailures` (type: `boolean`):

Skip a failed search URL and continue with the rest, true or false. Example: false to stop on the first failure. Leave true otherwise; a run with no listings still fails.

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

Proxy configuration for requests to public Bien'ici search endpoints. Leave the default.

## Actor input object example

```json
{
  "startUrls": [],
  "transactionType": "buy",
  "location": "Paris",
  "propertyTypes": [],
  "sortBy": "relevance",
  "includeDetails": false,
  "maxResults": 100,
  "maxResultsPerUrl": 0,
  "ignoreUrlFailures": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped 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 = {
    "startUrls": [],
    "transactionType": "buy",
    "location": "Paris",
    "propertyTypes": [],
    "sortBy": "relevance",
    "includeDetails": false,
    "maxResults": 100,
    "maxResultsPerUrl": 0,
    "ignoreUrlFailures": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("mlg14/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 = {
    "startUrls": [],
    "transactionType": "buy",
    "location": "Paris",
    "propertyTypes": [],
    "sortBy": "relevance",
    "includeDetails": False,
    "maxResults": 100,
    "maxResultsPerUrl": 0,
    "ignoreUrlFailures": True,
}

# Run the Actor and wait for it to finish
run = client.actor("mlg14/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 '{
  "startUrls": [],
  "transactionType": "buy",
  "location": "Paris",
  "propertyTypes": [],
  "sortBy": "relevance",
  "includeDetails": false,
  "maxResults": 100,
  "maxResultsPerUrl": 0,
  "ignoreUrlFailures": true
}' |
apify call mlg14/bienici-scraper --silent --output-dataset

```

## MCP server setup

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