Marktplaats.nl Scraper — Dutch Classifieds Search & Monitoring
Pricing
from $1.40 / 1,000 result items
Marktplaats.nl Scraper — Dutch Classifieds Search & Monitoring
Marktplaats.nl listings for AI agents and analysts: keyword + category (2,000 L1/L2) search with postcode radius, price, condition, delivery, seller type and raw facet filters; price, price type, city, coordinates, seller, date, attributes, photos, URL.
Pricing
from $1.40 / 1,000 result items
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Search marktplaats.nl (the Netherlands' #1 classifieds, 2,000+ categories) by keyword and/or category with the same filters the site offers — postcode + radius, price, condition, delivery, seller type (cars), attribute facets — and get clean JSON: price and price type, city, coordinates, distance, seller, category, date, attributes, photos, URL. Optionally open every listing page for the full description, exact publish time, view/favourite counts, seller type and bids (paced for marktplaats.nl's per-IP limit, see Limits). Built for AI agents, analysts and monitoring jobs: reads the site's own JSON search API, no browser, no API key, no proxy needed. Big detail: true jobs can use the optional fast mode (turn on a proxy): listing pages are opened with up to 8 IPs at once — see Speed and pricing.
Use cases
- Price monitoring — track asking prices for a product ("iphone 15 pro", "gazelle e-bike") daily;
sortBy: PRICEgives the cheapest offers first. - Sourcing / arbitrage — find under-priced items in a category near a warehouse postcode; filter
condition,delivery: shipping,sellerType: private. - Lead generation — list business sellers (dealers, refurbishers, contractors in Diensten en Vakmensen) with their profile URL and years active (
detail: true). - New-listing alerts — run every hour with
sinceHours: 1(+detail) and push fresh matches to Slack/CRM. - Market research — count listings and price distribution per subcategory;
mode: facetsreturns the facet histogram (brands, conditions, fuel types…) with counts. - Used-car analysis — category
auto-swithattributeRanges(construction year, mileage), fuel/transmission ids andsortAttribute.
Input
| Field | Type | Default | Notes / allowed values |
|---|---|---|---|
query | string | – (UI prefill fiets) | Keyword(s). Optional when category is set; leave empty to browse a whole category. |
category | string | – | L1 key or id, optionally l1/l2: fietsen-en-brommers, 445, fietsen-en-brommers/fietsen-racefietsen, 445/464. L1 table below; L2 keys via mode: categories. |
subcategory | string | – | L2 key / id / (part of) name, e.g. racefietsen. Alternative to the l1/l2 notation. |
mode | select | search | search = listings · categories = full category tree (~2,000 rows, about $4 — see Speed and pricing) · facets = filter values valid for the query/category (with ids and counts). |
postcode | string | – | Dutch postcode (1012AB) — enables distanceMeters filter, distance in output and sortBy: LOCATION. |
distanceMeters | integer | – | Radius in metres (site presets: 3000 … 100000). Needs postcode. |
priceFrom / priceTo | integer | – | Euro. |
condition | array | – | new, like-new, used, refurbished (OR). |
delivery | select | – | pickup (Ophalen) / shipping (Verzenden). |
sellerType | select | all | private / business. Server-side for cars (auto-s). Other categories: with detail: true every listing page is checked and a listing whose page could not be read is dropped (counted in the status). Without detail, private drops listings whose search data shows a business (website link, dealer tools, company logo) and keeps the rest unverified (sellerType: null); business keeps only listings whose search data shows a business. |
offeredSince | select | – | Vandaag, Gisteren, Een week, Altijd. Sent to the site and enforced client-side on the list date (day precision). |
sinceHours | integer | – | Keep listings newer than N hours. Exact with detail: true; a row without a listing page (no detail, or its page could not be read) is judged by its day label: kept when its day started less than N + 24 h ago. |
priceTypes | array | – | Client-side keep-list: FIXED, MIN_BID, SEE_DESCRIPTION, NOTK, FREE, ON_REQUEST, EXCHANGE, RESERVED. |
attributeIds | integer[] | – | Raw facet value ids (attributesById), e.g. [473, 534] = Benzine + Automaat. Discover with mode: facets. |
attributesByKey | string[] | – | Raw key:value facets, e.g. "offeredSince:Vandaag". |
attributeRanges | string[] | – | Range facets key:from:to, e.g. "constructionYear:2018:2024", "mileage:0:100000". |
sortBy | select | SORT_INDEX | SORT_INDEX (date), OPTIMIZED (relevance), PRICE, LOCATION (needs postcode), ATTRIBUTE (cars, with sortAttribute). |
sortOrder | select | auto | DECREASING / INCREASING (PRICE and LOCATION default to INCREASING). |
sortAttribute | select | – | constructionYear / mileage (cars). |
includeSponsored | boolean | false | Also return paid Admarkt listings from the top block (sponsored: true). |
detail | boolean | false | Open each listing page: full description, publishedAt, views, favourites, seller type/years, bids, shipping, all photos. At most 40 listing pages a minute (~1.5 s per listing); see Limits for what happens on a block. |
maxItems | integer | 50 | 1–2000 listings saved (100 per request; the site caps a query at 5,000 results). Rows dropped by filters do not count. Modes categories and facets return their whole list. |
maxPages | integer | 20 | 1–50 search pages. |
proxyConfiguration | object | off | Off = the normal run. On = fast mode for detail: true: Apify Proxy → 8 IPs (group RESIDENTIAL) or 4 IPs (datacenter groups, whose IPs are shared) open listing pages at once, at the fast-mode price; your own proxy URLs (http://user:pass@host:port, one per IP, up to 10 at once) → as many IPs as URLs, at the normal price. The search API is always read directly; without detail the proxy is not used. See Speed and pricing. |
fields | string[] | – | Keep only these output fields, in this order. Every row keeps id (facets rows: facetKey, valueKey), and with detail: true also detailError when the listing page was not read; they come first unless you list them. A different letter case or a near miss (titel) is read as the field and noted in the status; unknown names (and detail-only fields without detail) are ignored with a note; if no name is an output field the run fails before any request and lists the valid names. |
Reference
L1 categories (category)
| id | key | name | id | key | name |
|---|---|---|---|---|---|
| 1 | antiek-en-kunst | Antiek en Kunst | 565 | kinderen-en-baby-s | Kinderen en Baby's |
| 31 | audio-tv-en-foto | Audio, Tv en Foto | 621 | kleding-dames | Kleding | Dames |
| 91 | auto-s | Auto's | 1776 | kleding-heren | Kleding | Heren |
| 2600 | auto-onderdelen | Auto-onderdelen | 678 | motoren | Motoren |
| 48 | auto-diversen | Auto diversen | 728 | muziek-en-instrumenten | Muziek en Instrumenten |
| 201 | boeken | Boeken | 1784 | postzegels-en-munten | Postzegels en Munten |
| 289 | caravans-en-kamperen | Caravans en Kamperen | 1826 | sieraden-tassen-en-uiterlijk | Sieraden, Tassen en Uiterlijk |
| 1744 | cd-s-en-dvd-s | Cd's en Dvd's | 356 | spelcomputers-en-games | Spelcomputers en Games |
| 322 | computers-en-software | Computers en Software | 784 | sport-en-fitness | Sport en Fitness |
| 378 | contacten-en-berichten | Contacten en Berichten | 820 | telecommunicatie | Telecommunicatie |
| 1098 | diensten-en-vakmensen | Diensten en Vakmensen | 1984 | tickets-en-kaartjes | Tickets en Kaartjes |
| 395 | dieren-en-toebehoren | Dieren en Toebehoren | 1847 | tuin-en-terras | Tuin en Terras |
| 239 | doe-het-zelf-en-verbouw | Doe-het-zelf en Verbouw | 167 | vacatures | Vacatures |
| 445 | fietsen-en-brommers | Fietsen en Brommers | 856 | vakantie | Vakantie |
| 1099 | hobby-en-vrije-tijd | Hobby en Vrije tijd | 895 | verzamelen | Verzamelen |
| 504 | huis-en-inrichting | Huis en Inrichting | 976 | watersport-en-boten | Watersport en Boten |
| 1032 | huizen-en-kamers | Huizen en Kamers | 537 | witgoed-en-apparatuur | Witgoed en Apparatuur |
| 1085 | zakelijke-goederen | Zakelijke goederen | |||
| 428 | diversen | Diversen |
There are ~1,960 L2 subcategories (e.g. fietsen-en-brommers has 76: fietsen-racefietsen 464, elektrische-fietsen 451, fietsen-bakfietsen 446 …). Run {"mode": "categories"} once to get the whole tree as dataset rows (level, id, key, name, parentKey, howToUse), or {"mode":"categories","category":"auto-s"} for one branch. They also appear in the site URL: marktplaats.nl/l/<l1key>/<l2key>/.
Generic facet ids
| Facet | Values (id) |
|---|---|
| condition | Nieuw 30 · Zo goed als nieuw 31 · Gebruikt 32 · Refurbished 14050 (cars: Nieuw 30 · Gebruikt 14049) |
| delivery | Ophalen 33 · Verzenden 34 |
| offeredSince (by key) | Vandaag · Gisteren · Een week · Altijd |
| advertiser (cars only) | Particulier 10898 · Bedrijf 10899 |
| priceType (cars) | Vraagprijs 10882 · Leaseprijs 10883 |
Cars (auto-s) additionally expose ~40 facets: fuel (Benzine 473, Diesel 474, Elektrisch 11756, Hybride 13838/13839, LPG 475), transmission (Automaat 534, Handgeschakeld 535), body, color, energyLabel (A 13947 … G 13953), options, ranges constructionYear, mileage, engineHorsepower, roadTax, batteryCapacity… Every category has its own set (bikes: brand, frameHeight, brakeType) — mode: facets lists them with live counts and the exact howToUse string.
Sort options
SORT_INDEX+DECREASING newest first · SORT_INDEX+INCREASING oldest first · OPTIMIZED site relevance · PRICE asc/desc · LOCATION+INCREASING nearest first (postcode) · ATTRIBUTE + sortAttribute constructionYear / mileage (cars).
Price types
FIXED fixed price · MIN_BID "bieden vanaf" (price = minimum bid) · SEE_DESCRIPTION · NOTK n.o.t.k. (negotiable) · FREE gratis · ON_REQUEST · EXCHANGE ruilen · RESERVED.
Examples
Cheapest used road bikes within 25 km of Utrecht, shipped or picked up
{ "query": "racefiets", "category": "fietsen-en-brommers/fietsen-racefietsen", "postcode": "3511AB", "distanceMeters": 25000, "priceTo": 800, "condition": ["like-new", "used"], "sortBy": "PRICE", "maxItems": 100 }
Hourly new-listing alert with exact timestamps and seller type
{ "query": "iphone 15 pro", "category": "telecommunicatie", "sinceHours": 1, "detail": true, "sortBy": "SORT_INDEX", "sortOrder": "DECREASING", "maxItems": 60 }
Private-seller used cars: Volvo, 2018+, under 100,000 km, automatic, petrol/hybrid
{ "query": "volvo", "category": "auto-s", "sellerType": "private", "attributeRanges": ["constructionYear:2018:", "mileage:0:100000"], "attributeIds": [534, 473, 13838], "sortBy": "ATTRIBUTE", "sortAttribute": "mileage", "sortOrder": "INCREASING", "maxItems": 200 }
Lead list of business sellers in a category (with profile URL and years active)
{ "category": "zakelijke-goederen/horeca-keukenapparatuur", "sellerType": "business", "detail": true, "fields": ["id", "title", "price", "city", "sellerName", "sellerType", "sellerActiveYears", "sellerProfileUrl", "url"], "maxItems": 150 }
Discover the filters of a category before building a search
{ "mode": "facets", "category": "auto-s", "query": "tesla" }
Output
{"id": "m2440133929","title": "Gazelle Balance Innergy €500,-","description": "Gazelle balance innergy zeer goede staat goede accu en met acculader","price": 500, "currency": "EUR", "priceType": "FIXED","city": "Houten", "distanceMeters": 7000, "distanceKm": 7,"latitude": 52.0346, "longitude": 5.1558, "countryName": "Nederland","sellerName": "Ferdinand", "sellerId": 23350124, "isVerifiedSeller": false, "sellerHasWebsite": false,"categoryId": 451, "categoryName": "Elektrische fietsen","date": "7 sep 26", "dateIso": "2026-09-07","priorityProduct": "NONE", "sponsored": false, "reserved": false, "traits": ["PACKAGE_FREE"],"condition": "Gebruikt", "delivery": "Ophalen", "constructionYear": null, "mileageKm": null, "fuel": null, "transmission": null, "advertiserType": null,"attributes": { "condition": "Gebruikt", "delivery": "Ophalen", "frameHeight": "Minder dan 47 cm" },"images": ["https://images.marktplaats.com/api/v1/…?rule=ecg_mp_eps$_82.jpg"], "imagesCount": 1,"url": "https://www.marktplaats.nl/v/fietsen-en-brommers/elektrische-fietsen/m2440133929-gazelle-balance-innergy-500","query": "gazelle", "searchUrl": "https://www.marktplaats.nl/lrp/api/search?…", "fetchedAt": "2026-09-12T23:48:40.800Z","descriptionFull": "Gazelle Balance Innergy\nZeer goede staat\nGoede accu en met acculader","publishedAt": "2026-09-07T16:06:08Z", "viewCount": 212, "favoritedCount": 2,"sellerType": "CONSUMER", "sellerActiveYears": 10, "sellerProfileUrl": "https://www.marktplaats.nl/u/ferdinand/23350124/", "sellerCity": "Houten","adType": "RegularFree", "biddingEnabled": false, "bidCount": 0, "highestBid": null, "minimumBid": null,"shippingType": "Ophalen", "buyItNow": false, "buyerProtection": false, "isReserved": false, "allImages": ["…"]}
| Field | Description |
|---|---|
id, url, title, description | Listing id (m… / a… for Admarkt), canonical URL, title, list snippet. |
price, currency, priceType | Euro; see price types above (MIN_BID = bidding from this amount). |
city, distanceMeters, distanceKm, latitude, longitude, countryName | Location; distance only when postcode is given. |
sellerName, sellerId, isVerifiedSeller, sellerHasWebsite | From the list. |
sellerType, sellerTypeSource | CONSUMER (private) or TRADER (business), as on the listing page. sellerTypeSource: filter = the server-side seller filter of a car search, listing = the search data (car "advertiser" attribute, or a business-only website link / dealer tools / company logo), detail = the listing page. null when the search data has no signal and detail is off (no logo or website does not prove a private seller). |
categoryId, categoryName | L2 category of the listing. |
date, dateIso | Site label ("Vandaag", "7 sep 26") and ISO date (Dutch calendar day). |
priorityProduct, sponsored, reserved, traits | Paid placement (DAGTOPPER…), Admarkt top-block flag, reserved flag, feature traits. |
condition, delivery, constructionYear, mileageKm, fuel, transmission, advertiserType | Most-used attributes lifted to top level (null when the category has no such attribute; advertiserType = "Bedrijf"/"Particulier", cars only) |
attributes | Flat map of all listing attributes (condition, delivery, brand, mileage, fuel…). pricePerKm = price ÷ mileage for vehicles. |
images, imagesCount | Thumbnail URLs from the list. |
query, searchUrl, fetchedAt | Provenance. |
detail only: descriptionFull, publishedAt, viewCount, favoritedCount, exact sellerType for every listing, sellerActiveYears, sellerProfileUrl, sellerCity, sellerPhoneHidden, adType, categoryFullName, parentCategoryId, biddingEnabled, bidCount, highestBid, minimumBid, shippingType, buyItNow, buyerProtection, isReserved, allImages | Read from the listing page. |
detailError | detail only: why the listing page of this row was not read — skipped: … after marktplaats.nl kept refusing listing pages (see Limits), or the page's own error (removed listing). The row then holds the search data only. |
mode: categories rows: level, id, key, name, parentId, parentKey, howToUse, url. mode: facets rows: facetKey, facetLabel, valueId, valueKey, valueLabel, count, howToUse. The Output tab has a view per row type (Listings, Listings with detail, Categories, Filter values).
Every run also writes a SUMMARY record (linked in the run's output): rows saved, matching total, detailFor ("N of M" rows with a listing page read), pauses for the per-IP limit, rows dropped by each filter, notes, and why the run stopped early (spending limit, timeout, block). The run's status message says the same in one line.
Use it from code / agents
curl -X POST "https://api.apify.com/v2/acts/yadroo~marktplaats-nl/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"query":"racefiets","postcode":"1012AB","distanceMeters":25000,"priceTo":800,"maxItems":50}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/marktplaats-nl').call({ query: 'iphone 15 pro', sinceHours: 2, detail: true, maxItems: 40 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("yadroo/marktplaats-nl").call(run_input={"category": "auto-s", "query": "volvo", "sellerType": "private", "maxItems": 100})items = client.dataset(run["defaultDatasetId"]).list_items().items
MCP: add https://mcp.apify.com to your agent (Claude, Cursor, custom) and call the yadroo/marktplaats-nl tool with the same JSON input — the input schema descriptions are written for agents.
Speed and pricing
The search API is quick (100 listings per request, 2,000 listings in about 30–40 s), so runs without detail are fast in every mode. With detail: true the run opens one listing page per row, and marktplaats.nl refuses listing pages from one IP after about 60 a minute — so the normal run opens at most 40 a minute (see Limits). Fast mode opens them with several IPs at once, each at that same pace. Pick the mode with the proxyConfiguration input:
| Mode | How | 150 listings, detail: true | 1,000 listings, detail: true | Price per listing |
|---|---|---|---|---|
| Normal (default) | proxy off | ≈ 4 min | ≈ 25 min | $0.002 |
| Fast, Apify Proxy | proxy on → Apify Proxy, group RESIDENTIAL (8 IPs) | ≈ 1.1 min (measured) | ≈ 5–7 min (estimated) | $0.003 from 17 October 2026 (until then $0.002) |
| Fast, Apify Proxy datacenter | proxy on → any other Apify Proxy group (4 IPs: datacenter IPs are shared) | ≈ 1 min (estimated) | ≈ 7 min (estimated) | $0.003 from 17 October 2026 (until then $0.002) |
| Fast, your proxies | proxy on → your proxy URLs, one per IP | like Apify Proxy with 8 or more URLs; one URL = normal speed | $0.002 |
Measured in the Apify cloud on 2026-10-03 (build 0.1.9) with query: "fiets", detail: true, 150 listings on RESIDENTIAL: 67 s, every row with its detail fields, one IP replaced on the way, ≈ 26 KB of proxy traffic per listing; each IP opened about 20–30 listing pages a minute (the proxy adds latency), below the 40-a-minute cap. On the automatic (datacenter) group: 40 listings in 18 s on 4 IPs, all with detail fields. Datacenter IPs are shared with other Apify users, so some may already be refused — the run replaces those. Normal-mode times follow from the 40-a-minute pace (Limits).
- One price per listing in each mode. From 17 October 2026 (06:00 UTC) a fast run on Apify Proxy charges the fast-mode listing event instead of the normal listing event, not on top of it; the extra $0.001 pays for the proxy traffic (≈ 26 KB per listing, measured 2026-10-03). With your own proxies the traffic is yours, so the normal price stays. Without
detailthe proxy is not used and the normal price applies. Until 17 October every row costs the normal price in every mode. Run start: $0.005 in every mode. - Same pace per IP. Each IP starts its next listing page at least 1.5 s after its previous one (≤ 40 a minute), like a normal run. Before a proxy IP is used, the run reads it (Apify's own echo endpoint, not marktplaats.nl): two IP slots never share one IP. An IP marktplaats.nl refuses (HTTP 403/429) or that stops answering is replaced by a new one (up to 3 times per IP slot) and its listing is opened on another IP; a listing refused on 3 IPs keeps its search data with
detailError. If every IP is used up, the rest of the current results page is saved with search data only (detailError: "skipped: …") and no further pages are read — like a normal run after a block it could not wait out. A challenge or captcha page is never routed around: it counts as a failed listing page. - Which proxy. Your own proxies:
http://orhttps://URLs (SOCKS is not supported), one URL per IP; a "rotating" gateway URL counts as one IP.SUMMARY.speedshows the mode, the IPs used, IPs replaced and the charged event.
Discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the listing price (normal and fast); the start event ($0.005) is the same on every plan; platform usage and, in fast mode on Apify Proxy, the proxy traffic are included.
Typical runs (normal price): a 100-item price check costs about $0.205; a detail: true run costs the same per item. mode: categories writes the whole tree — about 1,960 rows, so about $4 on the free plan (pass a category for one branch); mode: facets rows are billed as rows too (normal price). The run stops at your "Maximum cost per run" and says so in its status.
Limits & FAQ
- Speed — the search API returns 100 listings per request and is not throttled (2,000 listings in about 30–40 s, measured October 2026). The site caps a query at 5,000 results (
maxAllowedPageNumber); narrow with category/price/postcode for more coverage. - Listing pages (
detail: true) — marktplaats.nl refuses listing pages from one IP after about 55–65 of them in a minute (HTTP 403; measured October 2026 at ~70 a minute) and lifts the block within about 3.5 minutes. The actor therefore opens at most 40 listing pages a minute (~1.5 s each: 100 listings ≈ 3 min, 300 ≈ 8 min, 1,000 ≈ 25 min — keep the run timeout above that); at that pace a 300-listing run read 298 pages without a single block (2 listings had been removed), October 2026. If a 403 comes anyway (another run on the same Apify server counts too), the run pauses 3.5 min, retries the same listing and goes on more slowly; a second pause is 4 min (fast mode replaces a refused IP instead of waiting, see Speed and pricing). If the block outlasts both pauses, the rest of the current results page is saved with list data only anddetailError: "skipped: …", no further pages are read, and the status says "detail for N of M" and that the run stopped early — wait 15 minutes before the next detail run. Rows are saved every 10 listings, so a stop or an abort loses at most a few page reads. - Freshness — live search results. List dates are day labels;
detail: truegives the exactpublishedAt. - Blocking — the search API has been stable without proxies (fast mode never uses a proxy for it). If it answers 403 or a challenge page on the first page, the run fails with a clear error; on a later page the run keeps what it saved and the status names the page that failed. A removed listing (HTTP 404) carries its own
detailError("listing no longer on marktplaats.nl"); 3 listing pages in a row that fail for another reason (layout change, no answer) stop listing pages like a block. - Spending limit and timeout — the run never goes over your "Maximum cost per run": it stops at it with "Stopped at your spending limit: N rows delivered". Near the run timeout it stops opening pages, saves what it has and ends SUCCEEDED with "Stopped before the run timeout".
- Seller type — the API only filters private/business for cars; there every row gets
sellerTypefrom the filter. Elsewhere the search data identifies business sellers only when they show a website link, dealer tools or a company logo — not every business does (3 of 9 business listings in a small September 2026 sample had none). So withoutdetail,privatemay keep a few businesses (they staysellerType: null, counted in the status) andbusinessreturns only the businesses that show such a signal; usedetail: truefor an exact answer. - Not included — phone numbers, bidder identities, private messages. Only what the public page shows.
- Roadmap — saved-search diffing (only items not seen in a previous run), seller-profile mode.
Made by Yadroo. Related actors: kleinanzeigen-de · willhaben-at · otodom-pl · rightmove-uk · autoscout24-cars · krisha-kz · kolesa-kz