# Marktplaats Scraper - NL Classifieds, Prices & Seller Leads (`scrapesage/marktplaats-scraper`) Actor

Scrape Marktplaats.nl by keyword, category or URL: prices, full ad details, attributes, images, location, seller leads & new-ad / price-drop monitoring. Cars, electronics, real estate & more.

- **URL**: https://apify.com/scrapesage/marktplaats-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 classified ad scrapeds

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/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

## Marktplaats Scraper — NL Classifieds, Prices, Listings & Seller Leads

Extract **complete data from [Marktplaats.nl](https://www.marktplaats.nl)** — the Netherlands' #1 classifieds marketplace. Search by **keyword, category or URL** and get every ad with its **price and price type, full description, structured attributes, image gallery, exact location, posted date, category and seller** — plus deduplicated **seller B2B leads** and a built-in **monitor mode** for new-ad and price-drop alerts.

No login, no API key, no browser — fast, reliable extraction straight from Marktplaats's own internal API across **cars, electronics, bikes, real estate, jobs, furniture, fashion and every other category**.

### Why this Marktplaats scraper?

Generic "paste-a-URL" crawlers grab a few visible fields and miss the data that actually matters. This actor reads Marktplaats's public search API and ad pages directly and ships the **richest dataset in the category** — real prices and price types, every structured attribute (car mileage, bike frame size, phone storage…), the full image gallery, geo-coordinates and the seller behind every ad.

| Data | Generic crawlers | This actor |
|---|---|---|
| Title, description, ad URL | ✅ | ✅ |
| **Price + price type** (fixed / bidding / on request / free / reserved) | partial | ✅ |
| **Every structured attribute** (condition, brand, mileage, frame size, storage…) | ❌ | ✅ |
| Full **image gallery** | partial | ✅ |
| **Exact location** + latitude/longitude | ❌ | ✅ |
| Category, category path & posted date | partial | ✅ |
| Seller name, **private vs business**, verified flag | ❌ | ✅ |
| Full description, **view & favourite counts**, bids (detail mode) | ❌ | ✅ |
| Deduplicated **seller B2B leads** (business-verified, reviews, website, lead score) | ❌ | ✅ |
| **Monitor mode** — only new ads / price drops | ❌ | ✅ |
| One clean dataset per entity (no empty columns) | ❌ | ✅ |

### Use cases

- **Price & market research** — track asking prices across any category, build pricing benchmarks, spot under-priced items the moment they're posted.
- **Reselling & arbitrage** — monitor a keyword for new listings and price drops, then be first to message the seller.
- **Dealer & business prospecting** — pull deduplicated **seller leads** filtered to businesses/dealers (verified flag, review count & rating, website, active-ad count) for B2B outreach.
- **Sourcing & procurement** — find specific parts, cars, equipment or stock by keyword, category and location radius.
- **Competitive intelligence** — see what businesses are listing, at what prices, in which categories.
- **Data & AI** — feed clean, structured classifieds data into dashboards, models or RAG pipelines.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **Marktplaats Scraper**, enter one or more **search keywords** (e.g. `iphone 15`, `racefiets`, `bmw e46`), or paste Marktplaats **Start URLs** (search, category, ad or seller pages).
3. Click **Start** and watch results stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "searchQueries": ["iphone 15", "racefiets"],
    "postcode": "1011",
    "distanceKm": 25,
    "minPrice": 50,
    "maxPrice": 500,
    "condition": "used",
    "sellerType": "business",
    "sort": "dateDesc",
    "maxItems": 200,
    "includeListingDetails": true,
    "includeSellerLeads": true,
    "monitorMode": false
}
```

- **searchQueries** — one or more keywords; each is scraped as its own feed.
- **startUrls** — Marktplaats search (`/q/…`), category (`/l/…`), ad (`/v/…/m123…`) or seller (`/u/…/123/`) URLs.
- **categoryId** — optional category ID to scope a search or browse a whole category.
- **listingUrls / sellerUrls** — scrape specific ads or seller storefronts directly.
- **postcode + distanceKm** — centre a radius search on a Dutch postcode.
- **minPrice / maxPrice / condition / sellerType** — filter the rich result data (price, new/used, private vs business).
- **sort** *(default relevance)* — `dateDesc`, `priceAsc`, `priceDesc`.
- **maxItems** *(default 100)* — cap across all searches/URLs.
- **includeListingDetails** *(default false)* — open each ad for the full description, every attribute, the complete image gallery, category breadcrumb, view & favourite counts and bids.
- **includeSellerLeads** *(default false)* — output one deduplicated lead per seller (business flag, reviews, website, lead score).
- **enrichSellerContacts** *(default false)* — open business sellers' storefronts for their website and accurate active-ad count.
- **monitorMode** *(default false)* — emit only new ads / price changes across runs (see below).
- **proxyConfiguration** — proxy settings (residential, Netherlands by default).

### Output

By default you get **one clean, dense table of listings** — every column applies to every row. Enable **seller leads** to add deduplicated `sellerLead` records (tagged with a `type` field), or use the **Listings** / **Seller leads** dataset views.

A listing record (`type: "listing"`):

```json
{
    "type": "listing",
    "listingId": "m2412150690",
    "title": "Racefiets Cannondale",
    "description": "Cannondale racefiets in prima staat, frame maat 58, Shimano Ultegra 10-speed…",
    "url": "https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-racefietsen/m2412150690-racefiets-cannondale",
    "price": 300,
    "priceType": "MIN_BID",
    "priceTypeLabel": "Bidding from",
    "currency": "EUR",
    "condition": "Zo goed als nieuw",
    "city": "Enschede",
    "country": "Nederland",
    "latitude": 52.2033,
    "longitude": 6.7998,
    "postedDate": "Vandaag",
    "images": ["https://images.marktplaats.com/api/v1/.../image.jpg"],
    "imageCount": 6,
    "category": "Bicycles Racing Bikes",
    "parentCategory": "Bicycles And Mopeds",
    "attributes": { "condition": "Zo goed als nieuw", "delivery": "Ophalen" },
    "extendedAttributes": { "material": "Aluminium", "frameHeight": "57 tot 61 cm", "numberOfGears": "Meer dan 20 versnellingen" },
    "promoted": true,
    "sellerId": 59814492,
    "sellerName": "Joris",
    "sellerType": "private",
    "sellerVerified": false,
    "viewCount": 142,
    "favoritedCount": 7,
    "scrapedAt": "2026-06-19T16:39:31.711Z"
}
```

A seller lead record (`type: "sellerLead"`) carries `sellerName`, `sellerType` (private/business), `smbVerified`, `rating`, `reviewCount`, `website`, `activeAds`, `city`, `categories`, `minPrice`/`maxPrice`, `sampleListings`, `sellerUrl` and a **`leadScore` (0–100)**.

#### What to expect (field coverage)

Marktplaats is seller-entered data, so some fields appear only when the seller filled them in. Typically you can expect:

| Field group | Always present | Usually present | Present when published |
|---|---|---|---|
| **Core** | listingId, title, url, priceType, category, seller, location | price ~85% (fixed-price ads), images ~95%, condition ~80% | province |
| **Attributes** | — | category-specific specs (mileage, size, storage…) on cars/bikes/electronics | extended specs |
| **Detail mode** | full description, category path | view & favourite counts | bids (bidding ads) |
| **Seller lead** | sellerName, sellerType, lead score | reviews & rating (active sellers), business-verified | website (business sellers, with enrichment) |

A blank field means the seller didn't publish it — not that scraping failed. Nothing is dropped, so you always get the richest dataset available.

### Monitor mode — only new ads & price drops

Turn on **monitorMode** and the actor remembers every ad it has seen in a named key-value store, then on each later run emits **only** ads that are **new** or whose **price changed** — each tagged with a `changeType` of `new`, `price_drop` or `price_rise`.

It's built to **complement** [Apify Schedules](https://docs.apify.com/platform/schedules), not collide with them: the schedule decides *when* the run starts; monitor mode decides *what's worth returning*. Schedule it hourly/daily on a keyword and pipe the output to Slack or email to get first-mover alerts on new listings and price drops. Use a different **monitorKey** per feed to track several searches independently.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily/hourly to catch new ads and price drops with monitor mode.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/marktplaats-scraper').call({
    searchQueries: ['iphone 15'],
    maxItems: 100,
    includeSellerLeads: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new ads or seller leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search adds a listing or a price drops.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find every business seller listing iPhones under €400 within 25 km of Amsterdam" and let it run the scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **classifieds & marketplace intelligence stack**:

- **[Kleinanzeigen Scraper](https://apify.com/scrapesage/kleinanzeigen-scraper)** — Germany's #1 classifieds, ads & seller leads.
- **[Kijiji Scraper](https://apify.com/scrapesage/kijiji-scraper)** — Canada's #1 classifieds across cars, real estate & for-sale.
- **[Gumtree Scraper](https://apify.com/scrapesage/gumtree-scraper)** — UK classifieds with listings & seller leads.
- **[Subito Scraper](https://apify.com/scrapesage/subito-scraper)** — Italy's #1 classifieds.
- **[OLX Brazil Scraper](https://apify.com/scrapesage/olx-brazil-scraper)** — Brazil's #1 classifieds & dealer leads.
- **[Craigslist Scraper](https://apify.com/scrapesage/craigslist-scraper)** — US classifieds across every category.
- **[eBay Scraper](https://apify.com/scrapesage/ebay-scraper)** — products, prices & seller leads across 10 marketplaces.
- **[AutoScout24 Scraper](https://apify.com/scrapesage/autoscout24-scraper)** — pan-European car marketplace & dealer leads.

### Tips

- **Start broad, then filter.** Run a keyword first, then add `minPrice`/`maxPrice`, `condition`, `sellerType` or a `postcode` + `distanceKm` radius to focus the feed.
- **Seller leads:** turn on `includeSellerLeads` (and `enrichSellerContacts` for websites) to turn a search into a list of dealers/businesses with reviews, ratings and a 0–100 lead score.
- **Detail mode is opt-in.** Search cards are already rich; enable `includeListingDetails` only when you need the full description, view/favourite counts or every attribute — it adds one request per ad.
- **Recurring monitoring:** combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` and a unique `monitorKey` per search for new-ad and price-drop alerts.

### FAQ

**How do I scrape a specific category?** Pass a `categoryId` (found in any category URL), or simply paste a category browse URL (`/l/…`) into Start URLs. You can combine a category with a keyword.

**Does it need the Marktplaats API or a key?** No. This actor reads Marktplaats's own public search API and ad pages — no key, login or browser required.

**Can I filter by location?** Yes — set a Dutch `postcode` and a `distanceKm` radius to only return ads within that area.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I get alerts for new ads or price drops?** Enable `monitorMode`, create a [Schedule](https://docs.apify.com/platform/schedules), and add a [webhook](https://docs.apify.com/platform/integrations/webhooks) or [Zapier zap](https://docs.apify.com/platform/integrations/zapier) to push new records to your CRM, Slack or email.

**A field is empty — why?** Some ads have no fixed price (bidding/free/on request), some sellers skip attributes, and not every ad has a description. Fields are blank only when the seller didn't publish that data — never because the scraper skipped it.

**Is scraping Marktplaats legal?** This actor collects publicly available data only. You're responsible for using the data in compliance with applicable laws (e.g. GDPR for personal data) and Marktplaats's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

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

Keywords to search Marktplaats.nl for, e.g. <code>iphone</code>, <code>racefiets</code>, <code>bmw e46</code>, <code>bank</code>, <code>ps5</code>. Each keyword is scraped as its own feed. Leave empty if you only use a Category or Start URLs.

## `startUrls` (type: `array`):

Marktplaats.nl URLs to scrape directly: search pages (<code>/q/\<keyword>/</code>), category / browse pages (<code>/l/\<category>/</code>), ad pages (<code>/v/.../m1234...</code>) and seller storefronts (<code>/u/.../\<id>/</code>). Used in addition to the keyword search.

## `categoryId` (type: `string`):

Optional Marktplaats category ID to scope the search/browse (e.g. <code>91</code> = Auto's, <code>322</code> = Telecommunicatie, <code>504</code> = Fietsen en Brommers). Find it in any category URL. Combine with a keyword or leave the keyword empty to browse the whole category.

## `listingUrls` (type: `array`):

Marktplaats ad URLs to fetch full detail for directly (<code>/v/.../m1234567890-...</code>).

## `sellerUrls` (type: `array`):

Marktplaats seller storefront URLs (<code>/u/\<name>/\<id>/</code>) to scrape all of a seller's ads and (optionally) build a seller lead.

## `postcode` (type: `string`):

Dutch postcode to centre a distance search on, e.g. <code>1011</code> (Amsterdam) or <code>3011</code> (Rotterdam). Pair with Distance.

## `distanceKm` (type: `integer`):

Radius in kilometres around the postcode to include ads from.

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

Only keep ads priced at least this much (euros). Ads without a fixed price (bidding / free / 'on request') are kept unless you set a max price.

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

Only keep ads priced at most this much (euros).

## `condition` (type: `string`):

Only keep ads with this item condition.

## `sellerType` (type: `string`):

Keep only ads from private sellers or from businesses / dealers.

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

How Marktplaats orders the results.

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

Maximum number of ad records to scrape across all searches/URLs.

## `includeListingDetails` (type: `boolean`):

Open each ad to add the full untruncated description, every structured attribute, complete image gallery, category breadcrumb, view count, favourite count and bidding info. Turn OFF for a faster/cheaper run (the search card already includes title, price, location, images, key attributes and seller). Adds one request per ad.

## `includeSellerLeads` (type: `boolean`):

Output one deduplicated lead record per seller seen in the run: name, private/business type, business-verified flag, review count & rating, storefront URL, website, active-ad count, sample listings, price range and a 0-100 lead score. Best for finding dealers and active businesses.

## `enrichSellerContacts` (type: `boolean`):

For business / dealer sellers, open their storefront to add their website, extra contact details and accurate active-ad count. Adds one request per business seller.

## `maxSellerLeads` (type: `integer`):

Maximum number of seller lead records to output.

## `deduplicateListings` (type: `boolean`):

Drop duplicate ads that appear in more than one search/page in the same run.

## `monitorMode` (type: `boolean`):

Remember ads across runs in a named key-value store and emit ONLY ads that are new OR whose price changed since the last run (each carries a <code>changeType</code>: new / price\_drop / price\_rise). Pair with Apify Schedules for new-ad & price-drop alerts — it complements the scheduler (the schedule starts the run; monitor mode dedupes against prior runs).

## `monitorKey` (type: `string`):

Names the monitor's memory store so you can run several independent monitors (e.g. one per keyword). Reuse the same key to keep tracking the same feed.

## `maxConcurrency` (type: `integer`):

Parallel detail/seller request fetches. Keep moderate (3–6).

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

Proxies to use. Marktplaats serves its internal API cleanly to Apify residential proxies — keep the default (residential, Netherlands).

## Actor input object example

```json
{
  "searchQueries": [
    "iphone"
  ],
  "condition": "any",
  "sellerType": "any",
  "sort": "default",
  "maxItems": 100,
  "includeListingDetails": false,
  "includeSellerLeads": false,
  "enrichSellerContacts": false,
  "maxSellerLeads": 200,
  "deduplicateListings": true,
  "monitorMode": false,
  "monitorKey": "default",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped Marktplaats classified-ad records and optional seller lead records as JSON items 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 = {
    "searchQueries": [
        "iphone"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/marktplaats-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"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/marktplaats-scraper").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 '{
  "searchQueries": [
    "iphone"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapesage/marktplaats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/marktplaats-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/XAg5yZlAN1bXYhVH0/builds/6m2KJFvShDy3V6q0n/openapi.json
