# France FSBO Property Listings — PAP.fr Scraper (`jungle_synthesizer/pap-fr-france-private-seller-property-listings-scraper`) Actor

France's for-sale-by-owner property listings from PAP.fr — sale and rental across every property type and department, with DPE energy class, GES, charges, and surface loi Carrez included.

- **URL**: https://apify.com/jungle\_synthesizer/pap-fr-france-private-seller-property-listings-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 record scrapeds

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

## France FSBO Property Listings — PAP.fr Scraper

Scrape France's for-sale-by-owner property listings from [PAP.fr](https://www.pap.fr) — Particulier à Particulier, the country's largest direct-from-owner marketplace. Returns sale and rental listings across every property type and department, with price, surface, DPE energy class, GES, and location fields included.

***

### PAP.fr Scraper Features

- Extracts every FSBO listing category PAP.fr publishes — apartments, houses, terrain, parking, local commercial, and immeuble, for both sale and rental
- Covers all of France, department by department, not a single city or region
- Returns the French regulatory fields most scrapers skip: DPE energy class, GES emissions grade, co-ownership charges, and loi Carrez surface
- Follows pagination automatically, so a single run can walk a category's full listing count
- Flags whether a listing is furnished (meublé), which decides the French rental tax regime
- Filter by deal type (sale or rental) and property category, or leave both open and get everything

***

### Who Uses PAP.fr Data?

- **Real estate agencies** — build a prospecting list of owners who chose not to list with an agent
- **iBuyers and instant-offer platforms** — source FSBO inventory before an agent ever touches it
- **Mortgage brokers and mandate hunters** — find sellers early, while they're still deciding how to sell
- **Market analysts** — track DPE/GES distribution and price-per-sqm by department, region-by-region
- **Compliance and underwriting teams** — pull the energy-class and charges data a real valuation actually needs, not just a headline price

***

### How the PAP.fr Scraper Works

1. Pick a deal type (sale, rental, or both) and one or more property categories, or leave the filters empty for full national coverage.
2. The scraper walks every matching category page by page and pulls each listing's detail page for the full field set.
3. Regulatory fields (DPE, GES), surface, room counts, and location are parsed straight off each listing.
4. Results land in your dataset as they're found — export to JSON, CSV, or Excel from the Apify Console, or pull them via API.

***

### Input

```json
{
  "maxItems": 50,
  "dealTypes": ["vente"],
  "propertyTypes": ["appartement_maison"]
}
```

| Field           | Type    | Default | Description |
|-----------------|---------|---------|---|
| `maxItems`      | integer | 10      | Maximum number of listings to return |
| `dealTypes`     | array   | *(all)* | `vente` (for sale) and/or `location` (for rent). Leave empty for both |
| `propertyTypes` | array   | *(all)* | `appartement_maison`, `terrain`, `parking`, `local_commercial`, `immeuble`. Leave empty for every category |
| `resumeCursor`  | string  | —       | Cursor from a previous run's Output, used to continue a stopped crawl |

Rental-only example, apartments and houses:

```json
{
  "maxItems": 100,
  "dealTypes": ["location"],
  "propertyTypes": ["appartement_maison"]
}
```

***

### PAP.fr Scraper Output Fields

```json
{
  "listing_id": "464702306",
  "listing_url": "https://www.pap.fr/annonces/maison-florensac-34510-r464702306",
  "title": "Vente maison 210 m² Florensac (34510)",
  "deal_type": "vente",
  "property_type": "maison",
  "price_eur": 680000,
  "price_per_sqm_eur": 3238,
  "rooms": 6,
  "bedrooms": 5,
  "area_sqm": 210,
  "land_area_sqm": 1520,
  "energy_class": "C",
  "ges_class": "A",
  "is_furnished": null,
  "features": ["jardin", "garage", "piscine", "climatisation"],
  "city": "Florensac",
  "postal_code": "34510",
  "department": "Hérault",
  "department_code": "34",
  "region": "Occitanie",
  "seller_type": "particulier",
  "contact_phone_available": true,
  "reference": "G47/2306",
  "images_count": 18,
  "published_at": "2026-09-28"
}
```

| Field                     | Type    | Description                                                          |
|---------------------------|---------|----------------------------------------------------------------------|
| `listing_id`              | string  | PAP's numeric listing id                                             |
| `listing_url`             | string  | Canonical detail-page URL                                            |
| `title`                   | string  | Listing headline                                                     |
| `deal_type`               | string  | `vente` (sale) or `location` (rent)                                  |
| `property_type`           | string  | Appartement, maison, terrain, local commercial, parking, or immeuble |
| `price_eur`               | number  | Asking price or rent, in EUR                                         |
| `price_raw`               | string  | Price as displayed on the page                                       |
| `price_period`            | string  | `sale` or `month`                                                    |
| `price_per_sqm_eur`       | number  | Price per square meter, when PAP computes it                         |
| `charges_eur_month`       | number  | Monthly co-ownership/rental charges, when stated                     |
| `rooms`                   | number  | Number of rooms                                                      |
| `bedrooms`                | number  | Number of bedrooms, when stated                                      |
| `bathrooms`               | number  | Number of bathrooms, when stated                                     |
| `area_sqm`                | number  | Living area (loi Carrez for apartments)                              |
| `land_area_sqm`           | number  | Land/plot area, for houses and terrain                               |
| `floor`                   | string  | Floor the unit is on, when stated                                    |
| `floors_total`            | number  | Total floors in the building, when stated                            |
| `has_elevator`            | boolean | Whether the building has an elevator                                 |
| `energy_class`            | string  | DPE energy class, A-G                                                |
| `ges_class`               | string  | GES greenhouse-gas class, A-G                                        |
| `energy_consumption_kwh`  | number  | Primary energy use in kWh/m²/year, when stated                       |
| `construction_year`       | number  | Year built, when stated                                              |
| `heating_type`            | string  | Heating system, when stated                                          |
| `is_furnished`            | boolean | Whether the listing is furnished (meublé)                            |
| `features`                | array   | Amenities called out on the listing                                  |
| `address_area`            | string  | Neighborhood/area as PAP displays it                                 |
| `arrondissement`          | string  | District number, Paris/Lyon/Marseille only                           |
| `city`                    | string  | City or commune                                                      |
| `postal_code`             | string  | French postal code                                                   |
| `department`              | string  | French department name                                               |
| `department_code`         | string  | French department code                                               |
| `region`                  | string  | French administrative region                                         |
| `description`             | string  | Full listing description                                             |
| `seller_type`             | string  | Always `particulier` — PAP is private-seller only                    |
| `contact_phone_available` | boolean | Whether a phone contact option is shown                              |
| `reference`               | string  | Seller's own reference code, when given                              |
| `image_urls`              | array   | Listing photo URLs                                                   |
| `images_count`            | number  | Number of photos                                                     |
| `published_at`            | string  | Publish date (ISO-8601 where parseable)                              |
| `updated_at`              | string  | Last-updated date, when shown separately                             |
| `scraped_at`              | string  | When this record was scraped                                         |

***

### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large crawl stops before it finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start a new run with **the same input** plus that `resumeCursor` to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### FAQ

#### How do I scrape PAP.fr listings?

Give the PAP.fr Scraper a deal type and property category — or leave both empty — and it returns every matching listing nationally. No account or API key needed.

#### What makes PAP.fr different from other French property sites?

Every listing on PAP.fr is from a private seller who chose not to use an agent. That's the whole point of the site, and it's why the data reads as a prospecting list rather than a generic portal dump.

#### Can I filter by sale vs. rental?

Yes. Set `dealTypes` to `vente` for sale, `location` for rent, or leave it empty to get both in one run.

#### Does the output include DPE and GES?

Yes, on every listing where PAP publishes them — DPE (energy class) and GES (emissions grade) are legally mandatory in France for most property types, and they're both parsed as clean single-letter grades.

#### How much does this actor cost to run?

Pricing follows Apify's standard pay-per-event model — check the Pricing tab on this actor's page for the current rate per listing.

***

### Need More Features?

Need custom fields or a different filter? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use the PAP.fr Scraper?

- **FSBO-only** — every record is a private seller, not an agency listing wearing a portal's branding.
- **Regulatory fields included** — DPE, GES, charges, and loi Carrez surface come standard, which is what turns a listing into something you can actually underwrite.
- **National coverage** — every department, every property category, in one actor.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

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

Maximum number of records to scrape

## `dealTypes` (type: `array`):

Sale (vente) and/or rental (location) listings. Leave empty for both.

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

Property categories to include. "Appartement / Maison" is PAP's own combined search category — the site does not expose apartments and houses as separate search filters; the record's own property\_type field still distinguishes them. Leave empty for all property types.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 10,
  "dealTypes": [],
  "propertyTypes": []
}
```

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 10,
    "dealTypes": [],
    "propertyTypes": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/pap-fr-france-private-seller-property-listings-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 10,
    "dealTypes": [],
    "propertyTypes": [],
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/pap-fr-france-private-seller-property-listings-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 10,
  "dealTypes": [],
  "propertyTypes": []
}' |
apify call jungle_synthesizer/pap-fr-france-private-seller-property-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/pap-fr-france-private-seller-property-listings-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/fLUgocfLb5gX2DeZF/builds/lXW9ckfKBR62d8rS2/openapi.json
