# Marktplaats Scraper — NL Classified Ads & Monitor (`crawloop/marktplaats-scraper`) Actor

Scrape marktplaats.nl classified ads: titles, prices, descriptions, images, seller info, bids, shipping, and location. Search by keyword, Dutch postcode + radius, or URL. Monitor mode, Telegram & Discord alerts. Export JSON/CSV.

- **URL**: https://apify.com/crawloop/marktplaats-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 scraped listings

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

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

## What's an Apify Actor?

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 — Netherlands Classified Ads, Prices & Listing Monitor

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by Marktplaats or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

Extract **structured classified ads data** from the Netherlands' largest marketplace — `marktplaats.nl`. Search by keyword, Dutch postal code (Postcode) + radius, price range, or paste a pre-filtered browser URL. Parses full listing descriptions, dynamic attributes (brand, model, storage, condition, etc.), **high-resolution images**, seller profile metrics (account type, active years, verification status), location data, view counts, shipping options, and bid histories.

Includes **monitoring mode** with delta tracking and native **Telegram & Discord webhooks** for real-time alerts when new listings appear or prices change.

**Best for:** Marktplaats price research, Dutch classifieds monitoring, resale arbitrage alerts, local deal hunting by postcode, and bulk JSON/CSV export via Apify integrations.

### When to use this Actor

- **Marktplaats price tracking** — Collect listing prices, attributes, and locations for market averages and trend analysis across phones, cars, furniture, and more.
- **Real-time deal hunting & arbitrage** — Run in monitor mode every 1–5 minutes and get instant Telegram or Discord alerts for newly listed underpriced items.
- **Local inventory matching** — Search by Postcode + radius (e.g. iPhone 15 Pro within 25 km of Amsterdam) to find pickup-friendly deals.
- **Category & filter scraping** — Copy any filtered search URL from your browser (category, brand, price, condition) into Start URLs for exact replication.
- **Seller trust signals** — Parse verification status, seller type (consumer vs trader), and active-since metrics alongside each listing.

### When not to use this Actor

- **Private messages or seller contact** — This Actor reads public listing pages only; it does not access Marktplaats messaging or in-app chat.
- **Account-authenticated actions** — No login, favorites, or saved-search API; use Start URLs for pre-built filter combinations instead.
- **Heavy JavaScript SPAs outside Marktplaats** — Built specifically for `marktplaats.nl` search and detail pages, not generic web scraping.

### Key Features

- **Lightweight & fast** — Runs on **128–512 MB RAM** with efficient HTTP requests — no heavy headless browser required.
- **Full image extraction** — All available high-resolution listing images, not just search-result thumbnails.
- **Postcode + radius search** — Dutch postal code geolocation with configurable km radius (3–150 km).
- **Detail-page enrichment** — View counts, favorites, shipping options, bid lists, and full attribute tables when `scrapeDetails` is enabled.
- **Seller profile parsing** — Account type, active years, and verification status from public listing data.
- **Telegram & Discord alerts** — Native webhook support in input config: images, prices, location, and description snippets on new listings.
- **Smart monitoring** — Key-Value store tracks seen listing IDs and prices; stops pagination early when consecutive known ads are found.
- **Parallel detail fetching** — Configurable concurrency for faster bulk runs on large result sets.

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | `[]` | Direct URLs to search results, categories, or individual listings. Filters from the URL are preserved. |
| `searchQuery` | String | — | Search term (e.g. `iphone 15 pro`). Ignored when Start URLs are provided. |
| `postalCode` | String | — | Dutch postal code (Postcode) to restrict search to a region. |
| `radius` | String | `"0"` | Radius in km around Postcode: `3`, `5`, `10`, `15`, `25`, `50`, `75`, `100`, `150`. |
| `minPrice` / `maxPrice` | Number | — | Filter listings by price range (€). |
| `maxItems` | Integer | `100` | Maximum number of listings to collect. |
| `scrapeDetails` | Boolean | `true` | Visit detail pages for full gallery, stats, bids, and shipping. If false, collects cards from search results only. |
| `maxConcurrency` | Integer | `5` | Parallel detail-page fetches (1–15). Higher = faster; lower = more stable on large batches. |
| `monitorMode` | Boolean | `false` | Delta tracking: only new/updated listings in output; early stop on known ads. |
| `telegramToken` | String | — | Telegram Bot token for alert notifications. |
| `telegramChatId` | String | — | Telegram chat ID to receive alerts. |
| `discordWebhook` | String | — | Discord webhook URL for rich listing embed cards. |
| `proxyConfiguration` | Object | — | Apify Proxy settings. Netherlands (`NL`) residential proxy recommended for high volume. |

#### Input Example

```json
{
  "searchQuery": "iphone 15 pro",
  "postalCode": "1012",
  "radius": "25000",
  "minPrice": 400,
  "maxPrice": 900,
  "maxItems": 500,
  "scrapeDetails": true,
  "maxConcurrency": 5,
  "monitorMode": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "NL"
  }
}
```

### Output Format

Each dataset row = one parsed Marktplaats listing.

| Field | Type | Description |
| :--- | :--- | :--- |
| `adId` | String | Unique Marktplaats listing ID. |
| `url` | String | Canonical listing URL. |
| `title` | String | Ad headline. |
| `price` | Number | Numeric price in EUR when fixed; null for auction-only listings. |
| `priceType` | String | e.g. `FIXED`, `MIN_BID`, `FAST_BID`, `SEE_DESCRIPTION`. |
| `description` | String | Full listing description text. |
| `location` | Object | City, postcode, country, latitude, longitude when available. |
| `shipping` | Object | Shipping options and carrier labels from detail page. |
| `attributes` | Object | Dynamic key/value pairs (condition, storage, model, etc.). |
| `images` | Array | High-resolution image URLs. |
| `seller.id` | Number | Seller account ID. |
| `seller.name` | String | Public seller display name. |
| `seller.type` | String | e.g. `CONSUMER`, `TRADER`. |
| `seller.active_since` | String | How long the seller has been active on Marktplaats. |
| `seller.isVerified` | Boolean | Verification badge status. |
| `stats.viewCount` | Number | Listing view count (detail scrape). |
| `stats.favoritedCount` | Number | Times saved to favorites (detail scrape). |
| `stats.since` | String | Exact publish timestamp (ISO 8601). |
| `bids` | Array | Current bids with value, date, and bidder nickname (when bidding enabled). |
| `publishedDate` | String | Listing publish date/time. |
| `scrapedAt` | String | Extraction timestamp (UTC ISO 8601). |

#### Output Example

```json
{
  "adId": "m2416596985",
  "url": "https://www.marktplaats.nl/v/telecommunicatie/mobiele-telefoons-apple-iphone/m2416596985-iphone-13-pro",
  "title": "iPhone 13 pro",
  "price": 275.0,
  "priceType": "MIN_BID",
  "description": "Selling my wife's iPhone 13 pro 128GB. Very good condition, battery health 76%. Pick up in Amstelveen.",
  "location": {
    "city": "Amstelveen",
    "postcode": "1181",
    "country": "Nederland",
    "latitude": 52.290225,
    "longitude": 4.841126
  },
  "shipping": {
    "augmentedLabels": [
      {
        "carrierId": "dhl-nl",
        "labels": [
          {
            "label": "Afhaalpunt via DHL voor",
            "price": "€ 2,89",
            "carrierName": "DHL",
            "deliveryMethod": "PICK_UP"
          }
        ]
      }
    ]
  },
  "attributes": {
    "Conditie": "Zo goed als nieuw",
    "Opslagcapaciteit": "128 GB",
    "Abonnement": "Zonder abonnement",
    "Simlock": "Zonder simlock"
  },
  "images": [
    "https://images.marktplaats.com/api/v1/hz-mp-pro-listing/images/a37247a3-38a9-4f66-8e8a-e5de7be6ff0e?rule=ecg_mp_eps$_85.jpg"
  ],
  "seller": {
    "id": 22317049,
    "name": "Mihai Filer",
    "type": "CONSUMER",
    "active_since": "11 jaar",
    "isVerified": true
  },
  "stats": {
    "viewCount": 78,
    "favoritedCount": 1,
    "since": "2026-07-03T12:46:35Z"
  },
  "bids": [
    {
      "id": 1548714969,
      "value": 27500,
      "date": "2026-07-03T16:04:18Z",
      "user": { "id": 52047226, "nickname": "JB" }
    }
  ],
  "publishedDate": "2026-07-03T12:46:35Z",
  "scrapedAt": "2026-07-03T18:55:10.397Z"
}
```

### Use Cases

| Use Case | What you get |
| :--- | :--- |
| **Resale arbitrage** | New-listing alerts with price, photos, and location for flip opportunities |
| **Market pricing** | Structured price + attribute datasets per keyword or category |
| **Local deal hunting** | Postcode + radius filters for pickup-friendly Dutch classifieds |
| **Automotive & spec-heavy sourcing** | Full attribute tables for cars, phones, and electronics |
| **Data pipelines** | JSON/CSV export or webhook integrations to Sheets, databases, and BI tools |
| **AI / MCP workflows** | Run via Apify API, clients, or MCP and summarize Dutch classifieds |

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/marktplaats-scraper').call({
  searchQuery: 'iphone 15 pro',
  postalCode: '1012',
  radius: '25000',
  maxItems: 50,
  scrapeDetails: true,
  proxyConfiguration: {
    useApifyProxy: true,
    apifyProxyGroups: ['RESIDENTIAL'],
    apifyProxyCountry: 'NL',
  },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token)
run = client.actor("crawloop/marktplaats-scraper").call(
    run_input={
        "searchQuery": "iphone 15 pro",
        "postalCode": "1012",
        "radius": "25000",
        "maxItems": 50,
        "scrapeDetails": True,
        "proxyConfiguration": {
            "useApifyProxy": True,
            "apifyProxyGroups": ["RESIDENTIAL"],
            "apifyProxyCountry": "NL",
        },
    }
)
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(len(items), items[:3])
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~marktplaats-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQuery": "iphone 15 pro",
    "postalCode": "1012",
    "radius": "25000",
    "maxItems": 50,
    "scrapeDetails": true,
    "proxyConfiguration": {
      "useApifyProxy": true,
      "apifyProxyGroups": ["RESIDENTIAL"],
      "apifyProxyCountry": "NL"
    }
  }'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/marktplaats-scraper`.

Example prompts:

- "Run Marktplaats Scraper for iphone 15 pro near postcode 1012, max 50, and return title, price, location, url"
- "Scrape Marktplaats listings for RTX 4090 and summarize the cheapest 10"
- "Chain Marktplaats Scraper then Kleinanzeigen Scraper for the same keyword and compare NL vs DE prices"

### Suite next step

For German classifieds, use [Kleinanzeigen Scraper](https://apify.com/crawloop/kleinanzeigen-scraper). For German vehicles, use [Mobile.de Scraper](https://apify.com/crawloop/mobile-de-scraper).

### Related Actors

| Actor | What it covers |
| :--- | :--- |
| **Marktplaats Scraper** ◄── you are here | Dutch classifieds + monitor alerts |
| [Kleinanzeigen Scraper](https://apify.com/crawloop/kleinanzeigen-scraper) | German classifieds + monitor alerts |
| [Mobile.de Scraper](https://apify.com/crawloop/mobile-de-scraper) | German vehicle marketplace |
| [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) | eBay completed sales / sold comps |

### FAQ

#### How is this different from a generic web scraper?

This Actor is built specifically for `marktplaats.nl`: search pagination, Dutch attribute parsing, seller metrics, bid history, monitor-mode delta tracking, and Telegram/Discord alerts — out of the box.

#### Do I need proxies?

For high-volume runs (500–1000+ listings), aggressive monitoring (every 1 minute), or detail scraping at scale, use **Apify Residential Proxies** with **Netherlands (`NL`) country targeting** for best reliability.

#### Can I scrape specific categories or advanced filters?

Yes. Open `marktplaats.nl` in your browser, apply all filters (category, brand, price, condition, sort), copy the URL from the address bar, and paste it into **Start URLs** (`startUrls`). This is the most reliable way to replicate complex filter combinations.

#### How does Monitoring Mode work?

With `monitorMode: true`, listing IDs and prices are stored in the default Key-Value Store. On each run the Actor scans from the top of search results. New or price-changed listings are written to the dataset and sent to Telegram/Discord. After **5 consecutive** already-known unchanged ads, pagination stops to save compute.

#### Can I scrape 1000+ listings in one run?

Yes. Set `maxItems` to your target (e.g. 1000) and tune `maxConcurrency` (default 5). Use Netherlands residential proxies for large batches with `scrapeDetails: true`. Pagination walks search result pages automatically until the limit is reached or results are exhausted.

#### Does it export to JSON / CSV / API?

Yes. Results are written to the Apify dataset. Download JSON, CSV, or Excel from the run, or connect webhooks and integrations (Google Sheets, BigQuery, custom API endpoints, etc.).

# Actor input Schema

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

Direct URLs to Marktplaats.nl search results, category pages, or individual listings. Copy a filtered browser URL for exact category/price/condition replication.

## `searchQuery` (type: `string`):

Keyword to search on Marktplaats (e.g. 'iPhone 15 Pro', 'Volkswagen Golf'). Leave empty if using Start URLs.

## `postalCode` (type: `string`):

Dutch postal code (e.g. '1012' or '1012 JS') to restrict search to a region.

## `radius` (type: `string`):

Search radius in km around the postal code. Only applies when Postal Code is set.

## `minPrice` (type: `number`):

Minimum listing price in euros.

## `maxPrice` (type: `number`):

Maximum listing price in euros.

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

Maximum number of Marktplaats listings to collect per run.

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

Visit each listing page for full gallery, view counts, bids, shipping options, and detailed seller info. Recommended for complete datasets.

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

How many listing detail pages to fetch in parallel. Default 5. Lower values improve stability on large batches.

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

Delta monitoring: only output new or price-updated listings. Stops pagination early when consecutive known ads are found.

## `telegramToken` (type: `string`):

Telegram Bot token for real-time new-listing notifications.

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

Telegram chat ID to receive listing alerts.

## `discordWebhook` (type: `string`):

Discord webhook URL for rich listing embed notifications.

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

Apify Proxy settings. Netherlands (NL) residential proxy recommended for 500+ listings or detail scraping at scale.

## Actor input object example

```json
{
  "startUrls": [],
  "searchQuery": "iphone",
  "radius": "0",
  "maxItems": 100,
  "scrapeDetails": true,
  "maxConcurrency": 5,
  "monitorMode": false
}
```

# Actor output Schema

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

Dataset of Marktplaats ads (price, images, seller, location).

# 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 = {
    "startUrls": [],
    "searchQuery": "iphone"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/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 = {
    "startUrls": [],
    "searchQuery": "iphone",
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/marktplaats-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/3gcrf2Pdfsil568jU/builds/Ij6YV2Ry3Z4xBmBPt/openapi.json
