# SeLoger Scraper - Listings With Real Sale Prices (`cycha/seloger-scraper`) Actor

SeLoger property listings for sale or rent in any French city, postcode or département: price, €/m², rooms, DPE, photos, agency, compared with real sale prices nearby (DVF). Only-new mode for alerts. No login.

- **URL**: https://apify.com/cycha/seloger-scraper.md
- **Developed by:** [Ken Digital](https://apify.com/cycha) (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 $1.20 / 1,000 property 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

## SeLoger Scraper - Listings With Real Sale Prices

SeLoger property listings as clean rows, **for sale or for rent, in any French city, postcode or département**: price, €/m², surface, rooms, bedrooms, floor, DPE energy class, year built, photos, full description, agency and publication date. Every sale listing is also compared with **what homes actually sold for nearby**, from the government's DVF register. Turn on **Only new listings** and schedule it for property alerts that never repeat a listing.

> **New name:** this actor is now `cycha/seloger-scraper` (it was `joyouscam35875/seloger-scraper` until 21 October 2026). If an API call or integration stopped working, update the name, or use the actor ID `Wt1UcHhbL47JuryMK`, which never changes.

*Annonces SeLoger à vendre ou à louer, par ville, code postal ou département : prix, €/m², surface, pièces, DPE, photos, agence, comparées aux prix de vente réels (DVF). Mode « nouvelles annonces uniquement » pour des alertes.*

- **Any place:** `Paris`, `75011`, `Lyon`, `Bordeaux`, `33`, `Haute-Savoie`; several searches, one per line.
- **Real filters:** buy or rent, apartment / house / land / parking, price, surface, rooms.
- **Market check included:** `marketPricePerSqm` is the median €/m² actually paid for the same type of home in the same postcode over the last two years, and `priceVsMarket` is this listing's €/m² divided by it (0.85 = 15% below the market). Viagers, bare-ownership sales and auctions list only part of the price: they are marked in `saleType` and get no `priceVsMarket`, so they never pose as bargains.
- **Only new listings** remembers what earlier runs delivered, so scheduled runs return and bill only fresh listings.
- **No login, no account, no proxy setup.**

### Quick start

```json
{
  "location": "Paris\n92",
  "transactionType": "buy",
  "propertyTypes": ["apartment"],
  "maxPrice": 600000,
  "minSurface": 40,
  "maxResults": 500
}
```

**Daily alert:** add `"onlyNewListings": true`, save as a task, schedule it every morning, and connect Slack, email or Google Sheets from the task's Integrations tab.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `location` | string | required | City, postcode or département. One per line for several searches. |
| `transactionType` | string | `buy` | `buy` or `rent`. |
| `propertyTypes` | array | apartment, house | `apartment`, `house`, `land`, `parking`, `other`. |
| `minPrice` / `maxPrice` | integer | | Sale price, or monthly rent. |
| `minSurface` / `maxSurface` | integer | | Living area in m². |
| `minRooms` | integer | | Pièces (T3 = 3). |
| `maxResults` | integer | 100 | Per location. `0` = everything SeLoger returns (up to 3,000). |
| `marketComparison` | boolean | true | Add DVF market prices to sale listings. |
| `onlyNewListings` | boolean | false | Return only listings not delivered by earlier runs of the same searches (one found by two searches is sent once). |

### Output

```json
{
  "listingId": "seloger:268MUDI8TF75",
  "url": "https://www.seloger.com/annonce/achat/auvergne-rhone-alpes/rhone-69/lyon-69000/268MUDI8TF75",
  "title": "Superbe 3 pièces",
  "transactionType": "buy",
  "propertyType": "apartment",
  "price": 189000,
  "pricePerSqm": 2739.13,
  "surface": 69,
  "rooms": 3,
  "bedrooms": 2,
  "floor": "2/5",
  "energyClass": "A",
  "yearBuilt": 2024,
  "newBuild": true,
  "city": "Lyon 8ème arrondissement",
  "postalCode": "69008",
  "district": "Monplaisir",
  "description": "Lyon 8ème : Appartement T3 Neuf...",
  "photos": ["https://..."],
  "sellerType": "agency",
  "agencyName": "Example Immobilier",
  "publishedAt": "2026-10-01T09:12:00Z",
  "marketPricePerSqm": 4310,
  "marketSampleSize": 812,
  "marketScope": "postcode",
  "priceVsMarket": 0.636,
  "searchLocation": "Lyon",
  "scrapedAt": "2026-10-07T10:00:00+00:00"
}
```

Fields SeLoger does not publish for a listing are `null`. Names of private sellers are never exported.

### Pricing

Pay per event: one `result` event per listing row, market comparison included, plus a tiny actor-start fee. With **Only new listings** on, a run with nothing new costs only the start fee.

### Use cases

- **Property alerts** for a city and budget, every morning
- **Investors:** sort by `priceVsMarket` to find listings priced under what homes actually sold for nearby
- **Agencies:** monitor competitors' new mandates, prices and price drops by area
- **Market studies:** asking prices vs. sale prices, €/m² by postcode, DPE mix

### Integrations

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("cycha/seloger-scraper").call(run_input={
    "location": "Bordeaux",
    "propertyTypes": ["apartment"],
    "maxPrice": 300000,
    "onlyNewListings": True,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["price"], row["surface"], row["priceVsMarket"], row["url"])
```

Works with Make, Zapier, n8n, Google Sheets, schedules and webhooks, and as an MCP tool for AI agents.

### FAQ

**How is `priceVsMarket` computed?** From DVF, the public register of every property sale in France: the two latest full years for the département, sales of exactly one apartment or house, median €/m² for the listing's postcode (or its commune or département when the postcode has fewer than 5 sales). It is a first filter, not a valuation.

**Why do I sometimes get fewer listings?** SeLoger protects its site against automated traffic. The actor retries with fresh connections; if SeLoger still refuses, the run succeeds with what it has and the status message says so. Re-running usually works.

**I need Leboncoin, PAP, Bien'ici and Logic-Immo too.** Use the [SeLoger, Leboncoin, Bien'ici, PAP & Logic-Immo Scraper](https://apify.com/cycha/france-real-estate-scraper): same fields, five sites, duplicates removed.

**Is it legal?** The actor reads publicly visible listings. You are responsible for how you use the data and for complying with SeLoger's terms and the GDPR.

### Feedback

Missing a field? Open an issue on the actor's **Issues** tab. If this scraper saved you time, a short review on the Store page helps other people find it.

### Related actors by the same developer

| Actor | What it does |
|---|---|
| [SeLoger, Leboncoin, Bien'ici, PAP & Logic-Immo Scraper](https://apify.com/cycha/france-real-estate-scraper) | French property listings from five sites with real sale prices |
| [Leboncoin Scraper](https://apify.com/cycha/leboncoin-scraper) | Ads from any Leboncoin category, cars included |
| [Zillow Search Scraper](https://apify.com/cycha/zillow-search-scraper) | Every home of a Zillow search, past the 820 limit |

# Actor input Schema

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

City, département number or postcode. One per line for several searches. Examples: Lyon, Bordeaux, 33, 75011, Gironde.

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

Properties for sale or for rent.

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

Apartment, house, land, parking or other.

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

Sale price, or monthly rent when renting.

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

Sale price, or monthly rent when renting.

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

Living area.

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

Living area.

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

Rooms in the French sense: T3 = 3 pièces.

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

Per location. 0 = everything SeLoger returns (up to 3,000).

## `marketComparison` (type: `boolean`):

Adds the median €/m² actually paid nearby in the last two years, from the government's DVF register, and how this listing compares. Sales only.

## `onlyNewListings` (type: `boolean`):

Remember the listings delivered by earlier runs of the same searches and return only listings not delivered before, even when another search of the task found them. You only pay for new listings.

## Actor input object example

```json
{
  "location": "Paris",
  "transactionType": "buy",
  "propertyTypes": [
    "apartment",
    "house"
  ],
  "maxResults": 100,
  "marketComparison": true,
  "onlyNewListings": false
}
```

# Actor output Schema

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

One row per listing, same fields for every site.

# 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 = {
    "location": "Paris"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cycha/seloger-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 = { "location": "Paris" }

# Run the Actor and wait for it to finish
run = client.actor("cycha/seloger-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 '{
  "location": "Paris"
}' |
apify call cycha/seloger-scraper --silent --output-dataset

```

## MCP server setup

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