# Bien'ici Scraper: France Real Estate Ads & DPE (`automation_craft/bienici-scraper`) Actor

Get Bien'ici property ads from any French town, department, region or radius up to 200 km, no login, each search read past the 2,500 ad cap. Rows hold price, price per m2, surface, DPE and GES, district, photos, agency contact. Watch new ads and price changes; pay per ad; JSON, CSV, API.

- **URL**: https://apify.com/automation_craft/bienici-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (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 $2.37 / 1,000 listings

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

### Bien'ici Scraper: France Real Estate Ads & DPE

**Bien'ici scraper** for bienici.com, the French property portal: search flats, houses, land, parking, offices, shops and more for
sale or rent in any town, arrondissement, postal code, department or region of France, or within a radius of up to 200 km around
a town, and get one row per ad with its price, price per m2, surface, rooms, bedrooms, energy class (DPE) and greenhouse gas class
(GES), district and map position, photos, dates and the advertiser. Paste Bien'ici search links or ad links if you have them. No
login, no cookies, no captcha. Every search is read to its end, past the 2,500 ads Bien'ici serves in one order.

Who uses it: estate agents and property hunters watching new listings ("pige immobilière"), investors and analysts comparing
prices per m2 and energy classes by district, proptech and price comparison apps, and teams building lists of French estate
agencies with their phone numbers.

### Quick start

1. Open the **Input** tab and type a place in **Places**, for example `Paris`, `Paris 18e`, `Lyon 3e`, `33160`, `Gironde`,
   `Bretagne` or `France`.
2. Choose buy or rent and the property types, then add filters if you like: price, surface, rooms, bedrooms, land surface, energy
   classes, features (lift, balcony, garden, pool, parking ...), new builds, keywords.
3. Or paste Bien'ici search links (`https://www.bienici.com/recherche/achat/paris-75000/appartement`) into **Bien'ici search
   links**, or ad links and ids into **Ad links or ids**.
4. Set **Maximum rows** and click **Start**. Download the rows as JSON, CSV or Excel, or read them through the Apify API.

To watch a search for new ads, give the run a **Monitor name** and schedule it: each later run delivers only the ads it never
delivered before, and with **Track price changes and removals** also the ads whose price moved and the ads that left the market.

### What you get

One row per ad (`type: "listing"`), one coverage row per search (`type: "search"`), free status rows for anything that could not be
delivered (`type: "status"`), in a monitor with change tracking a row per ad that left the market (`type: "removed"`), and a run
summary (`type: "summary"`).

| Field | What it is | Filled on (measured on 3,117 ads of 7 searches, 2026-10-18: Paris flats for sale, Gers houses, Lyon rentals, Bordeaux new builds, Marseille parking and premises, Gironde land, Paris offices to let) |
|---|---|---|
| `id`, `url`, `reference` | Bien'ici's ad id, the ad's link, the advertiser's own reference | id and url every ad, reference 3,078 (98.7 percent) |
| `transaction`, `propertyType`, `propertySubtype`, `isNewBuild` | buy or rent, Bien'ici's property type (flat, house, terrain, parking, programme ...), new build | every ad |
| `title`, `description` | the ad's title and its whole description as plain text | title 3,017 (96.8 percent), description 3,116 (99.97 percent) |
| `price`, `pricePerSqm`, `priceWithoutFees`, `agencyFeePercentage`, `feesChargedTo` | price in euros (the monthly rent for rentals), price per m2 (Bien'ici's own, else price over surface), fees | price 3,114 (99.9 percent), price per m2 3,021 (96.9 percent) |
| `charges`, `safetyDeposit`, `rentWithoutCharges`, `isSubjectToRentControl`, `maxReferenceRent` | rental figures | charges 863 (27.7 percent), deposit 692 (22.2 percent) |
| `surface`, `landSurface`, `rooms`, `bedrooms`, `bathrooms`, `showerRooms` | living surface and land in m2, rooms (pièces), bedrooms, bathrooms | surface 2,548 (81.7 percent), land 971 (31.2 percent), rooms 1,674 (53.7 percent), bedrooms 1,401 (44.9 percent); parking and land carry none |
| `floor`, `floorsInBuilding`, `yearBuilt`, `heating`, `exposure` | floor, floors of the building, year built, heating, exposure | floor 1,148 (36.8 percent), year built 934 (30.0 percent), heating 1,371 (44.0 percent) |
| `energyClass`, `energyValue`, `ghgClass`, `ghgValue`, `energyCostMin`, `energyCostMax` | DPE and GES letters and values, the yearly energy cost range | DPE letter 1,948 (62.5 percent), GES letter 1,931 (62.0 percent), DPE value 1,448, GES value 1,438 |
| `amenities`, `balconies`, `terraces`, `parkingPlaces`, `cellars`, `opticalFiberStatus` | lift, balcony, terrace, garden, pool, parking, cellar, fibre and the other features the ad shows | as the ad shows them |
| `isInCondominium`, `condominiumLots`, `annualCondominiumFees`, `condominiumInProcedure` | co-ownership data | as the ad shows them |
| `city`, `postalCode`, `departmentCode`, `region`, `district`, `inseeCode` | where the property is, with Bien'ici's district (quartier) | every ad (postal code 3,112) |
| `latitude`, `longitude`, `locationPrecision`, `locationRadiusMeters` | Bien'ici's map position and how precise it is | exact on 568 ads (18.2 percent), a blurred circle of 50 to 1,000 m on 2,261 (72.5 percent), the town or arrondissement on 284 |
| `distanceKm` | with a radius: the distance from the centre of the place | radius searches |
| `photos`, `photoCount`, `virtualTours`, `has3DTour` | every photo link, how many, video and 3D tours | photos 3,105 (99.6 percent), virtual tours 458 (14.7 percent) |
| `publishedAt`, `publicationDateHidden`, `updatedAt`, `daysOnMarket` | first published, whether Bien'ici hides that date, last modified, whole days on the market | updated every ad; published 2,316 (74.3 percent): Bien'ici hides the date of the other 801 (`publishedAt` null, `publicationDateHidden` true) |
| `priceHasDecreased`, `onTheMarket`, `isExclusiveMandate`, `isBienIciExclusive` | Bien'ici's price drop flag, market status, exclusive mandate, exclusive to Bien'ici | every ad |
| `advertiserType`, `isIndividualAgent`, `advertiserName`, `advertiserId` | agency, mandatary (an independent network agent), builder, broker, developer or network; the advertiser's name and id | type every ad (all are professionals); Bien'ici's search answer names the advertiser on 1,466 ads (47.0 percent; left empty for an independent agent with personal data off), and with **Agency contact details** on the agency's name comes from its contact record |
| `programmeLots` | a new build programme's lots (each its own ad id) | programmes |
| `priceMax`, `surfaceMax`, `roomsMax`, `pricePerSqmMax` | a new build programme's dearest, largest and roomiest lot (its `price`, `surface` and `rooms` are the cheapest, smallest and fewest); a price filter keeps a programme whose range overlaps it, as Bien'ici does | programmes |
| `contact` | with **Agency contact details** on: `agencyName`, `phone`, `street`, `postalCode`, `city`, `rcs`, `agencyId`, `website`, `hasEmail`, `affiliation` (FNAIM, SNPI), `contactName` (with personal data on) | every row read with it |
| `generatedTitle` | Bien'ici's own title of the ad (from its record) | rows whose record was read |
| `change` | on a monitor's change row: `priceChanged` or `reappeared`, the previous price, the change in euros and percent, the price history | change rows |
| `raw` | with **Raw Bien'ici data** on: Bien'ici's own ad object, every field it serves | with the switch on |
| `searchKind`, `searchLabel`, `searchPage`, `rank`, `monitorName`, `scrapedAt` | which search, page and rank delivered the row | every row |

A sample row (shortened; Agency contact details off, personal data off):

```json
{
  "type": "listing",
  "id": "guy-hoquet-18-GT1027-116",
  "url": "https://www.bienici.com/annonce/guy-hoquet-18-GT1027-116",
  "title": "Appartement",
  "description": "Guy Hoquet Paris 17 Épinettes vous propose en exclusivité ce charmant appartement de 3 pièces, situé au cœur du quartier recherché des Épinettes. ...",
  "transaction": "buy", "propertyType": "flat", "isNewBuild": false,
  "price": 595000, "priceWithoutFees": 567000, "pricePerSqm": 9230.02, "agencyFeePercentage": 4.94, "feesChargedTo": "purchaser",
  "surface": 61.43, "rooms": 3, "bedrooms": 2, "floor": 1, "floorsInBuilding": 7, "yearBuilt": 1870, "heating": "électrique individuel",
  "amenities": ["door_code", "optical_fiber"],
  "energyClass": "D", "energyValue": 215, "ghgClass": "B", "ghgValue": 8,
  "city": "Paris 17e", "postalCode": "75017", "departmentCode": "75", "region": "Île-de-France", "district": "La Fourche - Guy Moquet",
  "latitude": 48.89177267407265, "longitude": 2.3230022497389737, "locationPrecision": "area", "locationRadiusMeters": 50,
  "photoCount": 9,
  "publishedAt": "2026-10-17T19:15:33.925Z", "publicationDateHidden": false, "updatedAt": "2026-10-17T19:36:05.647Z",
  "onTheMarket": true, "isExclusiveMandate": true, "priceHasDecreased": false,
  "advertiserType": "agency", "isIndividualAgent": false, "advertiserName": "Guy Hoquet PARIS 17 EPINETTES",
  "searchKind": "place", "searchLabel": "place Paris"
}
```

The coverage row of each search says how many ads Bien'ici holds for it (`adsOnBienici`), how many were seen and delivered, how many
were left out by a filter (`filteredOut`, `filteredOutBy`), already delivered or known to the monitor, how many price bands were
read past the first 2,500 (`priceBands`), whether the search was read to its end (`complete`) and why it stopped (`stoppedBy`).
From a real run (Gironde, land for sale):

```json
{ "type": "search", "searchLabel": "place Gironde", "placeLabel": "Gironde (33)", "adsOnBienici": 3265, "pagesRead": 15,
  "adsSeen": 3265, "adsDelivered": 3265, "filteredOut": 0, "priceBands": 3, "complete": true, "stoppedBy": "end" }
```

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

You pay per event, with Apify's store discounts by plan:

| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| Listing (one ad row) | $2.85 per 1,000 | $2.66 per 1,000 | $2.52 per 1,000 | $2.37 per 1,000 |
| Actor start (once per run) | $0.005 | $0.005 | $0.005 | $0.005 |

Platinum and Diamond plans pay the Gold price. The Actor start is a flat fee per run, with no plan discount.

The Store pricing card shows these prices per 1,000 events: "$2.37 / 1,000" on the Listing row means one ad row costs $0.00237 on
the Gold plan (about a quarter of a cent).

- **Agency contact details** and **Raw Bien'ici data** cost nothing extra: they are part of the Listing row.
- In a monitor with change tracking, a price change row, a reappeared row and a removed row are each billed as one Listing.
- Never billed: ads left out by your filters, ads already delivered in the run, ads a monitor already knows, ad links or ids
  Bien'ici no longer has, places that match no place or several, invalid inputs, coverage rows, status rows and the summary.
- Example on the Bronze plan: 1,000 ads cost $0.005 (start) + 1,000 listings ($2.66) = $2.665. On the Free plan the same run costs
  $2.855, on the Gold plan $2.375.
- Example of a daily monitor run (Gold) that finds 40 new ads: start ($0.005) + 40 listings ($0.0948) = about $0.10.
- A run that delivers nothing (a place Bien'ici does not know, a filter no ad passes) pays only the start: $0.005.

### Input

| Setting | What it does |
|---|---|
| `places` | One search per place: towns (`Bordeaux`), Paris, Lyon and Marseille arrondissements (`Paris 18e`, `Lyon 3e`), postal codes (`33160`), departments (`Gironde`, `33`, `2A`), the 13 regions of mainland France (`Bretagne`, `Occitanie`) and `France`, resolved through Bien'ici's own place search. A name that matches several places (`Saint-Denis`) is a free row naming the candidates; add the department or postal code (`Saint-Denis (93)`). |
| `radiusKm` | 1 to 200: search around the centre of each place instead of inside it; each row carries `distanceKm`. Not for a region or France. |
| `transaction`, `propertyTypes`, `newBuild`, `marketStatus` | Buy or rent; apartment, house, parking, land, loft, shop, commercial premises, office, castle, building, townhouse, other; new builds included, only or left out; ads on the market (default) or Bien'ici's own list of ads that left the market. |
| `minPrice` ... `maxLandSurface` | Price, surface, rooms, bedrooms and land surface ranges, sent to Bien'ici and checked again on every row. |
| `energyClasses`, `features`, `lifeAnnuity`, `bareOwnership` | DPE letters A to G; 38 of Bien'ici's advanced filters (lift, balcony, terrace, cellar, parking, garden, pool, fireplace, caretaker, duplex, top or ground floor, disabled access, optical fibre, EV charging, furnished, flatsharing, exclusive mandate, 3D tour, photos, student, senior or tourism residence, Denormandie eligible, house to build ...); life annuity (viager) and bare ownership (nue-propriété) sales included, only or left out. |
| `minPricePerSqm`, `maxPricePerSqm`, `ghgClasses`, `minFloor`, `maxFloor`, `minYearBuilt`, `maxYearBuilt`, `minBathrooms` | Filters Bien'ici does not apply itself: checked on every row; an ad without the field is left out, free. |
| `advertiserTypes`, `priceDropOnly`, `withVirtualTourOnly` | Agency, network agent, developer, builder, broker or network; only ads Bien'ici marks as lowered in price; only ads with a video or 3D tour. |
| `keywords`, `excludeKeywords` | Up to 10 words each that the title or description must contain, or must not contain, as whole words, any case, accents ignored (`piscine`, `vue mer`). |
| `postedWithinDays` or `postedWithinHours`, `minDaysOnMarket` | Only ads published in the last N days or hours (read newest first); only ads on the market for at least N days. Ads whose date Bien'ici hides pass neither. |
| `excludeAdIds` | Up to 10,000 ad ids or links you already have, skipped free. |
| `sort` | 12 of Bien'ici's own orders: newest or oldest first, last updated, relevance, price, price per m2, surface or rooms, each way. Default newest first. |
| `searchUrls` | Up to 100 Bien'ici search links, read into Bien'ici's filters in code (never loaded as pages). A link with a drawn area, a travel time zone or a parameter this Actor does not read is a free row. |
| `adUrls` | Up to 5,000 ad links or ids (`ag942551-554736311`), each read from Bien'ici's own record of the ad and delivered as given, also when it left the market. |
| `maxItems`, `maxItemsPerSearch`, `maxPagesPerSearch` | Caps per run (default 100), per search, and per search in requests. |
| `includeDetails`, `includeRawData`, `includePersonalData` | Agency contact details, Bien'ici's own ad object, and the personal data switch (below). |
| `monitorName`, `monitorBaseline`, `trackChanges` | The monitor (below). |
| `failIfIncomplete`, `requestDelayMs`, `maxRetries`, `proxyConfiguration` | Fail the run when a search could not be read to its end; a pause between requests; retries per request (default 3); Apify's datacenter proxy by default (included in the price), the RESIDENTIAL group, or your own proxy links. |

A run takes up to 100 places and search links together. The search filters are sent to Bien'ici and checked again on every row
before it is billed; a row that does not match is left out free and counted on the coverage row.

#### Every search to its end

Bien'ici serves the first 2,500 ads of a search in one order. This Actor reads them, then reads the rest of the search in price
bands of about 2,000 ads each, in your order within each band, then (when you set no price range) the ads without a price,
skipping every ad it has already seen, so every ad of the search is read once. Measured on 2026-10-18: Gironde land for sale, 3,265 ads on Bien'ici, 3,265 delivered in
one run (15 pages, 3 price bands, no repeat). The coverage row says when a search was read past the first 2,500 and whether it is
complete.

#### Agency contact details

With **Agency contact details** on, each row's `contact` comes from the ad's own record: the agency or network name, phone,
address, RCS number, agency id, website and professional body (FNAIM, SNPI), plus Bien'ici's generated title. One extra request per
row, at no extra charge. Bien'ici shows no e-mail address: `hasEmail` only says whether the advertiser has one.

#### Monitor: new ads, price changes and removals

Give the run a **Monitor name** and schedule it. Each run reads, last updated first, every ad modified since its last complete run
(less 6 hours of margin; a first run reads the last 24 hours, or every current ad with **First run delivers every current ad**)
and delivers only the ads it never delivered before; the ads it knows are free. With **Track price changes and removals**, an ad it
delivered before comes back as a change row when its price moved (`priceChanged`, with the previous price, the change in euros and
percent and the price history) or when it returns after a removal (`reappeared`), and an ad that Bien'ici lists as no longer on the
market comes as a `removed` row. Each such row is billed as Listing. One monitor name belongs to one set of settings; a monitor
takes no ad links, no sort and no posted window, and remembers up to 50,000 ads.

#### Personal data

Every advertiser on Bien'ici is a professional, but some are individuals: independent network agents (mandataires) publish under
their own name, and an agency can name one of its agents as the contact. With **Include personal data** off (the default), the
fields that name or reach such a person are left empty: an individual agent's name, phone, street and RCS number, an agency's named
agent, an individual agent's account ids (advertiser id, agency id, the raw object's account ids: Bien'ici builds some from the
agent's e-mail address), and any id holding or spelling an e-mail address. Titles, descriptions and every other text are delivered
exactly as Bien'ici serves them, with the switch on or off: an ad's text can name its agent or give a phone number. An agency's
name, phone, address, RCS number and website are business data and always delivered. You are responsible for a lawful use of
personal data, GDPR included.

### What this Actor does NOT do

- **No private sellers.** Every ad on Bien'ici is a professional's (agency, network agent, builder, broker, developer, network).
- **No street address of the property.** Bien'ici shows it to no public reader; the row carries Bien'ici's own position with its precision (exact
  on 18 percent of ads, a blurred circle of 50 to 1,000 m on most).
- **No e-mail addresses** in the contact: Bien'ici shows none, only whether one exists. (Some account ids Bien'ici builds from an
  e-mail address: empty with personal data off, delivered as Bien'ici gives them with it on.)
- **No hidden publication dates.** Bien'ici hides the publication date of about a quarter of its ads; those rows carry
  `publishedAt` null and `publicationDateHidden` true (the modification date is real), and they never pass a posted window.
- **No sold prices and no other portals.** Only Bien'ici's own ads; ads that left the market carry their last asking price. No
  DVF sales records, no ADEME energy records.
- **No drawn areas or travel time zones** from search links; give places or a radius instead.
- **No login and no account data**: saved searches, alerts and messages are never read.
- Bien'ici's answers can be up to an hour old in its cache, so a monitor sees a new ad up to about an hour after it is published.
- One request at a time, at most 4 a second. An ad's own record (about half a second each) is read only with **Agency contact
  details** on. The default run timeout is one hour; raise it in the run options for very large searches. `maxItems` defaults to
  100\.
- A run stops when about USD 0.0006 to 0.0016 of its work has delivered no paid row (pages whose ads were all filtered out, slow
  or refused answers from Bien'ici; the higher figure while a search is still finding its places and first page, or after a stuck
  connection), with a status row saying so: run it again, or narrow the search.
- **No property tax** (taxe fonciere): Bien'ici gives none, in its search answers or in an ad's record.

### API examples

Run it and get the rows in one call (replace `YOUR_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~bienici-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"places": ["Bordeaux"], "radiusKm": 10, "propertyTypes": ["house"], "maxPrice": 500000, "energyClasses": ["A", "B", "C"], "maxItems": 200}'
```

Node.js:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/bienici-scraper').call({ places: ['Lyon 3e'], transaction: 'rent', monitorName: 'lyon 3 rentals', trackChanges: true, maxItems: 500 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((x) => x.type === 'listing'));
```

Python:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/bienici-scraper").call(run_input={"adUrls": ["ag942551-554736311"], "includeDetails": True})
ads = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "listing"]
```

### FAQ

#### How can I scrape Bien'ici listings?

Type a town, postal code, department or region (or paste a Bien'ici search link), set a maximum and start the run: no code, no
login and no proxy setup. The rows come out as JSON, CSV or Excel, or through the Apify API.

#### Is there a Bien'ici API for property ads?

Bien'ici documents no public API for its listings. This Actor works as one: call it through the Apify API with places, filters,
search links or ad ids and read the rows back as JSON.

#### How many ads can I get from one Bien'ici search?

All of them, up to your `maxItems` (100 by default) and the run's timeout. Bien'ici serves 2,500 ads of one search in one order;
this Actor reads the rest in price bands, every ad once (Gironde land for sale: 3,265 of 3,265 in one run), and the search's
coverage row says how many ads Bien'ici holds and how many were delivered.

#### Can I get the agency's phone number?

Yes: turn on **Agency contact details** (no extra charge) and each row carries the agency's name, phone, address, RCS number,
website and agency id from the ad's own record. An independent network agent's own name, phone, street and RCS number come in
those fields only with **Include personal data** on (an ad's own texts are delivered as Bien'ici serves them, either way), and the
contact carries no e-mail address (the row says only whether one exists).

#### Is it legal to scrape Bien'ici?

This Actor reads only what Bien'ici shows any visitor, without logging in and with no captcha. Bien'ici's terms forbid automated
extraction for commercial ends it has not authorised and that harm it, and Bien'ici has gone to court as the producer of its ad
database against an app that reused its ads, so you are responsible for a lawful use of the data, and for the GDPR on any personal
data, which is why individual agents' data is off by default.

#### Why does this Actor run with limited permissions?

It needs nothing more: it writes only to its own run's dataset and key-value store, and a monitor keeps its memory in a named
key-value store it creates itself. Limited permissions keep your other Apify data out of its reach.

### Changelog

- 0.1 (2026-10-18): first release: searches by place, region, France and radius with Bien'ici's filters, search links and ad
  links; every search read past the 2,500 ad cap in price bands; filters checked on every row; agency contact details; monitor with
  price changes, reappearances and removals; individual agents' data behind the personal data switch.
- 0.2 (2026-10-19): texts are never masked: titles, descriptions and the raw object's texts are delivered exactly as Bien'ici
  serves them, with personal data on or off; the switch governs only the fields that name or reach a private person (an individual agent's name, phone, street,
  RCS and account ids, an agency's named agent, any id holding or spelling an e-mail address). An ad's
  record is read only with Agency contact details on, so runs with personal data off are faster.

### More data tools by Automation Craft

- [Leboncoin Scraper: Ads, Prices, Real Estate & Cars](https://apify.com/automation_craft/leboncoin-scraper)
- [Kleinanzeigen Scraper & API: Ads, Prices, Places](https://apify.com/automation_craft/kleinanzeigen-scraper)
- [Mobile.de Scraper: Cars, Prices, Dealers & Ratings](https://apify.com/automation_craft/mobile-de-scraper)
- [AutoScout24 Scraper: EU Car Listings & Prices](https://apify.com/automation_craft/autoscout24-scraper)
- [Facebook Marketplace Scraper with Sold Tracker](https://apify.com/automation_craft/facebook-marketplace-scraper)
- [Craigslist Scraper: Listings, Prices & Alerts](https://apify.com/automation_craft/craigslist-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/bienici-scraper/changelog.md

# Actor input Schema

## `places` (type: `array`):

Towns, Paris, Lyon and Marseille arrondissements, departments, postal codes, department numbers, regions or France, as on Bien'ici: Paris, Paris 18e, Lyon 3e, Bordeaux, Gironde, 33160, 75018, 33 (a department number), 2A, Bretagne, Occitanie, France. A name must match exactly one Bien'ici place: when several share it (Saint-Denis), add the department number or the postal code, Saint-Denis (93) or Saint-Denis 93200. A name that matches none or several gives a free row with the candidates. A region name searches all its departments; a town that shares a region's name needs its department (Bretagne (36)).

## `radiusKm` (type: `integer`):

Search around the centre of each place instead of inside it: every ad whose position (the exact one, or the centre of the circle Bien'ici blurs it into) lies within this many kilometres of the centre of the place's map box, with its distance in distanceKm. 1 to 200. Not for a region or France.

## `searchUrls` (type: `array`):

Search links copied from bienici.com (https://www.bienici.com/recherche/achat/paris-75000/appartement/3-pieces-et-plus?prix-max=600000). The link is read into Bien'ici's own filters in this Actor (never loaded as a page) and searched to its end, with its sort unless you set one below. A link with a parameter this Actor does not read, a drawn area or a travel time zone is refused with a free row. Up to 100.

## `adUrls` (type: `array`):

Ads to read directly: bienici.com ad links (https://www.bienici.com/annonce/...) or Bien'ici ad ids (ag942551-554736311). Each is read from Bien'ici's own record of the ad and delivered as given, also when it is no longer on the market (onTheMarket false). An id Bien'ici does not have is a free row. Up to 5,000.

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

Ads for sale or for rent. Default buy.

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

Default apartment and house. New build programmes are delivered with apartments and houses (propertyType programme, with their lots).

## `newBuild` (type: `string`):

Default include.

## `marketStatus` (type: `string`):

Bien'ici keeps ads that left the market and lists them on their own (each with its last price and the date it changed). Default on the market.

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

The lowest price, in euros (the monthly rent for rentals).

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

The highest price, in euros (the monthly rent for rentals).

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

The smallest living surface in square metres.

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

The largest living surface in square metres.

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

The fewest rooms.

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

The most rooms.

## `minBedrooms` (type: `integer`):

The fewest bedrooms.

## `maxBedrooms` (type: `integer`):

The most bedrooms.

## `minLandSurface` (type: `integer`):

The smallest garden or land surface in square metres (Bien'ici reads the garden surface, else the land surface).

## `maxLandSurface` (type: `integer`):

The largest garden or land surface in square metres.

## `energyClasses` (type: `array`):

Only ads with one of these energy performance classes (DPE). An ad without a DPE class is left out, free.

## `features` (type: `array`):

Only ads with every one of these features, as Bien'ici applies them (its advanced search). A row whose own fields contradict a feature is left out, free; a row that does not show the field is kept as Bien'ici returned it.

## `lifeAnnuity` (type: `string`):

Default include.

## `bareOwnership` (type: `string`):

Default include.

## `minPricePerSqm` (type: `integer`):

The lowest price per square metre (Bien'ici's own figure, else the price divided by the surface). An ad without one is left out, free.

## `maxPricePerSqm` (type: `integer`):

The highest price per square metre. An ad without one is left out, free.

## `ghgClasses` (type: `array`):

Only ads with one of these greenhouse gas classes (GES). An ad without one is left out, free.

## `minFloor` (type: `integer`):

The lowest floor (0 is the ground floor). An ad without a floor is left out, free.

## `maxFloor` (type: `integer`):

The highest floor. An ad without a floor is left out, free.

## `minYearBuilt` (type: `integer`):

The earliest year of construction. An ad without one is left out, free.

## `maxYearBuilt` (type: `integer`):

The latest year of construction. An ad without one is left out, free.

## `minBathrooms` (type: `integer`):

The fewest bathrooms and shower rooms together. An ad that shows neither is left out, free.

## `advertiserTypes` (type: `array`):

Only ads of these kinds of advertiser. Every advertiser on Bien'ici is a professional.

## `priceDropOnly` (type: `boolean`):

Only ads whose price Bien'ici marks as lowered (priceHasDecreased).

## `withVirtualTourOnly` (type: `boolean`):

Only ads with a video or 3D tour.

## `keywords` (type: `array`):

Words every delivered ad's title or description must contain, as whole words, any case, accents ignored (piscine, vue mer, sans vis-a-vis). Up to 10, each up to 60 characters.

## `excludeKeywords` (type: `array`):

Ads whose title or description contains any of these words (the same matching as keywords) are left out, free. Up to 10.

## `postedWithinDays` (type: `integer`):

Only ads published in the last N days. The search is read newest first and stops at the first ad older than that. Bien'ici hides the publication date of some ads (publicationDateHidden): those never pass this filter (a monitor catches every new ad).

## `postedWithinHours` (type: `integer`):

Only ads published in the last N hours (instead of days), read the same way. Not with postedWithinDays.

## `minDaysOnMarket` (type: `integer`):

Only ads published at least N days ago (ads whose date Bien'ici hides are left out). Each row carries daysOnMarket.

## `excludeAdIds` (type: `array`):

Bien'ici ad ids or links you already have; they are skipped, free. Up to 10,000.

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

The order of a search, Bien'ici's own. Newest and oldest first sort on the publication date; the ads whose date Bien'ici hides come last (newest first) or first (oldest first). Past the first 2,500 ads of one order, the rest of a search is read in price bands, each in this order. A pasted link keeps its own sort unless you set one here. Default newest first.

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

The most paid rows the run delivers (ad rows, and a monitor's price change and removed rows, together). Default 100.

## `maxItemsPerSearch` (type: `integer`):

The most rows one place or link delivers.

## `maxPagesPerSearch` (type: `integer`):

The most requests one search makes (results pages of up to 500 ads, and one call per price band).

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

Read each delivered ad's own record and add the advertiser's contact: agency or network name, phone, address, RCS number, agency id, website, professional body (FNAIM, SNPI) and Bien'ici's generated title. One extra call per row, included in the Listing price.

## `includeRawData` (type: `boolean`):

Add Bien'ici's own ad object as the search answered it (every field it serves, in Bien'ici's names, its texts as served) under raw.

## `includePersonalData` (type: `boolean`):

Off by default. Some advertisers are individuals: network agents (mandataires) publish under their own name, and an agency can name one of its agents as the contact. On: the agent's name (contact.contactName, and the advertiser name of a network agent), an independent agent's own phone, street and RCS number, an independent agent's account ids (advertiserId, contact.agencyId, the raw account ids) and any id holding or spelling an e-mail address are delivered as Bien'ici shows them logged out. Off: those fields are empty. Titles, descriptions and every other text are delivered as Bien'ici serves them either way: a text can name the agent or give a phone number. You are responsible for using personal data lawfully (GDPR included).

## `monitorName` (type: `string`):

A short name of your choice (letters, digits, spaces and . \_ , - : # ( ), up to 60 characters). One name belongs to one set of settings.

## `monitorBaseline` (type: `boolean`):

With a monitor: its first run delivers every ad of its searches (the stock it starts from) instead of the ads modified in the last 24 hours. Every row is billed as Listing.

## `trackChanges` (type: `boolean`):

With a monitor: an ad it delivered before whose price changed is delivered again with the previous price, the change in euros and percent and the price history; an ad Bien'ici lists as no longer on the market is a removed row; an ad that comes back after a removal is delivered as reappeared. Each such row is billed as Listing.

## `requestDelayMs` (type: `integer`):

Wait at least this long between two requests to Bien'ici (this Actor never sends more than 4 a second). 0 to 10,000.

## `maxRetries` (type: `integer`):

How many times a failed request is asked again (default 3). 0 to 6.

## `failIfIncomplete` (type: `boolean`):

Mark the run failed when a search or link could not be read to its end for a reason other than your own limits. The rows delivered stay.

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

Apify's datacenter proxy by default, included in the price: Bien'ici answers it on every exit. The RESIDENTIAL group (France unless you choose a country) is accepted too, and so are your own proxy links (http://user:password@host:port, the password 12 characters or more with letters and digits, no space).

## Actor input object example

```json
{
  "places": [
    "Paris"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (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 = {
    "places": [
        "Paris"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/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 = {
    "places": ["Paris"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/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 '{
  "places": [
    "Paris"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call automation_craft/bienici-scraper --silent --output-dataset

```

## MCP server setup

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