# PAP Scraper 🇫🇷 Particuliers + Téléphone du Propriétaire (`tagadanar/french-real-estate-pap`) Actor

Annonces de particuliers PAP.fr, sans agences, avec le téléphone du propriétaire et l'adresse complète en option. Prix, surface, pièces, €/m², DPE et photos pour chaque annonce, dès 1$/1000 annonces. Idéal pour la pige immobilière, la prospection et les agents IA (API + MCP).

- **URL**: https://apify.com/tagadanar/french-real-estate-pap.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** Real estate, Lead generation, AI
- **Stats:** 5 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listing founds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PAP Real Estate Listings, Owner-Direct Sales & Rentals (France)

**Scrape French property ads from [PAP.fr](https://www.pap.fr) (Particulier à Particulier).** Paste a PAP search URL and get clean, structured listings for every result page, complete with **price, surface, rooms, €/m², energy class, description and photos**.

PAP is **owner-direct only**: no agencies, no agency fees. Every record is a private seller, which makes this ideal for **buyer/renter search, market analysis, lead sourcing, and AI agents** (works via API and MCP).

### Why this actor

Every lead here is owner-direct, since PAP carries no agency listings at all, so each result comes straight from a private individual selling or renting their own property. Turn on `scrapeDetails` *(optional)* and the actor also pulls the owner's **phone number** and the **exact street address** from the ad itself, for direct-to-owner contact with no agency standing in between.

Using it is as simple as it gets: build whatever search you want on pap.fr (city, sale or rental, property type, filters), paste the resulting URL into the actor, and every result page after that is followed automatically. Fields come back clean and computed too, French prices and surfaces parsed into numbers, **€/m² computed** for sales, and the DPE energy class extracted straight from the listing.

Need to narrow things down further? Filter inside the actor by price, surface, rooms, property type or keywords, on top of whatever the search URL already selects. And pricing stays fair throughout: you pay per listing returned, and the phone/address premium is only charged when contact data is actually found.

### Companion actors in the French real-estate suite

- [**SeLoger Scraper**](https://apify.com/tagadanar/french-real-estate-seloger): listings from SeLoger, France's #1 portal, with seller phone plus a particulier/agence flag.
- [**Logic-Immo Scraper**](https://apify.com/tagadanar/french-real-estate-logicimmo): listings from Logic-Immo, including the advertiser's phone number and an agency/private flag.
- [**French Real Estate Sales (DVF)**](https://apify.com/tagadanar/french-real-estate-dvf) gives you official recorded **sold** prices, handy for benchmarking PAP asking prices against reality.
- [**Real Estate Deal Score**](https://apify.com/tagadanar/french-real-estate-deal-score) scores PAP asking prices against DVF sold prices and ranks the best deals first.

Pair PAP with DVF for asking-vs-achieved price analysis, or feed both into Deal Score for an over/under-market ranking.

### Input

```json
{
    "searchUrls": [
        "https://www.pap.fr/annonce/vente-appartements-bordeaux-33000-g43898"
    ],
    "minPrice": 150000,
    "maxPrice": 400000,
    "minSurface": 40,
    "minRooms": 2,
    "propertyTypes": ["Appartement"],
    "keywords": ["terrasse", "balcon"],
    "scrapeDetails": true,
    "maxResults": 500
}
```

Set `scrapeDetails: true` to also fetch each listing's page for the **owner phone**, **street address** and full description. Leave it `false` (default) for a faster, list-only run.

**How to get a search URL:** go to [pap.fr](https://www.pap.fr), run the search you want (choose city, *acheter* or *louer*, property type, and any filters), then copy the address-bar URL and paste it into `searchUrls`. You can pass several URLs at once.

### Output (one record per listing)

```json
{
    "source": "PAP",
    "id": "450001168",
    "url": "https://www.pap.fr/annonces/appartement-aix-en-provence-r450001168",
    "transactionType": "sale",
    "propertyType": "Appartement",
    "title": "Aix-En-Provence",
    "location": "Aix-En-Provence",
    "price": 389000,
    "currency": "EUR",
    "pricePerM2": 9262,
    "rooms": 2,
    "bedrooms": 1,
    "surface": 42,
    "landSurface": null,
    "energyClass": "B",
    "description": "Beau Loft avec terrasse et parking, Aix centre…",
    "photos": ["https://cdn.pap.fr/photos/…-p3.jpg"],
    "photoCount": 8,
    "seller": "Particulier",
    "phone": "06 71 26 79 76",
    "streetAddress": "rue Constant Coquelin",
    "postalCode": "94400",
    "reference": "vente-450001168",
    "sourceRef": "pap.fr (Particulier à Particulier)"
}
```

The `phone`, `streetAddress`, `postalCode` and `reference` fields are populated only when `scrapeDetails` is on; otherwise they are `null`.

### Pricing

Pay per event, no subscription:

| Event | When |
|---|---|
| Actor start | Once per run |
| Listing found | Per listing returned |
| Listing detailed | Per listing enriched with owner phone/address (only when `scrapeDetails` is on **and** contact data is found) |

### FAQ

**What's the source?** Public listings on pap.fr, France's largest owner-to-owner (particulier à particulier) real-estate site. Agencies can't list there, so results are private sellers/landlords.

**Sales and rentals?** Both. The actor detects sale vs rental from the search URL; `€/m²` is computed for sales only.

**How do I target a specific city or neighbourhood?** Build the search on pap.fr: its filters (arrondissement, budget, surface, rooms, exterior, etc.) all encode into the URL you paste.

**Why do some fields come back null?** When a listing genuinely omits a value (e.g. price on request, no DPE), the field is `null` rather than a guess.

**Does it work with AI agents?** Yes, it's exposed via REST API and **MCP**.

***

### Something missing?

If you need an extra field, another source, or a different output, open an issue on this Actor and describe it. I read every request and small additions usually ship within days. More French real estate Actors (pige, DVF, deal score, DPE leads) are on [my profile](https://apify.com/tagadanar).

*Keywords: PAP, particulier à particulier, annonces immobilières, immobilier France, real estate listings, property France, prix immobilier, €/m², location appartement, vente maison, owner-direct, no agency, proptech.*

# Actor input Schema

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

One or more pap.fr search-result URLs. Build the search you want on <a href='https://www.pap.fr' target='_blank'>pap.fr</a> (city, sale/rental, property type, price/surface filters), then copy the page URL and paste it here. All result pages are followed automatically. Example: <code>https://www.pap.fr/annonce/vente-appartements-bordeaux-33000-g43898</code>

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

Keep only listings at or above this price.

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

Keep only listings at or below this price.

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

Keep only listings with at least this built surface.

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

Keep only listings with at least this many rooms (pièces).

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

Keep only these property types. Empty = all types found in the search.

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

Keep only listings whose description or location contains at least one of these words (e.g. <code>terrasse</code>, <code>jardin</code>, <code>ascenseur</code>).

## `scrapeDetails` (type: `boolean`):

Open each listing's page to also extract the <b>owner's phone number</b>, the <b>full street address</b> and the complete description. Slower and fetches one page per listing, but gives you direct owner contact for lead generation. Off = fast, list-only.

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

Stop after this many listings across all search URLs.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.pap.fr/annonce/vente-appartements-aix-en-provence-13-g11424"
  ],
  "propertyTypes": [],
  "keywords": [],
  "scrapeDetails": false,
  "maxResults": 500
}
```

# Actor output Schema

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

All scraped PAP listings (one item per property) in the default dataset.

# 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 = {
    "searchUrls": [
        "https://www.pap.fr/annonce/vente-appartements-aix-en-provence-13-g11424"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/french-real-estate-pap").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 = { "searchUrls": ["https://www.pap.fr/annonce/vente-appartements-aix-en-provence-13-g11424"] }

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/french-real-estate-pap").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchUrls": [
    "https://www.pap.fr/annonce/vente-appartements-aix-en-provence-13-g11424"
  ]
}' |
apify call tagadanar/french-real-estate-pap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=tagadanar/french-real-estate-pap",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/lWCYCZMdC2y7ld5bx/builds/vvgYC0BvHvEIvCyJa/openapi.json
