# Leboncoin Scraper: France Classified Ads & Prices (`reventadata/leboncoin-scraper`) Actor

Scrape leboncoin.fr search results by keyword, category number, price range and sort order. Rows have title, price in EUR, category, images, ad attributes, city, postal code, coordinates, seller name and type, SIREN of professional sellers and dates. Unofficial.

- **URL**: https://apify.com/reventadata/leboncoin-scraper.md
- **Developed by:** [reventadata](https://apify.com/reventadata) (community)
- **Categories:** E-commerce, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Leboncoin Scraper

Search leboncoin.fr, the French classifieds site, and get the ads as structured rows (JSON, CSV or Excel): one search per keyword, optionally narrowed by category number, price range and sort order. By reventadata. Unofficial: not affiliated with Leboncoin.

### What you get

For every ad the search lists: id, title, price (euros), category, up to all image URLs, the ad's attributes (condition, model, storage and so on, as shown on the site), city, postal code, department, region, latitude and longitude, the public seller name and type (private or professional), the SIREN of professional sellers, whether the seller has a phone number on the ad, whether the ad is promoted, and its publication, expiry and index dates.

### Input

| Field | Meaning |
|---|---|
| `searchQueries` | Keywords, one search each. Required. |
| `category` | Optional leboncoin category number (the `category=` value in a search URL, for example `17` for phones). |
| `sort` | `relevance` (default) or `newest`. With `newest`, boosted (paid) ads appear among the results in the order the site returns them, by their `indexedAt` time rather than `firstPublishedAt`; `isBoosted` marks them. |
| `minPrice`, `maxPrice` | Optional price limits in euros. |
| `maxItems` | Cap on rows across all queries. |
| `maxPages` | Pages per query, 35 ads each. The site serves at most 100 pages per search, so 3,500 ads per query. |

Example:

```json
{"searchQueries": ["iphone"], "category": "17", "sort": "newest", "minPrice": 100, "maxPrice": 300, "maxItems": 70, "maxPages": 2}
```

### Sample row

Generated from a real row of a local run on 2026-11-07 (the `imageUrls`, `attributes`, `expiresAt` and `searchUrl` fields of the same row are left out here for length):

```json
{
  "listId": 3304443255,
  "url": "https://www.leboncoin.fr/ad/telephones_objets_connectes/3304443255",
  "title": "IPhone X Blanc 64GO",
  "price": 115,
  "priceCents": 11500,
  "currency": "EUR",
  "categoryId": "17",
  "categoryName": "Téléphones & Objets connectés",
  "adType": "offer",
  "status": "active",
  "imageCount": 5,
  "city": "Rennes",
  "zipcode": "35000",
  "department": "Ille-et-Vilaine",
  "region": "Bretagne",
  "latitude": 48.108,
  "longitude": -1.684,
  "ownerName": "Mathéo",
  "ownerType": "private",
  "ownerSiren": null,
  "hasPhone": false,
  "isBoosted": false,
  "firstPublishedAt": "2026-11-07 20:19:12",
  "indexedAt": "2026-11-07 20:19:12",
  "matchedQuery": "iphone"
}
```

### Pricing

Pay per event: a small fee when a run starts and a fee for every ad row pushed to the dataset. A run stops cleanly when your maximum charge is reached. For current pricing and details, see the Store page.

### Limits

- The ad description and the phone number are not in the search results and are not returned. `hasPhone` only says whether the ad has a number.
- A search shows at most 3,500 ads (100 pages of 35).
- Promoted ads repeat across pages; each ad is returned once.
- Regions and departments cannot be selected; use the keyword, category and price.
- A search with no match ends successfully with a message saying so. A run that the site blocks ends as failed.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search on leboncoin.fr, one search per entry (for example "iphone" or "velo electrique"). Required.

## `category` (type: `string`):

Optional. Leboncoin category number, the value of category= in a leboncoin.fr search URL (for example 17 for phones and connected devices). Leave empty to search every category.

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

Relevance (the site default) or newest first.

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

Optional. Ads below this price, or with no price, are dropped. When both minimum and maximum are set, the site filters by price too.

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

Optional. Ads above this price, or with no price, are dropped. When both minimum and maximum are set, the site filters by price too.

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

Hard cap on rows pushed across all queries.

## `maxPages` (type: `integer`):

Cap on result pages fetched per query (35 ads each, 100 pages at most, so 3,500 ads per query). Each page is one paid unblocking request on the Actor's side and takes about 25 seconds.

## Actor input object example

```json
{
  "searchQueries": [
    "iphone"
  ],
  "sort": "relevance",
  "maxItems": 10,
  "maxPages": 1
}
```

# Actor output Schema

## `dataset` (type: `string`):

Items scraped from the target website.

# 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 = {
    "searchQueries": [
        "iphone"
    ],
    "maxItems": 10,
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("reventadata/leboncoin-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 = {
    "searchQueries": ["iphone"],
    "maxItems": 10,
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("reventadata/leboncoin-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 '{
  "searchQueries": [
    "iphone"
  ],
  "maxItems": 10,
  "maxPages": 1
}' |
apify call reventadata/leboncoin-scraper --silent --output-dataset

```

## MCP server setup

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