# Bien'ici Property Listings - France Rent and Sale (`superslowsloth/bienici-listings`) Actor

French property ads from Bien'ici, for sale or to rent, by city name or postal code: price, surface, rooms, energy label, agency, photos and publication dates. Newest first, so a daily run is a new-listing alert.

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

## Pricing

from $1.40 / 1,000 listing scrapeds

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 Listings Scraper - France, Rent and Sale

French property ads from [Bien'ici](https://www.bienici.com), one flat, typed
dataset row per ad: price, surface, rooms, bedrooms, energy and greenhouse-gas
labels, floor, year built, district, agency, photos and the publication and
update dates. For rent or for sale, by city name, postal code or Bien'ici zone
id, newest first - so a daily run is a **new-listing alert**.

### What you are paying for, honestly

The data comes from the JSON endpoint behind bienici.com's own map and search
(`/realEstateAds.json`). It needs no login or API key, and anyone who finds it
can read the same JSON. What this actor adds:

- **You type a place, not an id.** Bien'ici filters on internal zone ids
  (`-120965` is Lyon). This actor resolves a city name (`Lyon`, `Saint-Etienne`),
  an arrondissement (`Lyon 3e`) or a postal code (`69003`) with Bien'ici's own
  place search and tells you in the log which place each line became. If you
  already hold a zone id, paste it (`-7444`, or `zone:-7444`) and no lookup is made.
- **One row per ad, flat.** Prices that are `[min, max]` lists on new-build
  programmes, blurred coordinates in a nested object, photos as objects: here they
  are named columns and a list of photo URLs.
- **Checked input.** The API does not validate what it is sent: an unknown
  property type or zone returns zero ads, a mistyped transaction type is silently
  dropped, and a search with no zone returns every ad in France. This actor
  refuses all of those before a request, so a typo is an error message and not an
  empty or enormous run.
- **Several places in one run, on a schedule.** Run a list of cities daily and
  send the dataset to Sheets, a webhook, S3 or a warehouse. An ad that matches two
  of your places is returned and charged once.
- **The refusal handling.** A refused (403/429/5xx) request, a timeout, or a 200
  that is not the data is retried from a fresh proxy address.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `locations` | array | `Lyon` | City, arrondissement, 5-digit postal code or zone id, one per line. Required. |
| `transaction` | string | `rent` | `rent` (location) or `buy` (vente). |
| `propertyTypes` | array | `flat`, `house` | Any of `flat`, `house`, `loft`, `parking`, `terrain`, `shop`, `office`, `premises`, `building`, `townhouse`. |
| `minPrice`, `maxPrice` | integer | - | EUR: per month when renting, total when buying. Ads with no price are dropped when a bound is set. |
| `sort` | string | `newest` | `newest`, `updated`, `price_asc`, `price_desc`. |
| `maxItems` | integer | `100` | Most ads **per location**. Each ad is billed, so this is a spending cap. |
| `proxyConfiguration` | proxy | Apify datacenter | Measured 2026-10-09: the API answered 200 from the Apify platform on datacenter and residential exits. |

New-build programmes are returned under `flat` (a programme is one ad for many
units; see the price range fields below). `buy` also returns life-annuity sales
(viager, `ad_type` = `lifeAnnuitySale`) and, for commercial property types, lease
transfers and business take-overs; filter on `ad_type` if you want plain sales.

### The 2,500-ad window

Bien'ici serves at most the first 2,500 matches of any one search: asking past
that is refused by the API. For a bigger market (a flat search in Paris has
thousands of ads) the run stops at 2,500 and the log says how many more exist.
Split the market with `minPrice`/`maxPrice` bands or by property type to read all
of it; ads are de-duplicated across the run, so overlapping bands cost nothing extra.

### Output

One row per ad. The same ad found from two of your locations is one row.

```
id, url                                     Bien'ici ad id and the ad page URL
search_location, resolved_place             what you typed, and the place Bien'ici matched
ad_type, transaction_type, property_type, property_subtype
title, description
price, price_max, price_per_m2, charges, price_decreased        EUR (charges: monthly, rentals)
surface_area_m2, surface_area_max_m2        m2
rooms, bedrooms, bathrooms, floor, year_of_construction
new_property, is_furnished, has_elevator, has_terrace, has_pool
energy_class, ghg_class, available_date
city, postal_code, district
latitude, longitude, location_type, location_radius_m
published_at, modified_at                   ISO-8601 UTC
account_type, agency_name, reference
photo_count, photo_urls
```

Dataset views: **Listings** and **Energy, location and agency**.

#### Null means "not given", never zero

- **`price` is null when the ad has none** (a commercial lease on request, an
  unpriced building). It is never 0. Money can carry cents (`424.77`), so prices
  are numbers with decimals.
- **`published_at` is null on about 30% of ads.** Bien'ici stores
  `1970-01-01` for ads without a recorded first-publication date (measured: 736
  of 2,419 ads, 2026-10-09). That is a gap, not a date, so it is null here;
  `modified_at` is nearly always present, and `sort = updated` orders by it. Note
  that an ad with no publication date can still be brand new, so a new-listing
  alert should key on `id` (what you have not seen before) rather than only on
  `published_at`.
- **`rooms` is null when Bien'ici sends 0.** `bedrooms` keeps a 0: a studio has none.
- **Programmes (new builds)** are one ad for many units: `price` and
  `surface_area_m2` hold the lowest value and `price_max` and `surface_area_max_m2`
  the highest. On every other ad the `*_max` fields are null.
- **Coordinates are blurred by Bien'ici**, not the address. `location_type` says
  how (`disk` around the property, or the whole `cityOrArrondissement`) and
  `location_radius_m` the size of the disk.
- `energy_class`, `year_of_construction`, `floor`, `agency_name`, `charges` and the
  rest are null whenever the advertiser did not fill them in, which is common
  (more than a third of ads have no energy label: 907 of 2,419 measured).
- A place Bien'ici does not know, or a search with no ads, returns no rows, costs
  only the actor start fee and is named in the run log.

### Pricing

Pay per event: a small **actor start** fee plus one **listing scraped** event per
row. Set `maxItems` to cap spend.

### Limits

- France only, as far as Bien'ici covers it. Nothing is geocoded here.
- A snapshot: Bien'ici's search index lags the site by minutes, and an ad can be
  withdrawn between two runs.
- Photos and agency names are what the advertiser provided. Phone numbers and
  contact details are not part of the search data and are not returned.
- Not affiliated with Bien'ici.

# Actor input Schema

## `locations` (type: `array`):

Where to search, one per line: a French city or arrondissement by name (Lyon, Marseille, Lyon 3e, Saint-Etienne), a 5-digit postal code (69003), or - advanced - a Bien'ici zone id such as -7444 (Paris). Names and postal codes are looked up with Bien'ici's own place search and the best match is used; the log says which place each line became. Lyon is -120965 and Marseille -76469.

## `transaction` (type: `string`):

Which market to read. Rent returns lettings; buy returns properties for sale, including life-annuity sales (viager) and new-build programmes listed under flats.

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

Which kinds of property to include, one per line. Allowed: flat, house, loft, parking, terrain, shop, office, premises, building, townhouse. Leave empty for flat and house. An unknown word is refused before the search, because Bien'ici itself would answer it with zero ads.

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

Optional. Keep ads priced at least this many euros: per month when renting, in total when buying. Ads with no price are dropped when a price bound is set.

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

Optional. Keep ads priced at most this many euros: per month when renting, in total when buying. Use it to read past the 2,500-ads-per-search window Bien'ici serves.

## `sort` (type: `string`):

Newest first (by first publication) is what makes a repeated run a new-listing alert. About 30 percent of ads have no recorded publication date and sort last; 'Recently updated' orders by last change instead and does not have that gap.

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

Most ads to return for each location. Each ad is one billable event, so this is also a spending cap. Bien'ici serves at most 2,500 ads per search; to read a bigger market, split it with the price bounds or property types.

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

Apify proxy (automatic datacenter exits) is the default; Bien'ici's search API answered it 200 on 2026-10-09. A refused or timed-out request is retried from a fresh exit address.

## Actor input object example

```json
{
  "locations": [
    "Lyon"
  ],
  "transaction": "rent",
  "propertyTypes": [
    "flat",
    "house"
  ],
  "sort": "newest",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

No description

## `details` (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 = {
    "locations": [
        "Lyon"
    ],
    "propertyTypes": [
        "flat",
        "house"
    ],
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/bienici-listings").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 = {
    "locations": ["Lyon"],
    "propertyTypes": [
        "flat",
        "house",
    ],
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/bienici-listings").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 '{
  "locations": [
    "Lyon"
  ],
  "propertyTypes": [
    "flat",
    "house"
  ],
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/bienici-listings --silent --output-dataset

```

## MCP server setup

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

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/wqso6qWPR5H7i5yFQ/builds/gVWOQI54QjPppbJ8O/openapi.json
