Marktplaats.nl Scraper
Pricing
from $1.50 / 1,000 results
Marktplaats.nl Scraper
Marktplaats scraper & API (Netherlands classifieds): search listings by keyword & category and export title, price, description, location, seller, attributes, photos, date and URL. Dutch marketplace, resale and second-hand market data plus seller lead gen — fast, no login.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Haketa
Maintained by CommunityActor stats
1
Bookmarked
99
Total users
12
Monthly active users
a day ago
Last modified
Categories
Features
Share
Marktplaats.nl Scraper — Netherlands & Belgium Classifieds Data (Marktplaats, 2dehands.be & 2ememain.be)
Extract live classified listings from Marktplaats.nl (Netherlands), 2dehands.be (Belgium — Flemish), and 2ememain.be (Belgium — French) in one unified schema.
For every ad, this Marktplaats scraper captures the listing title, numeric EUR price, normalized price type (fixed, bidding, free, asking, negotiable), normalized item condition (new, like_new, used), category and subcategory names + IDs, seller name, seller ID, seller type (private vs business / zakelijk), city, country, GPS coordinates (latitude / longitude), category-specific attributes, high-resolution images, shipping availability, and canonical URL.
Export your dataset to JSON, CSV, Excel (XLSX), XML, or the Apify API with zero coding and no login.
Built for Benelux e-commerce & recommerce pricing teams, used-car dealers and arbitrage analysts, real-estate and rental researchers, B2B dealer lead-generation agencies, brand-protection teams, and marketplace intelligence analysts.
⚡ At a glance
| Feature | Details |
|---|---|
| Supported Platforms | 🇳🇱 marktplaats.nl (Netherlands), 🇧🇪 2dehands.be (Belgium NL), 🇧🇪 2ememain.be (Belgium FR) |
| Search Modes | Keyword search (single or comma-separated multi-keyword), 20 L1 category dropdowns, L2 subcategory ID, or combined keyword + category |
| Targeting & Filters | Seller type (all, private / particulier, business / zakelijk), item condition (new, like_new, used), min/max price (EUR cents), postcode + radius (distanceMeters), sort order (SORT_INDEX, PRICE, OPTIMIZED) |
| Core Extracted Fields | listingId, title, price, priceType, condition, category, subcategory, sellerName, sellerId, sellerType, location, latitude, longitude, attributes, images, description, url |
| Detail Enrichment | Optional scrapeDetails: true visits each listing page for full-length descriptions and extended specifications |
| Pagination & Scale | Automatic offset pagination unlocking 1,000+ to 5,000+ listings per search or multi-keyword run with 0 duplicates |
| Empty-Input Behavior | Running with {} automatically returns a balanced 100-item sample across 10 popular Benelux categories |
| Authentication | None required — keyless & browser-free |
| Export Formats | JSON, JSONL, CSV, Excel (XLSX), HTML, XML, RSS, and Apify REST API |
🔎 Why scrape Marktplaats, 2dehands.be & 2ememain.be?
With over 10 million active listings and millions of daily transactions, Marktplaats.nl is the indisputable backbone of the Dutch second-hand and dealer marketplace economy — from used cars (Auto's), auto parts, bicycles (Fietsen en Brommers), and consumer electronics (Telecommunicatie, Computers) to furniture, fashion, real estate, and commercial services. Together with its Belgian sister platforms 2dehands.be and 2ememain.be, it covers the entire Benelux classifieds market.
Collecting and analyzing Benelux marketplace data manually is slow and error-prone:
- Prices are stored in euro cents and mixed with non-numeric types (Bieden, Gratis, Zie omschrijving, Nader overeen te komen).
- Condition and price-type labels appear in Dutch or French depending on the platform.
- Category names are separated from listing records in facet trees.
- Vertical-specific specs (car mileage, build year, fuel type, phone storage, battery health) are split across multiple attribute structures.
This Marktplaats scraper normalizes all three platforms into a single, analysis-ready schema — converting cents to EUR, mapping Dutch and French labels into standardized English codes while preserving original strings, resolving category and subcategory names automatically, and deduplicating every record by listingId.
Key business benefits
- Live Benelux price benchmarking: Track median and percentile asking prices by product model, storage capacity, build year, and item condition across the Netherlands and Belgium.
- Used-car & vehicle arbitrage: Monitor
Auto's(91),Auto-onderdelen(92), andFietsen en Brommers(1655) for undervalued private-seller inventory (sellerType: "private") before competing dealers spot them. - Commercial seller (
zakelijk) lead generation: FiltersellerTypeFilter: "business"to build verified B2B prospect lists of Dutch and Belgian car dealerships, electronics refurbishers, furniture showrooms, and trade contractors. - Recommerce & circular-economy analytics: Measure listing velocity, regional supply density (via
latitude/longitude), and second-hand depreciation curves. - Brand protection & grey-market monitoring: Detect counterfeit goods, unauthorized commercial resellers, and MAP violations across all three Benelux marketplaces.
✨ Key features
- ✅ 3-in-1 Benelux coverage: Scrape Marktplaats.nl, 2dehands.be, and 2ememain.be with a single dropdown (
platform) and identical output fields. - ✅ 1,000+ listing deep pagination: Automatically advances through search pages (30 listings per page) up to your
maxListingstarget, and supports comma-separated multi-keyword queries to scale past single-query limits. - ✅ Bilingual label normalization: Maps Dutch (Vaste prijs, Bieden, Gratis, Zo goed als nieuw, Gebruikt) and French (Prix fixe, Faire offre, Gratuit, Comme neuf, Utilisé) into standardized English enums (
fixed,bidding,free,like_new,used) while keepingpriceTypeOriginalandconditionOriginal. - ✅ Automatic category & subcategory name resolution: Harvests L1 and L2 category labels from the marketplace facet tree so every listing includes both human-readable names (
category,subcategory) and stable numeric IDs (categoryId,subcategoryId). - ✅ Seller segmentation (
privatevsbusiness): Identifies commercial EU SOI-498 business accounts (zakelijk) vs private individuals (particulier) and lets you filter at run time. - ✅ Postcode & radius geo-targeting: Center searches on any Dutch (
1012AB) or Belgian (2000) postcode with a customdistanceMetersradius, and export exact listinglatitudeandlongitude. - ✅ High-resolution image & attribute extraction: Normalizes protocol-relative image URLs to
https://at maximum resolution and merges all vertical attributes (attributes+extendedAttributes+verticals) into one clean object.
🎯 Use cases
1. Used-car dealership sourcing & BPM valuation
Dutch and European car dealers track private listings (sellerTypeFilter: "private") in category 91 (Auto's) sorted by newest first (SORT_INDEX + DECREASING), capturing price, location, seller ID, and car attributes to spot underpriced vehicles within minutes of listing.
2. Recommerce & electronics trade-in pricing
Refurbished phone, laptop, and audio retailers scrape iPhone, MacBook, Samsung Galaxy, and PlayStation listings across new, like_new, and used conditions to calibrate automated trade-in and buyback pricing engines.
3. B2B lead generation (zakelijk sellers)
Marketing agencies and B2B SaaS vendors filter sellerTypeFilter: "business" across categories like Huis en Inrichting (322), Auto's (91), or Diensten en Vakmensen (34) to identify active commercial merchants on Marktplaats and 2dehands.be, grouping by sellerId to rank top-volume dealers.
4. Local supply & real-estate research
Analysts monitor category 135 (Huizen en Kamers) and 356 (Vakantie) alongside postcode radius filters to track private room rentals, garage boxes, vacation chalets, and commercial spaces across Dutch provinces.
📥 Input parameters
All fields are optional. If you run the Actor with empty input ({}), it automatically collects a fresh, balanced 100-listing sample across 10 popular Dutch search terms.
| Parameter | Type | Default | Description |
|---|---|---|---|
platform | string | "marktplaats.nl" | Marketplace to scrape: "marktplaats.nl" (Netherlands), "2dehands.be" (Belgium NL), or "2ememain.be" (Belgium FR). |
query | string | "" (prefill "iphone") | Search keyword(s) matched against title and description (e.g. "iphone 15", "bmw 320d", "vouwfiets"). Supports comma-separated keywords (e.g. "iphone 15, iphone 16, samsung s24") for multi-query sweeps. |
category | string | "" (All categories) | L1 category dropdown: Cars (91), Car parts (92), Bikes & mopeds (1655), Houses & rooms (135), Home & furniture (322), Phones & telecom (31), Computers (504), Audio/TV/Photo (1525), Clothing (621), Sport (728), Kids (1099), Antiques (367), Tickets (2017), Books (380), Holidays (356), Jobs (33), Services (34), etc. |
subcategoryId | string | "" | Optional L2 subcategory numeric ID (e.g. "1953" for Apple iPhone inside Telecom). |
sellerTypeFilter | string | "all" | Filter by seller type: "all", "private" (particulier), or "business" (zakelijk / dealer). |
conditionFilter | array<string> | [] | Keep only selected conditions: "new" (Nieuw), "like_new" (Zo goed als nieuw), "used" (Gebruikt). Empty = all conditions. |
postcode | string | "" | Dutch or Belgian postcode to center a radius search (e.g. "1012AB" Amsterdam, "3011AA" Rotterdam, "2000" Antwerp). |
distanceMeters | integer | 0 | Search radius around postcode in meters (e.g. 10000 = 10 km, 50000 = 50 km). 0 = nationwide. |
minPrice | integer | 0 | Minimum price in euro cents (10000 = €100.00). 0 = no minimum. |
maxPrice | integer | 0 | Maximum price in euro cents (100000 = €1,000.00). 0 = no maximum. |
sortBy | string | "SORT_INDEX" | Sort order: "SORT_INDEX" (newest first), "PRICE" (by price), or "OPTIMIZED" (best relevance match). |
sortOrder | string | "DECREASING" | Sort direction: "DECREASING" (high-to-low / newest first) or "INCREASING" (low-to-high / oldest first). |
scrapeDetails | boolean | false | When true, also opens each individual listing page to enrich the full-length description and detail-only attributes. |
maxListings | integer | 0 (prefill 100) | Maximum total listings to collect. Set 0 for unlimited (up to 1,000–5,000+ listings per search or multi-keyword run). |
requestDelay | integer | 500 | Pause between page requests in milliseconds (0–10000). |
proxyConfiguration | object | { "useApifyProxy": true } | Apify Proxy configuration. Default datacenter proxy works out of the box. |
Example input — 1,000+ iPhone & smartphone price benchmark (NL)
{"platform": "marktplaats.nl","query": "iphone 15, iphone 16","category": "31","sellerTypeFilter": "all","conditionFilter": ["new", "like_new", "used"],"minPrice": 20000,"maxPrice": 150000,"sortBy": "SORT_INDEX","sortOrder": "DECREASING","scrapeDetails": false,"maxListings": 1000,"proxyConfiguration": {"useApifyProxy": true}}
Example input — Belgian used cars from private sellers (2dehands.be)
{"platform": "2dehands.be","query": "volkswagen golf","category": "91","sellerTypeFilter": "private","postcode": "2000","distanceMeters": 50000,"sortBy": "PRICE","sortOrder": "INCREASING","maxListings": 500}
📤 Output schema & field reference
Every listing is saved as a flat, normalized JSON object across all three Benelux platforms.
🏷️ Core Listing & Pricing Fields
| Field | Type | Coverage | Description |
|---|---|---|---|
listingId | string | 🟢 High (100%) | Unique marketplace listing ID (e.g. "m2460844151"). Used for automatic deduplication. |
platform | string | 🟢 High (100%) | Source marketplace: "marktplaats.nl", "2dehands.be", or "2ememain.be". |
title | string | 🟢 High (100%) | Full ad title as displayed on the marketplace. |
price | number | null | 🟢 High (~92%) | Numeric asking price in EUR (converted from cents). null when priceType is bidding, free, or see_description. |
priceType | string | 🟢 High (100%) | Normalized price type: fixed, bidding, free, asking, trade, negotiable, on_request, see_description, or reserved. |
priceTypeOriginal | string | 🟢 High (100%) | Original Dutch or French price label (Vaste prijs, Bieden, Gratis, Prix fixe, Faire offre). |
currency | string | 🟢 High (100%) | Always "EUR". |
condition | string | null | 🟢 High (~95%) | Normalized item condition: new, like_new, used, or not_applicable. |
conditionOriginal | string | null | 🟢 High (~95%) | Original Dutch or French condition string (Nieuw, Zo goed als nieuw, Gebruikt, Comme neuf). |
📂 Category, Specifications & Media
| Field | Type | Coverage | Description |
|---|---|---|---|
category | string | null | 🟢 High (~99%) | Human-readable L1 category name (e.g. "Telecommunicatie", "Auto's"). |
categoryId | string | null | 🟢 High (100%) | Numeric L1 category ID (e.g. "31", "91"). |
subcategory | string | null | 🟢 High (~95%) | Human-readable L2 subcategory name (e.g. "Mobiele telefoons | Apple iPhone"). |
subcategoryId | string | null | 🟢 High (100%) | Numeric L2 subcategory ID (e.g. "1953"). |
attributes | object | null | 🟢 High (~98%) | Category-specific key/value attributes (e.g. storage, battery health, color, delivery, bouwjaar, kilometerstand). |
description | string | null | 🟢 High (100%) | Listing description snippet (or full text when scrapeDetails: true). |
images | array<string> | null | 🟢 High (~99%) | Deduplicated array of absolute https:// high-resolution image URLs. |
shippingAvailable | boolean | 🟢 High (100%) | true if Marktplaats/2dehands shipping (verzendservice) is enabled on the listing. |
👤 Seller, Geo-Location & Metadata
| Field | Type | Coverage | Description |
|---|---|---|---|
sellerName | string | null | 🟢 High (100%) | Seller or dealership display name. |
sellerId | string | null | 🟢 High (100%) | Unique internal seller ID — ideal for grouping all listings from a single dealer. |
sellerType | string | 🟢 High (100%) | "private" (particulier) or "business" (zakelijk commercial seller). |
location | string | null | 🟢 High (100%) | Seller city or municipality (e.g. "Amsterdam", "Rotterdam", "Antwerpen"). |
country | string | null | 🟢 High (100%) | Country name ("Nederland" or "België"). |
latitude | number | null | 🟢 High (~99%) | Approximate listing latitude for geographic heatmaps and distance calculations. |
longitude | number | null | 🟢 High (~99%) | Approximate listing longitude. |
date | string | null | 🟢 High (100%) | Listing date label ("Vandaag", "Gisteren", "Eergisteren", or date string). |
url | string | 🟢 High (100%) | Full canonical URL to the listing on Marktplaats.nl, 2dehands.be, or 2ememain.be. |
searchQuery | string | null | 🟢 High | Search keyword that produced the record. |
searchCategory | string | null | 🟡 Conditional | Category filter ID used in the search, if any. |
scrapedAt | string | 🟢 High (100%) | ISO-8601 UTC extraction timestamp. |
Sample output record
{"listingId": "m2460844151","platform": "marktplaats.nl","title": "Apple iPhone 16 Blauw 128GB - Zo goed als nieuw","price": 600,"priceType": "fixed","priceTypeOriginal": "Vaste prijs","currency": "EUR","condition": "like_new","conditionOriginal": "Zo goed als nieuw","category": "Telecommunicatie","categoryId": "820","subcategory": "Mobiele telefoons | Apple iPhone","subcategoryId": "1953","sellerName": "Artem","sellerId": "55707512","sellerType": "private","location": "Lemele","country": "Nederland","latitude": 52.458435120409,"longitude": 6.4229765265222,"date": "Vandaag","description": "Er zit een doos bij, maar deze is niet origineel. De kabel en het hoesje worden meegeleverd.","attributes": {"delivery": "Ophalen of Verzenden","battery health": "97 %","storage": "128 GB","color": "Blauw","type": "IPhone 16"},"images": ["https://images.marktplaats.com/api/v1/hz-mp-pro-listing/images/c37a528b-6f61-4d00-85c4-9ab03927645c?rule=ecg_mp_eps$_82.jpg"],"shippingAvailable": false,"url": "https://www.marktplaats.nl/v/telecommunicatie/mobiele-telefoons-apple-iphone/m2460844151-apple-iphone-16-blauw-128gb-zo-goed-als-nieuw","searchQuery": "iphone","searchCategory": null,"scrapedAt": "2026-11-10T02:00:00.000Z"}
🔁 Pagination & scaling to 1,000+ listings
- Automatic multi-page pagination: The scraper automatically steps through result pages (30 listings per request) until
maxListingsis reached or all matching ads are consumed. - 1,000+ to 10,000+ listings per run: Set
maxListings: 1000(or0for unlimited) to collect thousands of listings in a single run. You can also pass multiple comma-separated keywords inquery(e.g."iphone 14, iphone 15, iphone 16") to sweep entire product families across tens of thousands of listings. - Cross-page & cross-keyword deduplication: An in-memory
seenIdsset keyed onlistingIdguarantees 0 duplicate listings even when search terms overlap or new ads push pagination offsets mid-run.
⚙️ How to use & integrate
Python SDK example
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("haketa/marktplaats-scraper").call(run_input={"platform": "marktplaats.nl","query": "bmw 320d","category": "91","sellerTypeFilter": "all","postcode": "3011AA","distanceMeters": 50000,"sortBy": "PRICE","sortOrder": "INCREASING","maxListings": 1000,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{item['listingId']} | €{item['price']} ({item['priceType']}) | {item['title']} | {item['location']}")
Node.js SDK example
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('haketa/marktplaats-scraper').call({platform: 'marktplaats.nl',query: 'iphone 15, iphone 16',category: '31',subcategoryId: '1953',maxListings: 1000,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Extracted ${items.length} unique Marktplaats listings`);
💡 Pro tips for Benelux marketplace scraping
- Remember
minPriceandmaxPriceuse euro cents: Enter10000for €100 or250000for €2,500. To isolate free giveaway items (Gratis), setmaxPrice: 1. - Keep
scrapeDetails: falsefor fast bulk runs: The search response already includes price, condition, seller ID, coordinates, images, description snippet, and key vertical attributes (attributes). Turn onscrapeDetails: trueonly when you need the full un-truncated description text. - Segment large categories by price band or postcode: When scraping ultra-dense verticals like Auto's (
91) or Huis en Inrichting (322), combineminPrice/maxPricebrackets or comma-separated keywords inqueryto capture 10,000+ listings cleanly. - Switch
platformfor instant Belgian market comps: Compare Dutch and Belgian second-hand prices by running the exact same query againstmarktplaats.nl,2dehands.be, and2ememain.be.
❓ Frequently Asked Questions
How fast is the Marktplaats scraper?
With scrapeDetails: false (the default), the Actor collects 100 listings in ~10 seconds and 1,000 listings in ~60–90 seconds using lightweight HTTP requests.
Do I need residential proxies or a Marktplaats account?
No account or login is ever required. Standard Apify Proxy (useApifyProxy: true, enabled by default) works reliably for both Dutch and Belgian platforms without expensive residential proxy overhead.
Why is price sometimes null?
On Marktplaats and 2dehands.be, sellers can list items as Bieden (bidding), Gratis (free), Ruilen (trade), Zie omschrijving (see_description), or Nader overeen te komen (negotiable) without a fixed numeric price. Check priceType and priceTypeOriginal to see the exact pricing model.
Can I filter out commercial dealers or keep only business sellers?
Yes. Set sellerTypeFilter: "private" to keep only private individuals (particulieren), or sellerTypeFilter: "business" to extract only commercial sellers (zakelijke verkopers).
Does this Actor work for 2dehands.be and 2ememain.be in Belgium?
Yes. Select 2dehands.be (Dutch/Flemish) or 2ememain.be (French) in the platform dropdown. All output fields (priceType, condition, currency, latitude, longitude, etc.) are normalized to the exact same schema.
Can I scrape multiple keywords in a single run?
Yes — pass comma-separated keywords in query (for example, "iphone 14, iphone 15, iphone 16, samsung s24") and set maxListings: 1000 (or 0 for unlimited). The Actor paginates through each keyword in sequence and deduplicates all results by listingId.
How do I track new listings or price drops every day?
Use Apify's built-in Scheduler to run the Actor hourly or daily with sortBy: "SORT_INDEX" and sortOrder: "DECREASING" (newest first), then push the dataset into Google Sheets, Make, Zapier, n8n, BigQuery, or PostgreSQL keyed on listingId.
🗂️ Supported Benelux L1 categories (category parameter)
| Category ID | Dutch Name (marktplaats.nl / 2dehands.be) | English Vertical | Typical High-Value Use Cases |
|---|---|---|---|
"91" | Auto's | Cars & Vehicles | Used-car dealership arbitrage, BPM valuation, EV depreciation tracking |
"92" | Auto-onderdelen | Car Parts & Accessories | OEM/aftermarket parts pricing, dismantler inventory monitoring |
"1655" | Fietsen en Brommers | Bikes, E-Bikes & Mopeds | E-bike resale benchmarks (VanMoof, Gazelle, Cortina, Fatbikes) |
"135" | Huizen en Kamers | Houses, Rooms & Property | Private room rentals (kamer te huur), vacation homes, garage boxes |
"322" | Huis en Inrichting | Home, Furniture & Interior | Designer furniture sourcing, showroom dealer lead generation |
"31" | Telecommunicatie | Phones & Telecom | Smartphone trade-in & buyback pricing (iPhone, Samsung Galaxy) |
"504" | Computers en Software | Computers, Laptops & Tech | MacBook, GPU, monitor & enterprise hardware recommerce |
"1525" | Audio, Tv en Foto | Audio, TV & Cameras | Mirrorless camera, lens, and hi-fi equipment valuation |
"1953" | Sieraden, Tassen en Uiterlijk | Luxury, Watches & Bags | Luxury watch & designer handbag authentication/price tracking |
"621" | Kleding | Clothing & Fashion | Second-hand brand demand and resale volume analytics |
"728" | Sport en Fitness | Sports & Fitness | Gym equipment, road bikes, water sports gear |
"1099" | Kinderen en Baby's | Kids & Baby Gear | Strollers (Bugaboo, Joolz), LEGO, and baby furniture resale |
"367" | Antiek en Kunst | Antiques & Art | Auction house and antique dealer sourcing |
"33" / "34" | Werk en Personeel / Diensten | Jobs, Trades & Services | Local Dutch & Belgian contractor (zakelijk) lead generation |
🛠️ Ready-to-run workflow recipes
Recipe 1: Used-car private seller scout across the Netherlands
{"platform": "marktplaats.nl","query": "bmw 320, audi a4, mercedes c180","category": "91","sellerTypeFilter": "private","minPrice": 500000,"maxPrice": 3500000,"sortBy": "SORT_INDEX","sortOrder": "DECREASING","maxListings": 1000}
Recipe 2: Commercial dealer (zakelijk) lead generation in Belgium
{"platform": "2dehands.be","query": "","category": "91","sellerTypeFilter": "business","sortBy": "SORT_INDEX","sortOrder": "DECREASING","maxListings": 1000}
🔗 Related European marketplace & classifieds scrapers
- Kleinanzeigen.de Scraper (Germany) — Germany's #1 classifieds marketplace
- Leboncoin.fr Scraper (France) — France's leading classifieds & real-estate portal
- Subito.it Scraper (Italy) — Italian classifieds for cars, property, and electronics
- Wallapop Scraper (Spain, Italy & Portugal) — Southern Europe's largest second-hand marketplace
- Willhaben.at Scraper (Austria) — Austria's largest classifieds, auto, and property site
- Immoweb.be Scraper (Belgium) — Belgium's #1 real-estate portal
📋 Changelog
- v1.2 (2026-11) — Unlocked 1,000+ multi-keyword pagination & empty-run scaling: Added support for comma-separated multi-keyword queries in
query, raised offset pagination ceiling to 10,000, honored explicitmaxListings > 100on default sample runs, and upgraded documentation with field coverage indicators. - v1.1 (2026-08) — Added automatic L1/L2 category and subcategory name resolution from facet trees, normalized protocol-relative image URLs to
https://, and mergedextendedAttributesfor automotive verticals. - v1.0 (2026-05) — Initial release supporting
marktplaats.nl,2dehands.be, and2ememain.bewith Dutch/French price-type and condition normalization, postcode radius filtering, and optional detail-page enrichment.