Marktplaats.nl Scraper at a glance
Marktplaats.nl Scraper is a ready-to-run Apify actor from abotapi for collecting ecommerce data. Its documented output includes id, title, price (eur), price type and currency, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.20 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Ecommerce, Automation, Lead Generation
- Region
- Europe
- Pricing
- $2.20 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 26 options
From $1/1K. Scrape Marktplaats.nl listings by keyword or URL. Extract title, price, condition, location and coordinates, photos, seller details, ratings and reviews, shipping, views, and category-specific attributes for cars, bikes, electronics, and more.
What Marktplaats.nl Scraper can do
- Two ways to reach listings. Build a search from keywords plus filters, or paste any listing or result-page URL directly.
- Deep per-category attributes. Automotive listings carry make, model, trim, construction year, mileage, fuel, transmission, body type, energy label, options and more, alongside the 150+ fields every listing gets.
- Seller insight. Seller name, private vs professional, active-since, rating, number of reviews and payment method.
- Location-aware filtering. Centre a search on a Dutch postcode with a radius, or narrow by price range and seller type, all applied to the result pages the search reads anyway, with no extra requests.
- Optional detail enrichment. Switch on full detail pages for view/favorite counts, shipping options, bids, seller reviews and the complete description.
- Duplicate-safe pagination. Every result page is deduplicated by listing id, so paging never returns the same card twice.
Choose what to collect
These inputs let you configure Marktplaats.nl Scraper - Listings, Prices, Sellers & Reviews. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Choose Search to build queries from keywords/filters, or URL to scrape pasted listing or result-page URLs directly. |
queriesarray | One or more keywords to search for, e.g. "fiets", "iphone 15". Leave empty to browse a whole category. |
categoryIdinteger | Optional numeric Marktplaats category id to restrict results (e.g. 91 = Auto's, 447 = Fietsen). Find it in a category URL or leave empty for all categories. |
minPriceinteger | Only keep listings priced at or above this amount (euros). |
maxPriceinteger | Only keep listings priced at or below this amount (euros). |
postcodestring | Dutch postcode to centre a distance search on, e.g. "1011AB". Used together with Distance. |
distanceMetersinteger | Radius in meters around the postcode to search within (e.g. 25000 = 25 km). |
Show 19 more inputs
| Input | What it controls |
|---|---|
urlsarray | Paste Marktplaats listing URLs (/v/.../mNNNN-slug), result-page URLs (/q//, /q//p/2/, /l//, /l///, /l//q//), the short share link of a listing (link.marktplaats.nl/m) or seller profile URLs (/u///). Sort and price bounds pasted in the URL (query string: sortBy, sortOrder, priceFrom, priceTo; or the site's own hash form: #PriceCentsFrom:5000|PriceCentsTo:20000|sortBy:PRICE|sortOrder:INCREASING, which wins when both are present) and the page number (/p/N/) are honoured. Other hash filters (distance, postcode, brand) are not carried over. The price, postcode and distance inputs above are ignored in URL mode (use the price in the pasted address instead); Seller type and the ordering below still apply. |
sellerTypestring | Restrict to private (consumer) sellers, professional sellers, or both. Marktplaats narrows this on its own server when the results are requested, so it costs no extra requests and needs no detail pages. |
sortBystring | Result ordering. |
sortOrderstring | Direction for the selected sort field. Descending shows highest/newest first; ascending shows lowest/oldest first. |
fetchDetailsboolean | Visit each listing page for view/favorite counts, shipping options, bids, seller reviews/rating and the full HTML description. Adds one request per listing. |
maxPagesinteger | Optional bound on result pages walked per keyword/category/URL. Leave empty to walk every result page. |
maxListingsinteger | THE cap on this run: total number of listings to return across all searches. Defaults to 20. Set 0 for the maximum (a run never returns more than 100000 listings). |
maxRecordsinteger | Alias of Max listings for users migrating from other Marktplaats scrapers. When set, it replaces Max listings. Leave empty to use Max listings. 0 = the maximum; a run never returns more than 100000 listings. |
residentialCountriesarray | Country codes rotated through when the premium connection is used as a fallback. Leave the default unless you have a reason to pin specific regions. |
maxResidentialRequestsinteger | Caps how many requests may use the premium connection in one run, to control cost. Once that budget is spent, the run continues with the default connection. Set 0 to disable the premium connection entirely. |
resumeFromRunIdstring | Optional. 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). Combine both runs' datasets for the full set. Max listings then counts only the new listings. This continues ONE specific interrupted run; for recurring daily monitoring of the same search, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings. Turn on "Emit unchanged" or "Emit expired" only when you also want those listings returned (and billed). State is kept separately per search/category/URL and filter combination; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/category/URL and filter settings, different searches then never mix state with each other. |
emitUnchangedboolean | Off by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want the full snapshot every run. |
emitExpiredboolean | Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, not when Max listings capped it or when Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking. |
ignoreFieldsForChangesarray | Optional. Field names that must not count as a change in incremental mode, for example viewCount or price. Use a dotted path such as stats.since for a nested field. Ignored fields stay in the output; they only stop a listing from being marked UPDATED (and billed again) when just those fields moved. Always ignored: scrapedAt, stats, viewCount, savedCount, shipping, shippingOptions (the carrier list rotates between fetches) and the raw seller_information copy. The structured seller object does count as a change; add seller or seller.activeSince here to ignore it. |
mcpConnectorsarray | Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per listing (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL (or id) of the Notion page under which listing pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
idID (text)titleTitle (text)priceNumericPrice (EUR) (number)priceTypePrice Type (text)currencyCurrency (text)conditionCondition (text)brandBrand (text)location_cityNameCity (text)location_latitudeLat (number)location_longitudeLng (number)sellerNameSeller (text)sellerTypeSeller Type (text)Show 15 more fields
dateListed (text)imageUrlImage (image)urlURL (link)changeTypeChange type (incremental mode) (text)changedFieldsChanged fields (incremental mode) (array)firstSeenAtFirst seen (incremental mode) (date)lastSeenAtLast seen (incremental mode) (date)sellerRatingRating (number)sellerReviewsReviews (number)sellerPhonePhone Listed (text)viewCountViews (number)savedCountSaved (number)descriptionDescription (text)shippingShipping (object)attributesAttributes (object)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"id": "m0000000000",
"itemId": "m0000000000",
"title": "Elektrische fiets Cortina E-U4",
"url": "https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-dames-damesfietsen/m0000000000-elektrische-fiets",
"priceNumeric": 399,
"priceType": "FIXED",
"currency": "EUR",
"condition": "Zo goed als nieuw",
"brand": "Cortina",
"description": "Nette fiets, weinig gebruikt, inclusief oplader.",
"categoryId": 447,
"category": {
"id": 447,
"name": "Fietsen",
"parentName": "Fietsen en Brommers"
},
"location_cityName": "Utrecht",
"location_latitude": 52.0907,
"location_longitude": 5.1214,
"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": "Cortina",
"delivery": "Ophalen of Verzenden"
},
"seller": {
"id": 0,
"name": "FietsenhuisXYZ",
"type": "CONSUMER",
"activeSince": "1 jaar",
"sellerWebsite": null,
"sellerWebsiteDisplayUrl": null,
"paymentMethod": "ideal"
},
"isBuyersProtectionAllowed": true,
"sellerName": "FietsenhuisXYZ",
"sellerType": "CONSUMER",
"sellerRating": 4.8,
"sellerReviews": 21,
"viewCount": 58,
"savedCount": 4,
"shipping": {
"method": "DELIVERY",
"carrierName": "PostNL",
"price": "5,49"
},
"date": "Vandaag",
"scrapedAt": "2026-01-01T00:00:00+00:00"
}Ways to use this data
- Resellers and flippers: watch a keyword or category for new listings to spot underpriced items quickly.
- Pricing and market research: build a price-history dataset for a product category (bikes, phones, cars) across the Netherlands.
- Automotive marketplaces and lead generation: collect structured vehicle listings (make, model, mileage, fuel, transmission) for aggregation or outreach.
- Local and postcode-based apps: pull listings within a radius of a postcode to power a local classifieds feed.
- Brand monitoring: watch for unauthorized resale of a brand's products across the marketplace.
- Professional-seller discovery: filter to Commercial sellers in a category to build a list of active dealers or shops.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Marktplaats.nl Scraper return?
The documented output for Marktplaats.nl Scraper includes id, title, price (eur), price type, currency, condition, brand and city. Availability of each field depends on the source page and the selected mode.
How much does Marktplaats.nl Scraper cost?
It costs $2.20 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
What's the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues one specific interrupted or previous large run by pasting its run or dataset id. Incremental mode (incrementalMode) is for scheduling the same search again and again, for example daily, and getting back only what changed, without ever pasting an id. Resume is best used soon after the interruption: if even a few new listings were posted in between, a resumed run can stop after returning only those newest ones (see "Known limitation" under How to Use).
Can I run several keywords or URLs together and still get everything?
Usually yes, but if two of them genuinely overlap in the underlying catalogue (for example "fiets" and "fietsen"), a later one in the same run can stop early once it hits a results page made up entirely of listings an earlier search in that run already returned. See "Known limitation" under How to Use for the concrete mechanics and the workaround: give each keyword, category or URL you need a complete scan of its own run when the terms are likely to overlap.
Why did my run fail instead of returning an empty dataset?
If the site refuses every request, the run stops with a clear message so "no listings matched" is never confused with "nothing could be read". Run it again in a few minutes. If only part of a run could be read, you still get what was found.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
