# PAP Scraper: pap.fr Real Estate Ads & Phones (`automation_craft/pap-scraper`) Actor

Export PAP (pap.fr) ads de particulier à particulier across France: homes to buy or let, PAP Vacances holiday lets and PAP Commerces businesses, no login. Each ad gives its asking price or rent, m2, pièces, DPE, commune and badges; details add how to reach the owner. Alerts, CSV, API; pay per ad.

- **URL**: https://apify.com/automation_craft/pap-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Real estate, Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.95 / 1,000 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

### PAP Scraper: pap.fr Real Estate Ads & Phones

**PAP scraper** for France's owner to owner property portal ("de particulier à particulier"): search pap.fr flats, houses, land,
parking, offices, shops and the other PAP property types for sale or for rent (or both in one run), PAP Vacances (papvacances.fr)
holiday rentals and PAP Commerces (papcommerces.fr) businesses for sale by activity, all in one Actor. Type towns, arrondissements,
departments, regions or postal codes, or paste PAP search links, ad links, ad numbers or PAP references, and get one row per ad with
its price or rent, price per m2, surface, rooms, bedrooms, energy class (DPE), town, postal code, department, photos and PAP's badges.
With **Listing details**, each row adds the whole description, PAP's reference, the publication day, features, nearby stops, rent
terms and how to reach the owner. No login, no cookies. pap.fr searches are read past PAP's 25 page limit.

Who uses it: buyers and tenants watching new private ads, investors and analysts comparing asking prices and rents per m2 by town,
property search and alert services, holiday rental and business transfer researchers, and teams that need a feed of PAP ads in their
own tools.

### Quick start

1. Open the **Input** tab and type a place in **Places**, for example `Paris`, `Paris 12e`, `Lyon`, `Gironde`, `33`, `Bretagne`
   or `75011`.
2. Choose **For sale**, **For rent**, **For sale and for rent** or **Holiday rental (PAP Vacances)**, pick the property types, and
   add filters if you like: price or rent, surface, rooms, bedrooms, price per m2, energy class, keywords.
3. Or paste PAP search links into **PAP search links**, or ads into **Ad links or ad numbers** or **PAP references** (`G46/2150`).
4. Set **Maximum rows** and click **Start**. Download the rows as JSON, CSV or Excel, or read them through the Apify API.

To watch a search for new ads, give the run a **Monitor name** and schedule it: each run delivers only the ads it never delivered
before, and with **Track changes and removals** also the ads whose price changed and the ads PAP took offline.

### What you get

One row per ad (`type: "listing"`), one row per ad a monitor finds removed (`type: "removed"`), one coverage row per search
(`type: "search"`), free status rows for anything that could not be delivered (`type: "status"`), and a run summary
(`type: "summary"`).

| Field | What it is | Filled on (measured on the real actor's runs of 2026-10-19 and 2026-10-20: 563 distinct pap.fr ads, 30 with Listing details, 13 PAP Vacances rentals; a recount on build 0.1.4's 460 ads is within 1.5 points) |
|---|---|---|
| `id`, `site`, `url`, `commercesUrl` | PAP's ad number, pap.fr or papvacances.fr, the ad's link, the same ad on papcommerces.fr for a business or commercial ad | every ad; `commercesUrl` on business and commercial ads |
| `transaction`, `propertyType`, `kind` | sale, rent or holiday; the property type (the input's names); the kind word PAP writes in the ad's link | every ad |
| `price`, `priceText`, `currency`, `pricePerSqm` | the sale price, the monthly rent (charges included, as PAP shows it) or a holiday rental's starting weekly price; PAP's price per m2, else the price divided by the surface | price 100 percent, price per m2 99.6 percent of pap.fr ads |
| `surface`, `landSurface`, `rooms`, `bedrooms` | living surface and plot of land in m2, rooms (pièces), bedrooms | surface 99.6, rooms 96.4, bedrooms 79.8 percent of pap.fr ads (surface 99.8, rooms 100 and bedrooms 82.7 percent of flats and houses) |
| `city`, `postalCode`, `departmentCode`, `department`, `region`, `country` | the town or arrondissement, postal code, department and region (from the postal code) | city 99.3, postal code 98.4, department 99.3 percent |
| `description`, `descriptionIsFull` | the card's excerpt, or the whole text with Listing details | every ad |
| `fromText` | facts the owner writes in the text and PAP shows in no field: `floor`, `heating`, `heatingCollective`, `condoCharges` and `condoChargesPeriod`, `propertyTax`, `yearBuilt`, each null when it is not recognised in the text (read from the owner's words, not checked) | new since the measured build: 139 of 400 Paris ads in a test run of 2026-10-19 carried at least one (floor on 132) |
| `photos`, `photoCount`, `hasVirtualTour` | every photo link, how many, a virtual tour | photos 98.9 percent; virtual tour 9.1 percent |
| `energyClass`, `ghgClass` | the energy class (DPE) A to G; the greenhouse gas class (GES) from the ad's page | energy class 91.7 percent of pap.fr ads (94.1 of flats and houses); gas class 80.0 percent of ads with Listing details |
| `badge`, `badgeText`, `isFeatured` | PAP's badge: `exclusive` (Seulement sur PAP), `price_drop`, `cheaper_on_pap` or `negotiable`, with PAP's words; whether PAP also promotes the ad in its featured slots | badge 68.9 percent (exclusive 47.6, cheaper on PAP 10.5, price drop 9.4, negotiable 1.4); promoted 5.0 percent |
| `nearbyKm` | with **Keep PAP's nearby ads**: the distance PAP shows for an ad it added from a nearby town | those ads only |
| `sellerType` | always `private`: every PAP advertiser is a private person | every ad |
| `title` | the ad's title as PAP shows it on its page | ads with Listing details and ads read by link (30 of 30) |
| `searchKind`, `searchLabel`, `searchPage`, `searchRank` | which search, page and rank delivered the row | every row from a search |
| `reference`, `publishedDate`, `daysSincePublished` | with Listing details: PAP's reference (`G46/2150`), the day PAP last published the ad (renewed when the owner republishes it), whole days since then | 30 of 30 ads with Listing details |
| `features`, `transports`, `condition`, `energyText`, `ghgText` | with Listing details: the features PAP lists (lift, balcony or terrace, parking, cellar ...), the nearby metro, RER, tram and train stops, new or used, PAP's energy and gas texts | features 70.0, stops 63.3, condition 100, energy text 96.7, gas text 80.0 percent |
| `priceWithFees`, `monthlyPaymentEstimate`, `priceValidatedByPap` | with Listing details, sales: the price with notary fees and PAP's monthly payment estimate | 30 of 30 sales |
| `rentWithCharges`, `charges`, `deposit`, `rentControlled`, `referenceRentCap`, `rentSupplement` | with Listing details, rentals: rent with charges, charges, deposit, whether the town has rent control and its figures | rentals whose page shows them (no rental was read with Listing details in the measured runs) |
| `contactVia`, `hasPhone`, `phoneIsPapRelay`, `phone`, `phones`, `phonesE164`, `hasMessageForm`, `offersWhatsappVideoCall`, `refusesCanvassing` | with Listing details: how to reach the owner (`owner_phone`, `pap_relay` or `message_only`), PAP's relay number (the owner's own numbers only with **Include personal data**), the numbers in international form, PAP's message form, the owner's WhatsApp video call note, the owner's statement that they refuse commercial canvassing | of 30 ads with Listing details: owner's phone 16, PAP's relay 8, message form only 6; message form 30, WhatsApp note 5, refuses canvassing 29 |
| `guests`, `bathrooms`, `priceFrom`, `pricePeriod`, `minNights`, `rating`, `reviewCount` | PAP Vacances: guests, bathrooms, the starting price and its period, minimum nights, stars and number of reviews | guests every rental, bathrooms 11 and weekly price 9 of 13 |
| `rates`, `beds`, `composition`, `amenities`, `services`, `activities`, `unavailableDates`, `calendarShown`, `checkInTime`, `checkOutTime`, `reviews`, `availableForStay` | PAP Vacances with Listing details: the rate table, beds, rooms, amenities, services, nearby activities, booked nights from today, arrival and departure times, the reviews (author as shown, stars, day, stay, text), and whether your stay dates are free | of 5 rentals read with Listing details: beds, amenities and calendar 5, rates 4, reviews 1 |
| `change`, `repost`, `monitorBaseline` | on a monitor's change row: what changed, the previous price, the change in euros and percent, the price history; on a repost: the removed ad it repeats; the monitor's own record of the version delivered | monitor runs |
| `street`, `latitude`, `longitude` | the street and map position: only with **Include personal data** | with the switch on |
| `rawData` | with **Include PAP's raw data**: the result card as read and, with Listing details, the ad page's schema.org record (street, position, telephone and e-mail emptied while the personal data switch is off) | with the switch on |
| `detailsCharged`, `deliveryId`, `monitorName`, `scrapedAt` | whether the row was billed as Listing details, the row's own id, the monitor, when the row was written | every row |

A sample row (shortened, Include personal data off: PAP's relay number shows, the owner's number, street and position do not):

```json
{
  "type": "listing",
  "id": "464602150",
  "site": "pap.fr",
  "url": "https://www.pap.fr/annonces/appartement-place-de-parking-cave-paris-12e-75012-r464602150",
  "transaction": "sale",
  "propertyType": "apartment",
  "title": "Vente studio 24,11 m² + Place De Parking + Cave, Paris 12E (75012)",
  "price": 270000,
  "pricePerSqm": 11199,
  "surface": 24.11,
  "rooms": 1,
  "city": "Paris 12e",
  "postalCode": "75012",
  "department": "Paris",
  "region": "Île-de-France",
  "description": "Appartement Paris 12ème, situé au 7ème étage sur 8 avec ascenseur comprenant ...",
  "photoCount": 12,
  "energyClass": "E",
  "ghgClass": "E",
  "badge": "exclusive",
  "badgeText": "Seulement sur PAP",
  "isFeatured": false,
  "detailsCharged": true,
  "reference": "G46/2150",
  "publishedDate": "2026-10-19",
  "daysSincePublished": 0,
  "transports": [{ "name": "Reuilly - Diderot", "lines": ["METRO 1", "METRO 8"] }],
  "features": { "lift": true },
  "condition": "used",
  "priceWithFees": 291795,
  "monthlyPaymentEstimate": 1214,
  "refusesCanvassing": true,
  "contactVia": "pap_relay",
  "phone": "01 40 56 35 45",
  "hasMessageForm": true,
  "offersWhatsappVideoCall": false,
  "street": null,
  "latitude": null,
  "longitude": null,
  "scrapedAt": "2026-10-19T22:39:21.155Z"
}
```

The coverage row of each search says how many ads PAP counts for it (`adsOnPap`), how many results pages were read, how many ads
were delivered, left out by a filter (and by which, `filteredOutBy`), already delivered, known to the monitor or promoted by PAP
(`featuredSkipped`), how many price windows were read, whether the search was read to its end (`complete`) and why it stopped
(`stoppedBy`).

### How much does it cost to scrape PAP?

You pay per event, with Apify's store discounts by plan:

| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| Listing (one ad row) | $1.33 per 1,000 | $1.22 per 1,000 | $1.10 per 1,000 | $0.95 per 1,000 |
| Listing details (add-on, per ad row that carries the ad's page) | $2.09 per 1,000 | $1.99 per 1,000 | $1.89 per 1,000 | $1.69 per 1,000 |
| Results page (monitor runs only) | $3.00 per 1,000 pages | $3.00 per 1,000 pages | $3.00 per 1,000 pages | $3.00 per 1,000 pages |
| Actor start (once per run, charged on every run) | $0.012 | $0.011 | $0.0105 | $0.01 |

Platinum and Diamond plans pay the Gold price.

The Store pricing card shows these prices per 1,000 events: "$0.95 / 1,000" on the Listing row means one ad row costs $0.00095 on
the Gold plan, and "$3.00 / 1,000" on the Results page row means one results page costs $0.003.

- Never billed: ads left out by your filters, PAP's featured promotions, PAP's padded nearby ads you did not ask for, ads already
  delivered in the run, ads a monitor already knows (and unchanged ads it delivers on request), reposts you skip, ads no longer
  online, ad pages a filter leaves out or that cannot be read, invalid inputs, status rows, coverage rows and the summary. The
  Actor start event is charged on every run, whatever it delivers.
- Results pages are billed only in monitor runs: a monitor reads every page of its window each run (with change tracking, the
  whole search), so each page it reads (about 12 ads) is billed whatever it held. Searches outside a monitor never pay for their
  pages.
- Ad links and PAP references are read on the ad's own page, so each row they give is billed as Listing and Listing details.
- Example on the Gold plan: 1,000 ads from one search cost $0.01 (start) + $0.95 (1,000 listings) = $0.96. With Listing details,
  add $1.69: $2.65. On the Free plan the same runs cost about $1.34 and $3.43.
- Example: 100 ad links on the Gold plan cost $0.01 + $0.095 + $0.169 = about $0.27.
- Example of a daily monitor run (Gold) that reads 3 results pages and finds 10 new ads: $0.01 + 3 pages ($0.009) + 10 listings
  ($0.0095) = about $0.03.

### Input

| Setting | What it does |
|---|---|
| `places` | Towns, cities, arrondissements, departments, regions, postal codes or France, as you would type them on PAP (`Paris`, `Paris 12e`, `Marseille 8`, `Gironde`, `33`, `Bretagne`, `75011`, `France`), or PAP place ids (`g439`). A name several towns share needs its postal code or department (`Sainte-Colombe 69560`); a name that matches none or several is a free row with the candidates. A region is searched department by department. Up to 100. Countries outside France are refused. |
| `transaction` | `sale` (default), `rent`, `sale_and_rent` (each place and type searched for sale and for rent) or `holiday` (PAP Vacances). |
| `propertyTypes` | 18 types: house, apartment, land, parking, building, space to fit out, houseboat, mobile home, life annuity (viager), timeshare, serviced residence, rent to own, housing for services, office, shop, business, workshop, other. One search each; default apartment and house. Office, shop, business and workshop are the commercial ads PAP Commerces shows. |
| `businessActivities` | PAP Commerces businesses for sale (fonds de commerce) by activity: food, gifts and flowers, services, hotels, bars and restaurants, press and tobacco, fashion and beauty, video, photo and computers. |
| `holidayTypes` | PAP Vacances: house, apartment, gite, mobile home, unusual stay, bed and breakfast (default every kind). |
| `minPrice`, `maxPrice`, `minSurface`, `maxSurface`, `minRooms`, `maxRooms`, `minBedrooms`, `maxBedrooms` | Price or monthly rent, surface, rooms and bedrooms, sent to PAP and checked again on every row. |
| `minPricePerSqm`, `maxPricePerSqm` | Price per m2, checked on every row; an ad without one is left out free. |
| `minLandSurface`, `maxLandSurface` | Plot of land, read from the ad's page (needs Listing details). |
| `excludeNewBuild` | Sales: PAP's own "neuf exclus" filter (PAP lists almost no new builds: on 2026-10-20 it removed 0 of 13,253 ads). |
| `includeNearby` | Keep the ads PAP adds from nearby towns to a small town's search, with `nearbyKm`. Off by default: they are left out free and counted. |
| `features` | Duplex or triplex (sales) and virtual tour from the result card; lift, balcony or terrace, top floor, furnished and unfurnished from the ad's page (need Listing details). |
| `energyClasses`, `ghgClasses` | Energy classes (DPE) on the card or page; greenhouse gas classes (GES) on the page (needs Listing details). |
| `exclusiveOnly`, `priceDropOnly`, `flatshare` | Only ads PAP marks "Seulement sur PAP", only ads with a lowered price; rentals: only flat shares (colocation) or none. |
| `keywords`, `keywordsMatch`, `excludeKeywords` | Words the ad must hold (all, or any one) and words it must not hold: whole words, accents and capitals ignored, on the card's text or the whole description with Listing details. |
| `postedWithinDays` | Only ads published or republished in the last N days (needs Listing details: PAP shows the day of the ad's latest publication on its page). |
| `withPhotosOnly`, `withPhoneOnly`, `ownerPhoneOnly` | Ads with photos; ads whose page shows a phone number; ads whose page shows the owner's own number, not PAP's relay (the last two need Listing details; the number itself needs Include personal data). |
| `excludeAdIds`, `excludeDatasetIds` | Ads to leave out free by number or link (up to 10,000), or every ad of up to 10 of your datasets (up to 200,000 ads). |
| `sort` | Newest first (default, PAP's own order), oldest first, price or surface, each way. |
| `minGuests`, `minBathrooms`, `maxWeeklyPrice` | PAP Vacances: guests, bathrooms, the highest starting weekly price. |
| `holidayAmenities`, `stayFrom`, `stayTo` | PAP Vacances, with Listing details: 16 amenities and services (Wi-Fi, pool, air conditioning, pets welcome, parking, garden ...), and stay dates checked against the ad's calendar (at most 90 nights; a stay past the calendar's last bookable day is left out). |
| `searchUrls` | pap.fr or papvacances.fr search links, read from the first page; the link's own type, place and filters must show on PAP's page. PAP Commerces search links, and PAP Vacances links of its own old region ids, are refused with a free row: use `places` (with `businessActivities` or the commercial property types for PAP Commerces). A link naming several places is read only when they are all towns or arrondissements; any other mix is refused with a free row: put the places in `places`. PAP Vacances links take no `sort`, no `postedWithinDays` and none of the sale and rent filters (PAP Vacances serves its own order and its ads answer only the holiday filters); in a holiday run, pasted pap.fr links take none of the holiday filters. Up to 100. |
| `adUrls`, `references` | Ad links or numbers (`r464602150` or `464602150`, up to 5,000) and PAP references (`G46/2150`, up to 500), looked up with PAP's own reference search (pap.fr ads; a PAP Vacances ad by its link or number). An ad PAP no longer has is a free row. |
| `maxItems`, `maxItemsPerSearch`, `maxPagesPerSearch` | Caps per run (default 100 rows), per search, per search in results pages. |
| `maxRequestsPerSecond` | The pace of the run's requests: 1 a second by default, up to 3 for a faster run. |
| `includeDetails`, `includePersonalData`, `includeRawData` | The Listing details add-on, the personal data switch (below), PAP's structured record. |
| `descriptionMaxLength`, `omitEmptyFields`, `flattenOutput`, `outputFields` | Shorter descriptions, no empty fields, dotted flat keys for spreadsheets, only the fields you list. |
| `monitorName`, `monitorBaselineOnly`, `trackChanges`, `changeFields`, `includeUnchanged`, `flagReposts`, `skipReposts` | The monitor (below). |
| `webhookUrl`, `webhookSecret`, `webhookHeaders`, `slackWebhookUrl`, `discordWebhookUrl`, `telegramBotToken`, `telegramChatId`, `whatsappPhoneNumberId`, `whatsappAccessToken`, `whatsappTo`, `notifyOnlyChanges`, `notificationMaxRows` | Notifications of the run's new rows, at no extra charge. |
| `failIfIncomplete`, `runLabel`, `feedback`, `proxyConfiguration` | Mark the run failed when a search or link was not read to its end (the rows stay); a label for the summary; a note to the developer; Apify residential proxies in France (default, included in the price) or your own French residential proxy links. |

Every search filter whose value the result card shows (property type, place, price or rent, surface, rooms, bedrooms, price per m2,
energy class, photos, badges, flat share, keywords, holiday guests, bathrooms and weekly price) is checked again on each ad before
it is billed; an ad that does not match is left out free and counted on the coverage row. Filters only the ad's page answers read
each candidate's page, and an ad they leave out is not billed.

#### Every pap.fr search to its end

PAP shows 25 pages of one search in one order (about 300 ads). This Actor reads them, then goes on in price order in windows that
start at the last price read, so a pap.fr search of any size is read to its end. Measured on 2026-10-19: all 1,112 Paris apartments
for sale in one walk (127 results pages, 5 price windows, about 6 minutes), and the 381 featured cards met on the way left out.

An arrondissement (`Paris 11e`, `Lyon 3e`, `75011`) is padded by PAP with ads of the city's other arrondissements and of nearby
towns, the latter shown under the arrondissement's own heading. Each card is placed by its own ad link, so both kinds are left out
free and counted (`otherArrondissement`, `padding`). The walk reads PAP's pages to its last one or to the bound on unpaid reading:
PAP pads a Paris arrondissement about nine to one with the rest of the city, so such a walk usually stops on that bound after 15 to
35 pages, its newest own ads delivered and a status row saying so, and the places after it in the same run are then not read. For
every ad of Paris arrondissements, search `Paris` (no padding) and keep the postal codes you want, or give one arrondissement per run.
On every place search a card is delivered only
when every place it could be in lies inside the search; a card whose place line names no place, or a name several towns share with no
department shown, is left out free (`placeUnknown`). Measured on 2026-10-20: the Lyon 3e apartment
rentals walk met 65 ads on 7 pages and delivered its 9 own ads (23 other arrondissements and 33 nearby towns left out).

#### Listing details (add-on)

With **Listing details** on, each ad row carries what the ad's own page adds: the whole description, PAP's reference, the
latest publication day and the days since, PAP's energy and gas texts, the gas class, features, condition, nearby stops, the price with
notary fees and the monthly payment estimate (sales), the rent with charges, deposit and rent control figures (rentals), the virtual
tour link, and how to reach the owner. For PAP Vacances: the rate table, beds, rooms, amenities, services, activities, calendar,
arrival and departure times and reviews. Billed as Listing details per row; a page that cannot be read is not billed.

#### Monitor: new ads, changes and removals

Give the run a **Monitor name** (words separated by spaces: 24 characters or more without a space that mix letters and digits
read as a token and are refused) and schedule it. Each run reads the ads published since the day before its last complete run (a
first run: since yesterday; at most 30 days back), newest first, and delivers only the ads it never delivered before. PAP Vacances
and PAP Commerces activity lists show no publication day: a monitor reads those searches whole every run (the coverage row says
`monitorReads: wholeSearch`), and its first run delivers them whole, or only remembers them with **First run: remember only**. With
**First run: remember only**, the first run stores what it meets without delivering it. With **Track changes and removals**, each
run reads the whole search, and an ad it delivered before comes back as a change row when its price (or another field you watch:
surface, rooms, bedrooms, energy class, description, photos) changed, with the previous price, the change and the price history;
an ad PAP no longer serves comes as a `removed` row and one that comes back as `reappeared`. With **Flag reposts** a new ad of a
property the monitor saw removed carries `repost`; with **Leave out reposts** it is skipped free when its description is also the removed ad's, else
delivered with its flag (a repost has the same kind, transaction, five digit postal code, surface and rooms, so an ad whose card shows
no surface is never matched, and holiday rentals take neither switch). Change and removed rows are billed
as Listing. A monitor never forgets an ad (up to 50,000), so one monitor never bills an ad twice.

#### Notifications

A webhook (JSON, up to 1,000 rows a run, signed with HMAC SHA-256 when you give a secret), Slack, Discord, Telegram and WhatsApp
(up to 30 rows each by default) receive the run's new rows; with **Notify only changes**, only change and removed rows. A failed
notification never fails the run: a free status row names it.

#### Personal data

PAP's relay number (01 40 56 35 45) is PAP's own and always delivered. The owner's own phone numbers (`phone`, `phones`,
`phonesE164`), the street and the map position are delivered only when you turn on **Include personal data**
(`includePersonalData`, with Listing details); with it off those fields are empty, and so are their copies in `rawData`. Titles,
descriptions, PAP Vacances reviews (with their authors' names as PAP shows them) and every other text are delivered exactly as PAP
serves them, whether the switch is on or off. Most PAP owners state on their ad that they refuse commercial canvassing (`refusesCanvassing`); you are responsible for a lawful
use of personal data, GDPR included.

#### What PAP's robots.txt keeps out

This Actor reads only the pages PAP's robots.txt allows. So a few PAP filters are not offered for sale and rental ads: pool,
parking or garage, garden and disabled access (PAP applies them only through links its robots.txt asks crawlers not to read; use
**Keywords** such as `piscine`, `parking` or `jardin`), and two property types in one search (each type is its own search). A pasted
link that robots.txt disallows (two types, feature words, a `/pagination/` address) or that carries a query is refused with a free
row. Lift, balcony or terrace, top floor, furnished, land surface and the PAP Vacances amenities are checked on each ad's page
instead.

### What this Actor does NOT do

- **No seller names and no e-mails.** PAP shows neither; every advertiser is a private person (`sellerType: "private"`).
- **No owner's phone without your choice.** It is delivered only with Listing details and Include personal data on.
- **No complete walk past 25 pages on PAP Vacances and PAP Commerces**, nor on a pasted pap.fr link that holds a feature, a
  transport stop or several types: those searches stop at about 300 ads and the coverage row says how many were beyond reach;
  search a smaller place, or paste a link of one property type.
- **No time on the market.** PAP renews an ad's publication day when the owner republishes it, so rows carry
  `daysSincePublished` (days since the latest publication), not the days since the first one.
- **No new build filter.** PAP lists almost no new builds: its own "neuf exclus" search removed 0 of 13,253 ads.
- **Filters PAP keeps behind robots.txt are not offered** (above): pool, parking, garden, disabled access, rental investment and
  mobility lease on pap.fr ads; use keywords.
- **No radius search** (PAP's nearby padding is kept on request, with `nearbyKm`) and **no address resolution, ADEME energy
  records or DVF sold prices**: only what PAP's pages show.
- **Not on PAP's pages, so not in the rows:** video links, the publication hour, a kWh figure (PAP's energy text gives a range),
  and a COVID guarantee or registration number for holiday rentals.
- **No foreign countries.** Only ads in France, overseas departments included; PAP Vacances rentals abroad are not read.
- **No price history before your first monitor run.** PAP keeps none; a monitor with change tracking records prices and removals
  from its first run on.
- **No login and no account data**: no saved searches, alerts or messages, and it never contacts an owner.
- **No other portals and no CRM exports** (Notion, Airtable and the like). Only pap.fr, papvacances.fr and papcommerces.fr; the
  rows go to Apify's own integrations, the API, webhooks and the chat notifications.
- **No ad links, references, other orders or posted windows in a monitor.** A monitor watches searches, newest first.
- **No guarantee on rare filters over big searches.** Unpaid page reads are bounded (USD 0.001 a run plus a share of every paid
  event), so a filter few ads pass can end a large search early; a status row says so. Narrow the search or loosen the filter.
- **No complete walk of a Paris arrondissement in most runs.** PAP pads it about nine to one with the rest of Paris; the padding is
  left out free but read unpaid, so the walk usually stops on the unpaid bound with its newest own ads, and later places of the run
  are not read (a status row says so). Search `Paris` and keep the postal codes you want, or one arrondissement per run.
- **No guarantee on many near empty searches in one run.** A results page holding one ad costs about as much to read as that ad
  pays, so a run of many searches with about one ad each (100 small towns) can stop on the same bound after about half of them;
  its coverage rows name the searches not read. Run them in a few smaller runs or name a department instead.
- **Pace:** 1 request a second by default (the 1,112 ad Paris walk took about 6 minutes), up to 3 with `maxRequestsPerSecond`;
  Listing details read one more page per ad. `maxItems` defaults to 100.

### API examples

Run it and get the rows in one call (replace `YOUR_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~pap-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"places": ["Lyon"], "transaction": "rent", "propertyTypes": ["apartment"], "maxPrice": 1200, "minRooms": 2, "maxItems": 200}'
```

Node.js:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/pap-scraper').call({ places: ['Paris 15e'], includeDetails: true, maxItems: 100 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((x) => x.type === 'listing'));
```

Python:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/pap-scraper").call(run_input={"places": ["Gers"], "transaction": "holiday", "maxItems": 50})
rentals = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "listing"]
```

### FAQ

#### How can I scrape PAP (pap.fr) listings?

Type a place (a town, an arrondissement, a department, a region or a postal code) or paste a PAP search link, set a maximum, and
start the run: no code, no login and no proxy setup. The rows come out as JSON, CSV or Excel, or through the Apify API.

#### Is there a PAP API for property ads?

PAP offers no public API for reading its ads. This Actor works as one: call it through the Apify API with places, filters, search
links, ad links or PAP references and read the rows back as JSON.

#### How many ads can I export from one PAP search?

All of a pap.fr search, up to your `maxItems` (100 by default) and the run's timeout. PAP shows 25 pages of one search; this Actor
goes on in price windows, and on 2026-10-19 it read all 1,112 Paris apartments for sale (127 results pages, 5 price windows). Its
coverage row says how many ads PAP counts and how many were delivered.

#### Can I get the owner's phone number from PAP ads?

With Listing details on, each row says how to reach the owner: their own phone, PAP's relay number (01 40 56 35 45, always
delivered) or PAP's message form only. The owner's own number, the street and the map position are delivered only when you also
turn on **Include personal data**; most PAP owners state that they refuse commercial canvassing (`refusesCanvassing`).

#### Is it legal to scrape PAP?

This Actor reads only pages PAP's robots.txt allows, names itself in its User-Agent, and never logs in or solves a captcha. PAP's
terms forbid extracting or reusing its content beyond personal use and contacting its advertisers for business, PAP has won a
database case in court, and the CNIL holds that private sellers may not be canvassed without their consent, so you are responsible
for a lawful use: the parts you need, PAP's terms, and the GDPR for any personal data.

#### Why does this Actor run with limited permissions?

It needs nothing more: it writes only to its own run's dataset and key-value store, a monitor keeps its memory in a named key-value
store it creates itself, and it reads only the datasets you pick in **Datasets of ads to leave out**. Limited permissions keep your
other Apify data out of its reach.

### Changelog

- 0.1 (2026-10-20): first release: pap.fr sales and rentals (or both in one run), PAP Vacances holiday rentals and PAP Commerces
  businesses by place, search link, ad link, ad number or PAP reference; pap.fr searches read past the 25 page limit; Listing
  details add-on with how to reach the owner; monitor with change tracking, price history, removals, reappearances and reposts;
  notifications by webhook, Slack, Discord, Telegram and WhatsApp; private persons' data behind the personal data switch, texts as
  PAP serves them; robots.txt respected; arrondissement searches leave PAP's padding of the city and of nearby towns out free; facts from the owner's text
  (`fromText`); a faster pace on request (`maxRequestsPerSecond`).

### More data tools by Automation Craft

- [Bien'ici Scraper: France Real Estate Ads & DPE](https://apify.com/automation_craft/bienici-scraper)
- [SeLoger Scraper: Listings, Prices and Agencies](https://apify.com/automation_craft/seloger-scraper)
- [Leboncoin Scraper: Ads, Prices, Real Estate & Cars](https://apify.com/automation_craft/leboncoin-scraper)
- [La Centrale Scraper: Used Cars, Prices & Dealers](https://apify.com/automation_craft/lacentrale-scraper)
- [Airbnb Scraper: Prices, Calendar, Reviews](https://apify.com/automation_craft/airbnb-scraper)
- [Kleinanzeigen Scraper & API: Ads, Prices, Places](https://apify.com/automation_craft/kleinanzeigen-scraper)
- [Mobile.de Scraper: Cars, Prices, Dealers & Ratings](https://apify.com/automation_craft/mobile-de-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/pap-scraper/changelog.md

# Actor input Schema

## `places` (type: `array`):

Towns, cities, arrondissements, departments, regions, postal codes or France, as you would type them on PAP: Paris, Lyon, Paris 12e, Marseille 8, Gironde, 33, Bretagne, 75011, France. A name that several towns share needs its postal code or department (Sainte-Colombe 69560); a name that matches none or several gives a free row with the candidates. A postal code of several towns searches them together. A region is searched department by department. PAP place ids (g439) are accepted too; countries outside France are refused. Up to 100.

## `transaction` (type: `string`):

Ads for sale or for rent on pap.fr (or both: each place and type is then searched for sale and for rent), or holiday rentals on papvacances.fr. Default sale.

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

Sales and rentals: the kinds of property to search, one search each (PAP's robots.txt asks crawlers not to read its links that join two types). Default apartment and house. Office, shop, business and workshop are PAP's commercial ads, the ads PAP Commerces shows.

## `businessActivities` (type: `array`):

Businesses for sale (fonds de commerce) by activity, as PAP Commerces lists them: one search per activity and place. Sales only; leave Property types out (or set it to business).

## `holidayTypes` (type: `array`):

Holiday rentals: the kinds of stay to search, one search each. Default every kind.

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

The lowest sale price, or the lowest monthly rent (charges included, as PAP shows it).

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

The highest sale price, or the highest monthly rent.

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

The smallest living surface in square metres.

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

The largest living surface in square metres.

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

The fewest rooms (1 = studio, 6 = 6 or more).

## `maxRooms` (type: `integer`):

The most rooms (1 = studio, 6 = 6 or more, no upper bound).

## `minBedrooms` (type: `integer`):

The fewest bedrooms (holiday rentals too).

## `maxBedrooms` (type: `integer`):

The most bedrooms, checked on every row that shows a count (with Listing details, on the ad's own count too).

## `minPricePerSqm` (type: `integer`):

The lowest price per square metre, checked on every row (PAP's own figure, else the price divided by the surface). An ad without one is left out, free.

## `maxPricePerSqm` (type: `integer`):

The highest price per square metre, checked on every row. An ad without one is left out, free.

## `minLandSurface` (type: `integer`):

The smallest plot of land of a house or land ad, read from the ad's page (PAP's robots.txt asks crawlers not to read its land filter links). An ad that shows no land surface is left out, free.

## `maxLandSurface` (type: `integer`):

The largest plot of land, read from the ad's page. An ad that shows no land surface is left out, free.

## `excludeNewBuild` (type: `boolean`):

Sales: leave out new build ads (PAP's own neuf exclus filter).

## `includeNearby` (type: `boolean`):

PAP pads a search of a small town with ads of nearby towns, each card showing its distance (Fleurance - 15 Km). Off (default): those ads are left out, free, and counted. On: they are delivered with nearbyKm, the distance PAP shows.

## `features` (type: `array`):

Only ads with every one of these features. Duplex is PAP's own filter and a virtual tour shows on the result card; the others show only on the ad's own page (PAP's robots.txt asks crawlers not to read its feature filter links), so they need Listing details: each candidate's page is read and an ad without the feature is left out free (its page is not billed). A pool, parking or disabled access is not shown in a form that can be checked; use Keywords (piscine, parking) for them.

## `energyClasses` (type: `array`):

Only ads with one of these energy classes (DPE), checked on the result card (on the ad's page with Listing details). An ad that shows no class is left out, free.

## `ghgClasses` (type: `array`):

Only ads with one of these greenhouse gas classes (GES), which show only on the ad's page: needs Listing details.

## `exclusiveOnly` (type: `boolean`):

Only ads PAP marks as published only on PAP (Seulement sur PAP).

## `priceDropOnly` (type: `boolean`):

Only ads PAP marks with a lowered price (Baisse de prix).

## `flatshare` (type: `string`):

Rentals (transaction rent): only flatshare rooms, or none of them. Default any.

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

Words to find in the ad (jardin, parquet, metro): whole words, accents and capitals ignored. Checked on the title and the card's description excerpt, or on the whole description with Listing details. Up to 10, each up to 60 characters.

## `keywordsMatch` (type: `string`):

With several keywords: all of them (default), or any of them.

## `excludeKeywords` (type: `array`):

Leave out ads whose title or description holds any of these words (whole words, accents and capitals ignored), free. Up to 10.

## `postedWithinDays` (type: `integer`):

Only ads published or republished in the last N days (PAP shows the day of the ad's latest publication, which it renews when the owner republishes). The search is read newest first and stops at the first page that reaches past the window.

## `withPhotosOnly` (type: `boolean`):

Only ads that show at least one photo.

## `withPhoneOnly` (type: `boolean`):

Only ads whose page shows a phone number (the owner's own, or PAP's relay number).

## `ownerPhoneOnly` (type: `boolean`):

Only ads whose page shows the owner's own phone number, not PAP's relay number. The number itself is delivered only with Include personal data.

## `excludeAdIds` (type: `array`):

PAP ad numbers or ad links you already have (pap.fr, PAP Vacances, PAP Commerces); they are skipped, free. Up to 10,000.

## `excludeDatasetIds` (type: `array`):

Ids of your Apify datasets (an earlier run of this Actor, or any dataset whose rows carry a PAP ad number or link in "id" or "url"): their ads are skipped, free. Up to 10 datasets and 200,000 ads; a dataset that cannot be read stops the run before any paid work. Only the datasets picked here are readable to the run (limited permissions).

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

The order PAP lists the ads in. Default newest first (PAP's own order). A search link keeps its own order unless you set one here.

## `minGuests` (type: `integer`):

Holiday rentals: the fewest people the place sleeps.

## `minBathrooms` (type: `integer`):

Holiday rentals: the fewest bathrooms.

## `maxWeeklyPrice` (type: `integer`):

Holiday rentals: the highest starting price per week PAP Vacances shows (dès ... par semaine).

## `holidayAmenities` (type: `array`):

Holiday rentals: only places whose page lists every one of these amenities or services. Needs Listing details.

## `stayFrom` (type: `string`):

Holiday rentals: the first night of your stay (YYYY-MM-DD). With Stay to, only places whose calendar shows every night free are delivered (a stay past the calendar's last bookable day cannot be judged and is left out); each row carries availableForStay. Needs Listing details.

## `stayTo` (type: `string`):

The day you leave (YYYY-MM-DD; that night is not part of the stay). At most 90 nights.

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

The most paid rows the run delivers (ad rows, change and removed rows together). Default 100.

## `maxItemsPerSearch` (type: `integer`):

The most rows one search or link delivers.

## `maxPagesPerSearch` (type: `integer`):

The most results pages (about 12 ads each) one search or link reads.

## `maxRequestsPerSecond` (type: `integer`):

The pace of the run's requests on its one French residential exit: 1 a second by default, up to 3 for a faster run (PAP answers in about a second, so the gain is modest).

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

Search links copied from PAP: https://www.pap.fr/annonce/vente-appartements-paris-75-g439 or https://www.papvacances.fr/annonces/location-gers-32-g396, PAP's other wordings of its page links included. Every page is read from the first. The link's own type, place and filters must show on PAP's page, else the search is not read (free). A link PAP's robots.txt asks crawlers not to read (two property types, feature words, a page address under /pagination/), one that carries a query, a filter word outside PAP's rooms, bedrooms, price, surface and sort words, or a PAP Commerces search link (use places with businessActivities or the commercial property types) is refused with a free row. Up to 100.

## `adUrls` (type: `array`):

Ads to read directly: pap.fr, PAP Vacances or PAP Commerces ad links, or ad numbers (r464602150 or 464602150). Each ad's page is read, so each row is billed as Listing and Listing details. An ad PAP no longer has is a free row. Up to 5,000.

## `references` (type: `array`):

PAP ad references as printed on each ad (G46/2150), looked up with PAP's own reference search (pap.fr ads; for a PAP Vacances ad paste its link or number) and read like ad links. An unknown reference is a free row. Up to 500.

## `includeDetails` (type: `boolean`):

Read each delivered ad's own page: the whole description, reference, latest publication day and the days since, energy and gas texts, nearby metro and train stops, features (lift, balcony, top floor, furnished ...), the offer condition as PAP labels it, price with fees and the monthly payment estimate, rent with charges, deposit and rent control, whether the owner refuses canvassing, how to reach the owner (their phone, PAP's relay number or messages only) and, for holiday rentals, the rate table, beds, rooms, amenities, services and calendar. Billed as Listing details per row.

## `includePersonalData` (type: `boolean`):

Off by default. On, with Listing details: the owner's own phone numbers (phone, phones and phonesE164), the street and the map position (latitude, longitude) are delivered as PAP shows them logged out. Off: those fields are empty (phones \[], phonesE164 \[]), and the page's structured data in rawData carries no street, position, telephone or e-mail. PAP's relay number, which is PAP's own, is always shown. Titles, descriptions, holiday reviews (with their authors' shown names) and other texts are delivered exactly as PAP serves them, on or off. You are responsible for using personal data lawfully (GDPR included), and many owners state they refuse commercial canvassing (refusesCanvassing).

## `includeRawData` (type: `boolean`):

Add rawData to each ad row: the result card as read (rawData.card) and, with Listing details, the ad page's structured data (its schema.org record, rawData.ldJson; without the street, position, telephone and e-mail unless Include personal data). Larger rows; no extra charge.

## `descriptionMaxLength` (type: `integer`):

Cut the description of each row at this many characters (at a word, marked ...). Default the whole text.

## `omitEmptyFields` (type: `boolean`):

Leave out the fields of an ad row that are empty (null, an empty text or list). The fields that identify the row are always kept.

## `flattenOutput` (type: `boolean`):

Write nested objects as dotted keys (features.lift), handy for spreadsheets.

## `outputFields` (type: `array`):

Keep only these top level fields of an ad row (price, surface, city, url ...); the fields that identify the row and the Listing details fields you pay for are always kept.

## `runLabel` (type: `string`):

A label of your choice copied to the run summary (letters, digits, spaces and . \_ , - : # ( ) ' /, up to 100 characters; 24 characters or more without a space that mix letters and digits read as a token and are refused), to tell runs apart.

## `monitorName` (type: `string`):

A short name of your choice (letters, digits, spaces and . \_ , - : # ( ), up to 60 characters; 24 characters or more without a space that mix letters and digits read as a token and are refused, so separate words with spaces). One name belongs to one set of settings.

## `monitorBaselineOnly` (type: `boolean`):

With a monitor: on its first run only (complete or not), the ads met are only remembered, not delivered (no Listing charged; the results pages read are billed as Results pages). Later runs deliver only ads new since then. Not with trackChanges: turn it on for the later runs of the same monitor.

## `trackChanges` (type: `boolean`):

With a monitor: an ad it delivered before whose price (or another watched field, below) changed is delivered again with what changed, an ad PAP no longer serves is reported as removed and a removed ad that comes back as reappeared (all billed as Listing). This reads every page of the searches each run, every results page billed.

## `changeFields` (type: `array`):

With trackChanges: which changes of a known ad deliver it again (billed as Listing). A price change row carries the previous price, the change in euros and percent and the price history. Default price only.

## `includeUnchanged` (type: `boolean`):

With trackChanges: known ads met again without a watched change are delivered too, free, marked unchanged (they never count toward the maximum and are not sent in notifications, which carry new, changed and removed ads).

## `flagReposts` (type: `boolean`):

With trackChanges: a new ad that describes the same property as an ad this monitor reported removed (same kind, transaction, postal code, surface to the m2 and rooms) carries repost.repostOf with the removed ad's number and last price. Billed as a new ad.

## `skipReposts` (type: `boolean`):

With trackChanges: such a repost is left out, free (counted in the coverage row), instead of flagged, when its description is also the removed ad's; one with another description is delivered with its repost flag (sameDescription false), since a shared place, surface and rooms alone may be another property.

## `webhookUrl` (type: `string`):

An https address the run posts its new rows to (JSON, up to 100 rows a call, at most 1,000 a run, with a plain text summary in the field "text").

## `webhookSecret` (type: `string`):

Optional: each call then carries an x-signature-sha256 header, the HMAC SHA-256 of the body with this secret (16 to 200 letters, digits and - \_ . ~, with at least one letter and one digit).

## `webhookHeaders` (type: `object`):

Optional: up to 5 headers sent with each webhook call ({"Authorization": "Bearer ..."}), each value 8 to 500 characters; treated as secrets.

## `slackWebhookUrl` (type: `string`):

A Slack incoming webhook address (https://hooks.slack.com/...): the run posts its first new rows as messages, one line per ad (at most 30 lines).

## `discordWebhookUrl` (type: `string`):

A Discord channel webhook address (https://discord.com/api/webhooks/...): the run posts its first new rows as messages, one line per ad (at most 30 lines).

## `whatsappPhoneNumberId` (type: `string`):

The phone number id of your WhatsApp Business app (WhatsApp Cloud API); with the token and the recipient below, the run sends one message per new row (at most 30). WhatsApp delivers free text only inside a conversation the recipient opened in the last 24 hours.

## `whatsappAccessToken` (type: `string`):

The access token of your WhatsApp Business app.

## `whatsappTo` (type: `string`):

The phone number the messages go to, in international form (+33612345678).

## `telegramBotToken` (type: `string`):

Your own bot's token from BotFather; the run sends one message per new row (at most 30).

## `telegramChatId` (type: `string`):

The chat id (a number) or channel name (@name) your bot posts to.

## `notifyOnlyChanges` (type: `boolean`):

With trackChanges: the notifications carry only change and removed rows, not new ads.

## `notificationMaxRows` (type: `integer`):

The most rows each notification channel sends (default: 1,000 for the webhook, 30 for the chat channels).

## `failIfIncomplete` (type: `boolean`):

Mark the run failed when a search or link could not be read to its end for a reason other than your own limits. The rows delivered stay.

## `feedback` (type: `string`):

Optional: a note to the developer (a missing field, a place that did not resolve, an idea). It is copied to the run's summary row, where the developer reads it; up to 1,000 characters. Do not put personal data or secrets here.

## `proxyConfiguration` (type: `object`):

Apify residential proxies in France are used and included in the price: PAP refuses other addresses. Other Apify groups and countries are refused; your own proxy links (http://user:password@host:port, a French residential exit, the password 12 characters or more, no space) can be given instead.

## Actor input object example

```json
{
  "places": [
    "Paris"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# Actor output Schema

## `items` (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 = {
    "places": [
        "Paris"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/pap-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 = {
    "places": ["Paris"],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/pap-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 '{
  "places": [
    "Paris"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call automation_craft/pap-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/pap-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/5VetAV28ACf0o9dK1/builds/kUa2AcPdXGvOHi7WY/openapi.json
