# Licitor Scraper: French Judicial Real Estate Auctions (`klyde_nsx/licitor-scraper`) Actor

New French judicial real estate auction listings (ventes aux enchères immobilières) and hammer prices from licitor.com, as a clean table. No personal data. Run daily.

- **URL**: https://apify.com/klyde_nsx/licitor-scraper.md
- **Developed by:** [gabriel genevrier](https://apify.com/klyde_nsx) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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

## Licitor Scraper: French Judicial Real Estate Auctions (ventes aux enchères immobilières)

[Version française plus bas](#version-française)

**Get every new French judicial real estate auction (ventes judiciaires, saisie immobilière) and every hammer price (adjudication) from Licitor as a clean, deduplicated table — with no personal data.**

### Who is it for?

- **Property dealers (marchands de biens)** looking for below-market deals before everyone else.
- **Real estate investors** tracking judicial auctions in France for investissement immobilier.
- **Property hunters** watching a few départements for their clients.
- **Real estate tools and data teams** who need a reliable daily feed.
- **AI agents** that need structured, compliant data on ventes aux enchères immobilières.

### Why this Actor

#### 1. New listings only — perfect for daily alerts

Every run delivers **up to `maxResultats` listings you have never received before, for sales still to come** (50 by default). New listings of the last 7 days come first; if there are not enough, the Actor goes further down the list, upcoming sales only — never a sale that already took place. The Actor remembers what it already delivered (per saved search), so you can schedule it daily and plug it into e-mail or Slack alerts without deduplicating anything yourself.

#### 2. Structured auction results for all of France

Hammer prices from court hearings all over France, as structured rows: **hammer price, hearing date, court, outcome** (sold / sale not required), with **price per m²**. Ideal to benchmark a starting price against what similar properties actually sold for.

#### 3. GDPR-compliant by design

No precise address, no names, no phone numbers, no e-mails, no photos — ever. Lawyers, judicial officers and the people whose property is sold never appear in the data. Only facts about the sale: city, département, court, dates, prices, surface, occupancy. Safe to store, share and feed to your tools.

### Output example (real data)

New listing:

```json
{
    "recordType": "new_listing",
    "listingId": "110414",
    "url": "https://www.licitor.com/annonce/11/04/14/vente-aux-encheres/une-maison-d-habitation/la-roche-sur-yon/vendee/110414.html",
    "conditionsPdfUrl": null,
    "publishedAt": "2026-10-21",
    "court": "Tribunal Judiciaire de La Roche-sur-Yon",
    "saleOrganizerType": "court",
    "saleDateTime": "2026-11-23T09:45:00+01:00",
    "daysUntilSale": 32,
    "propertyTitle": "Une maison d'habitation",
    "propertyCategory": "house",
    "city": "La Roche-sur-Yon",
    "departmentCode": "85",
    "departmentName": "Vendée",
    "surfaceM2": 225.6,
    "lotCount": 1,
    "occupancy": "occupied",
    "roomCount": null,
    "startingPriceEur": 70000,
    "pricePerM2Eur": 310,
    "visitDates": [],
    "outcome": "upcoming",
    "hammerPriceEur": null,
    "hammerPricePerM2Eur": null,
    "hearingDate": null,
    "needsReview": false,
    "scrapedAt": "2026-10-22T07:00:00.000Z"
}
```

Auction result:

```json
{
    "recordType": "result",
    "listingId": "109632",
    "url": "https://www.licitor.com/annonce/10/96/32/vente-aux-encheres/un-appartement/paris-15eme/paris/109632.html",
    "court": "Tribunal Judiciaire de Paris",
    "saleDateTime": "2026-10-15T14:00:00+02:00",
    "propertyTitle": "Un appartement",
    "propertyCategory": "apartment",
    "city": "Paris 15ème",
    "departmentCode": "75",
    "surfaceM2": 134.1,
    "roomCount": 5,
    "outcome": "sold",
    "hammerPriceEur": 707000,
    "hammerPricePerM2Eur": 5272,
    "hearingDate": "2026-10-15",
    "needsReview": false
}
```

(Result rows have the same 27 fields; some are shortened here.)

### Fields

| Field                                                             | Description                                                                                               |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `recordType`                                                      | `new_listing` or `result`                                                                                 |
| `listingId`, `url`                                                | Licitor listing number and link                                                                           |
| `conditionsPdfUrl`                                                | Link to the sale conditions (cahier des conditions de vente) when published — link only, never downloaded |
| `publishedAt`                                                     | Publication date                                                                                          |
| `court`, `saleOrganizerType`                                      | Court, or `judicial_officer` when a commissaire de justice runs the sale                                  |
| `saleDateTime`, `daysUntilSale`                                   | Sale date and time (Europe/Paris), days left before the sale                                              |
| `propertyTitle`, `propertyCategory`                               | Short title; `apartment`, `house`, `building`, `commercial`, `land`, `parking`, `other`                   |
| `city`, `departmentCode`, `departmentName`                        | Location, city level only                                                                                 |
| `surfaceM2`, `lotCount`, `roomCount`                              | Surface (Carrez first; total for a multiple lot), number of lots, main rooms when written                 |
| `occupancy`                                                       | `free`, `occupied`, `rented` or `null`, from the listing wording                                          |
| `startingPriceEur`, `pricePerM2Eur`                               | Starting price (mise à prix) and per m²                                                                   |
| `visitDates`                                                      | Visit dates                                                                                               |
| `outcome`, `hammerPriceEur`, `hammerPricePerM2Eur`, `hearingDate` | `upcoming`, `sold`, `not_required` or `null`; hammer price and per m²; hearing date                       |
| `needsReview`                                                     | `true` when a key field could not be read or the result is unusual                                        |
| `scrapedAt`                                                       | Extraction time                                                                                           |

### Input

| Field                          | Default            | Meaning                                                                                   |
| ------------------------------ | ------------------ | ----------------------------------------------------------------------------------------- |
| `mode`                         | `both`             | `new_listings`, `results` or `both`                                                       |
| `departements`                 | empty = all France | Département codes, e.g. `69`, `75`, `2A`, `974`                                           |
| `region`                       | empty              | Shortcut: adds all départements of a region                                               |
| `typesDeBien`                  | empty = all        | Property types                                                                            |
| `miseAPrixMin`, `miseAPrixMax` | empty              | Starting price range (€), new listings                                                    |
| `saleDateFrom`, `saleDateTo`   | empty              | Sale date range (results: hearing date)                                                   |
| `occupancyFilter`              | `any`              | `free_only` keeps properties stated as free                                               |
| `joursResultats`               | 10                 | Results: hearings from the last N days (max 10)                                           |
| `maxResultats`                 | 50                 | Maximum rows per run; in `both` mode, half for each mode (unused share goes to the other) |
| `cleMemoire`                   | `defaut`           | Memory name — one per saved search                                                        |

### Tutorial: daily alerts by e-mail or Slack

1. Open the Actor, set your filters (for example `mode: new_listings`, `region: auvergne-rhone-alpes`, `typesDeBien: ["apartment"]`) and a memory name such as `lyon-apartments`. Click **Save**.
2. Go to **Schedules** → **Create new**, pick this Actor with your saved input and a daily time (e.g. 7:00, Europe/Paris).
3. On the Actor, open **Integrations** and add **Slack** or **E-mail** with the trigger "Run succeeded": you receive the new rows every morning.
4. Use a different memory name for each saved search: each one remembers its own deliveries.

### Pricing

Pay per result: **$0.002 per row ($2 per 1,000 rows)**, plus the default Actor start fee. You only pay for rows delivered; `maxResultats` caps each run, and the run stops cleanly when your spending limit is reached. With new listings only, you never pay twice for the same listing.

### Limits

- **Run it daily.** New listings are spotted in a 7-day window; beyond it, the Actor only fills up to `maxResultats` with upcoming sales never delivered. **After more than 7 days without a run, listings beyond `maxResultats` can be missed.** A past sale is never delivered in `new_listings`.
- **Results cover the last 10 days only** (`joursResultats` ≤ 10). The current day's hearings are skipped (results often not published yet).
- **Hammer prices can still change**: during the 10 days after the hearing, anyone can make an outbid offer (surenchère), leading to a new auction. Treat recent prices as provisional.
- **Unofficial listings**: Licitor marks each listing « Annonce non-officielle - Contenu non certifié ». Always check the original listing on licitor.com and the court documents before deciding.
- In `results` mode the starting price is not available, and département / region filters apply to rows read (the court's hearings are read in full).
- Slow, polite crawling: one page at a time, at least 3 seconds apart, at most 150 pages per mode and per run (about 3–4 minutes for 50 new listings). robots.txt is respected; no proxies, no accounts, no captcha solving.

### FAQ

**Why is there no address?** Because a precise address (or lieu-dit, or cadastral reference) can identify the person whose property is being seized. We keep the city and the département — enough to decide whether a listing is worth opening on licitor.com, where the full listing is available.

**Why no lawyer contact?** Contact details of lawyers and judicial officers are personal data. The listing link takes you to the official contact.

**Will I receive the same listing twice?** No, as long as you keep the same memory name (`cleMemoire`). Use a new name to start over.

**What does `needsReview: true` mean?** A key field could not be read, or the result is unusual (e.g. « carence d'enchères », no bidder). Check the listing on licitor.com.

**Is the PDF of the sale conditions included?** Only its link, when Licitor publishes one and the link contains no name. The PDF itself is never downloaded or read.

***

### Version française

**Toutes les nouvelles ventes aux enchères immobilières judiciaires (ventes judiciaires, saisies immobilières) et tous les prix d'adjudication publiés sur Licitor, en un tableau propre et sans doublon — sans aucune donnée personnelle.**

#### Pour qui ?

- **Marchands de biens** à la recherche d'affaires avant les autres.
- **Investisseurs** qui suivent les ventes judiciaires en France pour leur investissement immobilier.
- **Chasseurs immobiliers** qui surveillent quelques départements pour leurs clients.
- **Outils immobiliers et équipes data** qui ont besoin d'un flux quotidien fiable.
- **Agents IA** qui ont besoin de données structurées et conformes sur les ventes aux enchères immobilières.

#### Pourquoi ce robot

**1. Seulement les nouvelles annonces — idéal pour des alertes quotidiennes.** Chaque lancement livre **jusqu'à `maxResultats` annonces jamais livrées, pour des ventes encore à venir** (50 par défaut). Les annonces des 7 derniers jours passent d'abord ; s'il n'y en a pas assez, le robot remonte la liste, ventes à venir uniquement — jamais une vente déjà passée. Le robot se souvient de ce qu'il a déjà envoyé (par recherche suivie) : programmez-le chaque jour et branchez-le sur vos alertes e-mail ou Slack, sans rien dédoublonner vous-même.

**2. Des résultats d'adjudication structurés pour toute la France.** Les prix d'adjudication des audiences de toute la France, en lignes structurées : **prix, date d'audience, tribunal, résultat** (vendu / vente non requise), avec le **prix au m²**. Idéal pour comparer une mise à prix aux prix réellement obtenus.

**3. Conforme au RGPD par conception.** Aucune adresse précise, aucun nom, aucun téléphone, aucun e-mail, aucune photo — jamais. Les avocats, commissaires de justice et personnes saisies n'apparaissent jamais. Seulement les faits de la vente : ville, département, tribunal, dates, prix, surface, occupation.

#### Données produites

Une ligne par vente, toujours les mêmes 27 champs (voir le tableau et les exemples réels ci-dessus) : numéro et lien de l'annonce, lien du cahier des conditions de vente s'il est publié (jamais téléchargé), tribunal, date et heure de vente, jours restants avant la vente, type de bien, ville, département, surface (loi Carrez en priorité ; total pour un lot multiple), nombre de lots et de pièces, occupation (`free` libre, `occupied` occupé, `rented` loué), mise à prix et prix au m², dates de visite, résultat, prix d'adjudication et prix au m², date d'audience, `needsReview` (à vérifier).

#### Paramètres

| Champ                          | Défaut                 | Rôle                                                                                                                      |
| ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `mode`                         | `both`                 | `new_listings`, `results` ou `both`                                                                                       |
| `departements`                 | vide = toute la France | Codes de département, par ex. `69`, `75`, `2A`, `974`                                                                     |
| `region`                       | vide                   | Raccourci : ajoute tous les départements d'une région                                                                     |
| `typesDeBien`                  | vide = tous            | Types de bien                                                                                                             |
| `miseAPrixMin`, `miseAPrixMax` | vides                  | Fourchette de mise à prix (€), nouvelles annonces                                                                         |
| `saleDateFrom`, `saleDateTo`   | vides                  | Dates de vente (résultats : date d'audience)                                                                              |
| `occupancyFilter`              | `any`                  | `free_only` : biens indiqués libres seulement                                                                             |
| `joursResultats`               | 10                     | Résultats : audiences des N derniers jours (10 au maximum)                                                                |
| `maxResultats`                 | 50                     | Nombre maximal de lignes par lancement ; en mode `both`, moitié pour chaque mode (la part non utilisée revient à l'autre) |
| `cleMemoire`                   | `defaut`               | Nom de la mémoire — un par recherche suivie                                                                               |

#### Tutoriel : alertes quotidiennes par e-mail ou Slack

1. Ouvrez le robot, réglez vos filtres (par ex. `mode: new_listings`, `region: auvergne-rhone-alpes`, `typesDeBien: ["apartment"]`) et un nom de mémoire comme `lyon-appartements`. Cliquez sur **Save**.
2. Allez dans **Schedules** → **Create new**, choisissez ce robot avec vos paramètres enregistrés et une heure quotidienne (par ex. 7 h, Europe/Paris).
3. Sur le robot, ouvrez **Integrations** et ajoutez **Slack** ou **E-mail** avec le déclencheur « Run succeeded » : vous recevez les nouveautés chaque matin.
4. Un nom de mémoire différent par recherche suivie : chacune garde ses propres livraisons.

#### Prix

Paiement au résultat : **0,002 $ par ligne (2 $ les 1 000 lignes)**, plus les frais de démarrage par défaut. Vous ne payez que les lignes livrées ; `maxResultats` plafonne chaque lancement et le robot s'arrête proprement quand votre plafond de dépense est atteint. Avec les nouvelles annonces seulement, vous ne payez jamais deux fois la même annonce.

#### Limites

- **Lancez-le chaque jour.** Les nouveautés sont repérées sur une fenêtre de 7 jours ; au-delà, le robot complète seulement jusqu'à `maxResultats` avec des ventes à venir jamais livrées. **Au-delà de 7 jours sans lancement, les annonces au-delà de `maxResultats` peuvent être manquées.** Une vente passée n'est jamais livrée en `new_listings`.
- **Les résultats se limitent aux 10 derniers jours** (`joursResultats` ≤ 10). Les audiences du jour même sont ignorées (résultats souvent pas encore publiés).
- **Les prix d'adjudication peuvent encore changer** : pendant les 10 jours qui suivent l'audience, une surenchère reste possible et entraîne une nouvelle vente. Considérez les prix récents comme provisoires.
- **Annonces non officielles** : Licitor indique sur chaque fiche « Annonce non-officielle - Contenu non certifié ». Vérifiez toujours la fiche d'origine sur licitor.com et les documents du tribunal avant de décider.
- En mode `results`, la mise à prix n'est pas disponible, et les filtres département / région s'appliquent aux lignes lues (les audiences du tribunal sont lues en entier).
- Collecte lente et polie : une page à la fois, au moins 3 secondes d'intervalle, 150 pages au maximum par mode et par lancement (environ 3 à 4 minutes pour 50 nouvelles annonces). robots.txt est respecté ; ni proxy, ni compte, ni résolution de captcha.

#### FAQ

**Pourquoi pas d'adresse ?** Parce qu'une adresse précise (ou un lieu-dit, ou une référence cadastrale) peut identifier la personne dont le bien est saisi. Nous gardons la ville et le département : assez pour décider si une annonce mérite d'être ouverte sur licitor.com, où la fiche complète est disponible.

**Pourquoi pas les coordonnées de l'avocat ?** Ce sont des données personnelles. Le lien de l'annonce mène aux contacts officiels.

**Vais-je recevoir deux fois la même annonce ?** Non, tant que vous gardez le même nom de mémoire (`cleMemoire`). Changez de nom pour repartir de zéro.

**Que signifie `needsReview: true` ?** Un champ clé n'a pas pu être lu, ou le résultat est inhabituel (par ex. « carence d'enchères », aucun enchérisseur). Vérifiez la fiche sur licitor.com.

**Le PDF du cahier des conditions de vente est-il inclus ?** Seulement son lien, quand Licitor en publie un et que le lien ne contient aucun nom. Le PDF lui-même n'est jamais téléchargé ni lu.

# Actor input Schema

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

What to collect. <b>new_listings</b>: listings published since the last run (first run: last 7 days). <b>results</b>: hammer prices of hearings from the last N days. <b>both</b>: both. / Que collecter. <b>new_listings</b> : annonces publiées depuis le dernier lancement (premier lancement : 7 derniers jours). <b>results</b> : prix d'adjudication des audiences des N derniers jours. <b>both</b> : les deux.

## `departements` (type: `array`):

French département codes, e.g. 69, 75, 2A, 974. Empty = all of France. / Codes de département, par ex. 69, 75, 2A, 974. Vide = toute la France.

## `region` (type: `string`):

Shortcut: adds all départements of a region to the list above. / Raccourci : ajoute tous les départements d'une région à la liste ci-dessus.

## `typesDeBien` (type: `array`):

Keep only these property types. Empty = all. / Ne garder que ces types de bien. Vide = tous.

## `miseAPrixMin` (type: `integer`):

New listings only: minimum starting price in euros. Empty = no minimum. / Nouvelles annonces seulement : mise à prix minimale en euros. Vide = pas de minimum.

## `miseAPrixMax` (type: `integer`):

New listings only: maximum starting price in euros. Empty = no maximum. / Nouvelles annonces seulement : mise à prix maximale en euros. Vide = pas de maximum.

## `saleDateFrom` (type: `string`):

Keep sales on or after this date (results: hearing date). Applied once the listing is open. / Ventes à partir de cette date (résultats : date d'audience). Appliqué une fois la fiche ouverte.

## `saleDateTo` (type: `string`):

Keep sales on or before this date. / Ventes jusqu'à cette date incluse.

## `occupancyFilter` (type: `string`):

<b>free_only</b>: keep only properties stated as free (libre) on the listing; listings that say nothing are dropped. / <b>free_only</b> : ne garder que les biens indiqués libres sur la fiche ; les fiches muettes sont écartées.

## `joursResultats` (type: `integer`):

Results mode: hearings from the last N days (maximum 10). / Mode résultats : audiences des N derniers jours (10 au maximum).

## `maxResultats` (type: `integer`):

Stop after this many rows (you pay per row). / Arrêt après ce nombre de lignes (facturation à la ligne).

## `cleMemoire` (type: `string`):

Name of the memory that remembers what was already delivered. Use a different name for each saved search. Letters, digits, dot, dash, underscore. / Nom de la mémoire des annonces déjà livrées. Un nom différent par recherche suivie. Lettres, chiffres, point, tiret, tiret bas.

## Actor input object example

```json
{
  "mode": "new_listings",
  "departements": [],
  "typesDeBien": [],
  "occupancyFilter": "any",
  "joursResultats": 10,
  "maxResultats": 50,
  "cleMemoire": "defaut"
}
```

# Actor output Schema

## `results` (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 = {
    "mode": "new_listings",
    "maxResultats": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("klyde_nsx/licitor-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 = {
    "mode": "new_listings",
    "maxResultats": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("klyde_nsx/licitor-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 '{
  "mode": "new_listings",
  "maxResultats": 50
}' |
apify call klyde_nsx/licitor-scraper --silent --output-dataset

```

## MCP server setup

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