Marktplaats.nl $1💰 Listings, Prices, Sellers avatar

Marktplaats.nl $1💰 Listings, Prices, Sellers

Pricing

from $1.00 / 1,000 listing scrapeds

Go to Apify Store
Marktplaats.nl $1💰 Listings, Prices, Sellers

Marktplaats.nl $1💰 Listings, Prices, Sellers

From $1/1K. Scrape Marktplaats.nl listings: title, price, condition, location with coordinates, all photos, seller name/type/rating/reviews, shipping, views, and full per-category attributes (cars, bikes, electronics). Search by keyword or paste URLs.

Pricing

from $1.00 / 1,000 listing scrapeds

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

2

Monthly active users

6 days ago

Last modified

Share

Marktplaats.nl Scraper

Extract structured listing data from Marktplaats.nl, the largest online marketplace in the Netherlands. Search by keyword and filters or paste listing and result-page URLs, and get clean JSON for every advert: title, price, condition, location with GPS coordinates, every photo, seller name/type/rating/reviews, shipping options, view and favorite counts, and the complete per-category attribute set (cars, bikes, electronics, and more).

Why This Scraper?

  • Complete field coverage: 150+ fields per listing including price, condition, full description, all photos, GPS coordinates, seller profile, shipping and per-category attributes.
  • Rich automotive data: for vehicle adverts it pulls make, model, trim, construction year, mileage, fuel, transmission, body type, power, cylinder capacity, energy label, options and more.
  • Seller insight: seller name, private vs professional, active-since, rating and number of reviews, and payment method.
  • Two input modes: build searches from keywords plus filters, or paste any listing or result-page URL.
  • Fast and lightweight: runs on the free tier with the default datacenter proxy.
  • Result paging with duplicate protection: collects result pages up to your chosen limit without returning repeats.
  • Optional detail enrichment: toggle full detail pages on for views, favorites, shipping, bids, reviews and the full description.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
idm0000000000
titleKoga elektrische fiets
priceNumeric399.0
priceTypeMIN_BID
currencyEUR
conditionZo goed als nieuw
brandKoga
descriptionNette elektrische fiets, inclusief oplader.
location_cityNameAmsterdam
location_latitude52.3702
location_longitude4.8952
sellerNameJane Doe
sellerTypeCONSUMER
sellerRating4.9
sellerReviews37
viewCount73
savedCount3
mileage89900
fuelTypeBenzine
transmissionAutomaat
imageUrlhttps://images.marktplaats.com/api/v1/.../image.jpg
urlhttps://www.marktplaats.nl/v/.../m0000000000-koga

Incremental mode only. When incrementalMode is on, every returned record also carries:

FieldDescription
changeTypeNEW | UPDATED | UNCHANGED | REAPPEARED | EXPIRED
changedFieldsTop-level fields that changed since last seen; non-empty only for UPDATED
firstSeenAtWhen this listing was first observed by this monitoring campaign
lastSeenAtWhen this listing was last observed

How to Use

1. Keyword search with detail enrichment

{
"mode": "search",
"queries": ["fiets"],
"fetchDetails": true,
"maxListings": 50,
"proxy": { "useApifyProxy": true }
}

2. Browse a category with price and seller filters

{
"mode": "search",
"queries": [""],
"categoryId": 91,
"minPrice": 5000,
"maxPrice": 20000,
"sellerType": "COMMERCIAL",
"sortBy": "PRICE",
"sortOrder": "INCREASING",
"maxListings": 100,
"proxy": { "useApifyProxy": true }
}

3. Search near a postcode

{
"mode": "search",
"queries": ["bankstel"],
"postcode": "1011AB",
"distanceMeters": 15000,
"maxListings": 40,
"proxy": { "useApifyProxy": true }
}

4. URL mode (listing or result pages)

{
"mode": "url",
"urls": [
"https://www.marktplaats.nl/l/auto-s/",
"https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-dames-damesfietsen/m0000000000-koga"
],
"fetchDetails": true,
"maxListings": 60,
"proxy": { "useApifyProxy": true }
}

Input Parameters

ParameterTypeDescription
modeselectsearch (keyword + filters) or url (paste URLs).
queriesarrayOne or more search keywords. Empty browses a whole category.
categoryIdintegerNumeric category id to restrict results (e.g. 91 = Auto's).
sortByselectOPTIMIZED, SORT_INDEX, PRICE, DATE.
sortOrderselectDECREASING or INCREASING.
minPrice / maxPriceintegerKeep listings within this euro range.
sellerTypeselectany, CONSUMER, or COMMERCIAL.
postcodestringDutch postcode to centre a distance search on.
distanceMetersintegerRadius in meters around the postcode.
urlsarrayListing or result-page URLs (URL mode).
fetchDetailsbooleanVisit each detail page for views, shipping, reviews, full description.
maxPagesintegerOptional bound on result pages walked per keyword/category/URL; leave empty to walk every result page. The run size is controlled by maxListings, which this field defers to.
maxListingsintegerTHE run cap: total listings to return; default 20, 0 = unlimited.
resumeFromRunIdstringOptional. ID of a previous run of this actor (or a dataset ID). Listings already in that dataset are skipped, so this run returns only NEW listings (a delta). Continues ONE specific interrupted run — for recurring monitoring of the same search, use incrementalMode instead.
incrementalModebooleanOff by default. Turn on for daily/recurring monitoring of the same search: the first run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED listings, each carrying changeType, changedFields, firstSeenAt, lastSeenAt. State is scoped per mode/queries/categoryId/urls/fetchDetails/filters, so two differently-filtered runs never share a baseline.
stateKeystringOptional, incremental mode only. Name a monitoring campaign to keep its state stable or deliberately share it across runs. Leave empty to derive the key automatically from the search + filter settings.
emitUnchangedbooleanOff by default, incremental mode only. Also return listings unchanged since the last run, marked UNCHANGED (bills those rows too).
emitExpiredbooleanOff by default, incremental mode only. Also return listings from a previous run no longer found, marked EXPIRED. Only produced after a complete, uncapped, non-resumed scan of the tracked search.
proxyobjectProxy configuration; Apify datacenter proxy by default (works on the free tier).
residentialCountriesarrayCountries rotated through when the residential tier is used as a fallback. Default NL, BE, DE, FR, GB.
maxResidentialRequestsintegerCap on residential requests per run, to control cost; the run auto-downgrades to datacenter once spent. Default 200. 0 disables residential.
backupProxyUrlstringOptional last-resort proxy gateway URL. Leave blank to use the built-in default.
mcpConnectorsarrayOptional MCP connectors to pipe a copy of each listing into (Notion, Linear, Airtable, Apify). Authorize one under Apify → Settings → Integrations, then pick it here. Leave empty to skip.
notionParentPageUrlstringNotion only: URL (or id) of the page under which listing pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset. Default 50.

Resume & recurring updates

Two different things — pick the one that matches what you're doing:

NeedUse
A crawl stopped and should continueresumeFromRunId / automatic checkpoint recovery
Run the same search every day and receive only changesincrementalMode
Keep separate daily campaigns for similar searchesdistinct stateKey values
Run a normal full snapshotleave both off

Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips listings already collected there, returning only the remaining new listings. An automatic same-run checkpoint also protects against platform migrations/Resurrects without any input needed.

Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED listings by default — duplicates and unchanged listings are suppressed (and not charged). Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per mode/queries/categoryId/urls/fetchDetails/filter combination automatically; set stateKey to name or deliberately share a monitoring campaign.

Scheduled-run example — same search, run daily:

Day 1 (first run ever for this search):

{ "mode": "search", "queries": ["fiets"], "incrementalMode": true }

→ every listing comes back with "changeType": "NEW".

Day 2 (the schedule fires again, identical input):

{ "mode": "search", "queries": ["fiets"], "incrementalMode": true }

→ listings whose price/condition/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new listings come back as "changeType": "NEW", listings that vanished and came back come back as "changeType": "REAPPEARED" — and listings that are still there, unchanged, are not returned at all (suppressed, not charged) unless emitUnchanged is on.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"id": "m0000000000",
"title": "Koga elektrische fiets",
"url": "https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-dames-damesfietsen/m0000000000-koga",
"priceNumeric": 399.0,
"priceType": "MIN_BID",
"currency": "EUR",
"condition": "Zo goed als nieuw",
"brand": "Koga",
"description": "Nette elektrische fiets, inclusief oplader en fietstassen.",
"categoryId": 447,
"category": { "id": 447, "name": "Damesfietsen", "parentName": "Fietsen en Brommers" },
"location_cityName": "Amsterdam",
"location_latitude": 52.3702,
"location_longitude": 4.8952,
"imageUrl": "https://images.marktplaats.com/api/v1/listing/images/0000.jpg",
"image_urls": ["https://images.marktplaats.com/api/v1/listing/images/0000.jpg"],
"attributes": { "condition": "Zo goed als nieuw", "brand": "Koga", "delivery": "Ophalen of Verzenden" },
"seller": {
"id": 0,
"name": "Jane Doe",
"type": "CONSUMER",
"activeSince": "1 jaar",
"paymentMethod": "ideal"
},
"sellerName": "Jane Doe",
"sellerType": "CONSUMER",
"sellerRating": 4.9,
"sellerReviews": 37,
"viewCount": 73,
"savedCount": 3,
"shipping": { "method": "DELIVERY", "carrierName": "PostNL", "price": "€ 5,49" },
"date": "Vandaag",
"scrapedAt": "2026-01-01T00:00:00+00:00"
}

Send results into your apps (MCP connectors)

Optionally pipe the scraped listings into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape — the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each listing — not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where listings should be created.
  4. Use maxNotifyListings to cap how many listings are written to each connector per run.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Plan Requirement

Runs on any Apify plan, including the free tier, using the default Apify datacenter proxy. Heavier runs with detail enrichment benefit from a paid plan for higher concurrency and proxy throughput.

Proxy policy

The scraper uses a tiered, cost-first proxy strategy:

  • Datacenter (default). Datacenter is the default and works on every plan, including the free tier.
  • Residential (optional, budgeted fallback). Selecting the residential proxy group is bounded by maxResidentialRequests. Because residential traffic is billed at a higher rate, the run falls back to datacenter once that budget is spent.
  • Backup gateway (last resort). If the Apify proxy is unavailable on your plan, the run uses a backup gateway (override with backupProxyUrl) instead of returning nothing.

Run logs reference only the abstract tier (datacenter / residential / backup) and never expose any geography.