# Marktplaats Price Monitor: Price Drop Alerts, No Login (`accountable_eel/marktplaats-price-monitor`) Actor

Marktplaats price monitor: schedule a keyword search and get back only the listings whose price fell since the last run, with the old price, the new price and the drop percentage. Postcode and distance filters, no login. A run with nothing cheaper is free.

- **URL**: https://apify.com/accountable\_eel/marktplaats-price-monitor.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 price drop returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Marktplaats Price Monitor: Price Drop Alerts, No Login

This is a **price monitor**, not a search dump. Give it a Marktplaats keyword search, put it on a
schedule, and every run returns **only the listings whose price has fallen since the last run** —
with the old price, the new price and the drop percentage on the row. A run where nothing got cheaper
returns one summary row and costs you the start fee alone.

The general-purpose [Marktplaats Scraper](https://apify.com/accountable_eel/marktplaats-listing-lookup)
can do this too, but it ships as a full-search scraper: you have to turn monitoring on, turn new
listings off, pick a threshold, and then find the price change in a 39-column row. Here that is the
default and the only thing the actor is shaped for. If you want everything a Marktplaats search
returns — every current listing, descriptions, raw seller names, sold-signal and sell-through
tracking — use the parent actor instead; it is listed under **Related actors** at the bottom.

### Who it's for

- **Deal hunters** on a saved search who want to know the moment a seller drops the asking price,
  not that the item exists (they already know).
- **Resellers** watching a category for the markdowns that make a flip work.
- **Automations.** One row per price drop, straight into Google Sheets, n8n, Make, Zapier or your own
  bot. Nothing to deduplicate: the actor has already removed everything that did not change.

### What this does that a plain Marktplaats search doesn't

Marktplaats shows you today's asking prices. It cannot tell you that a bike was EUR 340 last week
and is EUR 275 now, because the page has no memory. This actor keeps one.

| | Plain search | This actor |
|---|---|---|
| Rows you get back | every match, every run | only the ones that got cheaper |
| Old price | not available | `previousPrice` on the row |
| Size of the cut | you work it out | `priceDropPct`, and a minimum you set |
| Cost of a quiet run | you pay for every row again | start fee only |
| Deduplication | yours to do | already done |

### How the price memory works

Each search line becomes a **watchlist**. The actor remembers every Marktplaats listing ID and its
price between runs, in your own account's storage.

1. **First run.** Nothing to compare with, so it returns a single summary row with
   `listingCount: 0` and remembers the prices it found. No listings, no charge.
2. **Every run after.** A listing comes back only when its price has fallen by at least
   *Smallest price drop worth an alert* (5% by default) since it was last seen. The row carries
   `previousPrice`, the current `price`, `priceDropPct` and `changeType: price-drop`.
3. **A quiet run.** Nothing cheaper, so you get one summary row with `listingCount: 0`.

Two schedules with different filters keep **separate** memories, so they never overwrite each other.
Give a *Watchlist name* to pin one memory across a filter change, or to have two schedules share one.

Want new listings as well? Turn on *Also return listings that are brand new*. They arrive as ordinary
rows marked `changeType: new`.

### Price types: what a drop can and cannot be measured on

Marktplaats listings are not all fixed-price. A price drop is only ever reported for a listing with a
**fixed price** or an **asking price**, where both the old and the new number are set. Bidding,
minimum-bid, fast-bid, free, trade, reserved and "see description" listings have no comparable price,
so they are never reported as drops — they would be noise, and you would be billed for it.

The cleanest way to run this watchlist is to set *Price type* to **Fixed price**, so the pages it
reads are the ones it can actually compare.

### Location filters

Set *Postcode to search near* to a Dutch postcode (for example `1011AB`) and *Distance from postcode*
in kilometres to keep the watchlist local. Marktplaats' own interface offers 3, 5, 10, 15, 25, 50 and
100 km; any positive number works. Leave the postcode empty to watch the whole of the Netherlands.

### What you get

One row per price drop:

- **The drop** — `previousPrice`, `price`, `priceDropPct`, `priceType`.
- **The listing** — `listingId`, `title`, `condition`, `category`, `imageUrl`, `imageCount`, `url`,
  `city`, `countryName`, `postedAt`, `postedText`, `isPromoted`.
- **The seller** — `sellerType`, `sellerVerified`, and an anonymous `sellerHash` so you can spot the
  same reseller across listings. No names, no IDs.
- **The history** — `changeType`, `firstSeenAt`, `lastSeenAt`, `daysListed`.
- **The search** — `searchQuery`, `listingCount`, `priceDropCount`, `medianPrice`, so every row tells
  you whether the new price is actually below the market for that search.

### Price

- **Price drop returned**: $4 per 1,000 listings

Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (`found:false`) are never charged.

- **Price drops:** $4 per 1,000 rows returned, plus a $0.00005 start fee per run.
- **A quiet run costs the start fee only.** Nothing cheaper means no rows, and no rows means no
  charge — even though the actor still fetched and compared every page.
- A search that returns nothing, or a request Marktplaats refuses, is never billed.

Worked example. One watchlist checked hourly on a search where about 4 listings a day get cheaper:
4 × 30 = 120 rows a month, **about $0.48 plus 720 start fees ($0.04)** — roughly **$0.52 a month**.
The cost of a watchlist is driven by how often prices actually move, not by how often you check.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `searches` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~marktplaats-price-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"searches":["iphone"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

Tips:

- **Check often, it is nearly free.** A run that finds nothing costs $0.00005. Hourly is a reasonable
  cadence; every 15 minutes is fine on a hot search.
- **Set *Price type* to Fixed price.** Drops can only be measured on fixed and asking prices, so this
  removes pages that can never produce a row.
- **Raise the threshold on noisy searches.** Sellers nudge prices by a euro to resurface a listing;
  10 or 15% keeps those out.
- **Use `minPrice` / `maxPrice` to bound the watchlist,** not the keyword — both are applied before
  billing, so a listing outside your range never costs you a row.
- `includeKeywords` and `excludeKeywords` also match before billing: "defect" or "onderdelen" in
  `excludeKeywords` keeps broken items out for free.

### How to filter

Every filter below is optional and off by default — leave it out and you get the exact same price
drops as before. `minPrice`/`maxPrice`/`priceType` already existed; this section adds
`conditions`, `cities`, `includeKeywords`/`excludeKeywords` and `sortBy`. There is no
`availability` filter on this actor: it is a price-drop monitor, and Marktplaats' own feed
already excludes sold listings.

**1. Like-new price drops only:**

```json
{
  "searches": ["iphone"],
  "conditions": ["like_new", "new"]
}
```

`conditions` matches Marktplaats' own Dutch labels (Nieuw, Zo goed als nieuw, Gebruikt, Niet
werkend, Refurbished) — there is no "with tags" grade, so `new_with_tags` never matches.

**2. One city, a word excluded:**

```json
{
  "searches": ["fiets"],
  "cities": ["amsterdam"],
  "excludeKeywords": ["kapot"]
}
```

**3. Biggest price drops, sorted:**

```json
{
  "searches": ["laptop"],
  "minPriceDropPct": 15,
  "sortBy": "price_desc"
}
```

`sortBy` sorts the price drops this run found, after filtering — Marktplaats' own feed is already
newest-first, so leaving it empty (or "Newest") keeps that order unchanged.

### Input

```json
{
  "searches": [
    "iphone"
  ]
}
```

One search per line: keywords like "iphone", or paste a marktplaats.nl search URL (its filter fragment after # is not read; use the Postcode / Distance / Price type fields below instead). Each line becomes a watchlist: the first run remembers the prices it finds, and every run after it returns only the listings that got cheaper. Accepted formats: iphone, racefiets, https://www.marktplaats.nl/q/iphone/.

### Sample output

| query | found | status | searchQuery | listingCount | priceDropCount | medianPrice | listings | listingId | url | title | price | currency | previousPrice | priceDropPct | priceType | city | countryName | postedAt | postedText | imageUrl | imageCount | condition | conditionRaw | conditionBucket | category | sellerHash | sellerVerified | sellerType | isPromoted | changeType | firstSeenAt | lastSeenAt | daysListed | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| iphone | true | OK | <search> | <price drops returned> | <price drops since last run> | \<median price this run (eur)> | \<all price drops found (full list)> | <marktplaats listing id> | <listing link> | <title> | \<price (eur)> | \<currency (always eur — marktplaats.nl is single-currency)> | \<previous price (eur)> | \<price drop %> | <price type> | <city> | <country> | \<posted (date)> | \<posted (as marktplaats words it)> | <image> | <photo count> | <condition> | \<condition (raw, same as condition — marketplace-filters standard column)> | \<condition (standard grade)> | <category id> | \<seller (anonymous hash)> | <seller verified> | <seller type> | <promoted listing> | <change type> | <first seen on a run> | <last seen on a run> | <days listed> | 1970-01-01T00:00:00.000Z |

A real row from the live smoke test (`iphone`, 5 listings checked, 2026-09-26). This is what run
one looks like: the prices are now remembered, and the drops start next run.

```json
{
  "query": "iphone",
  "found": true,
  "status": "OK",
  "searchQuery": "iphone",
  "listingCount": 0,
  "priceDropCount": 0,
  "medianPrice": 470,
  "scrapedAt": "2026-09-26T00:08:32.318Z"
}
```

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~marktplaats-price-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"searches":["iphone"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~marktplaats-price-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"searches":["iphone"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~marktplaats-price-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"searches":["{{search}}"]}`, mapping the row's search into the `searches` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Marktplaats Price Monitor: Price Drop Alert by Keyword" — the agent will find and run this actor.

For a channel or a sheet, add an integration on the Task: trigger on "Apify: run succeeded" in n8n,
Make or Zapier and read the run's dataset. A quiet run leaves one summary row with
`listingCount: 0` — filter on `listingCount > 0` to skip it.

### vs. alternatives

- **A Marktplaats saved search with email alerts.** Free, but it tells you about new listings only.
  Marktplaats does not email you when the price on a listing you already saw comes down, which is the
  change most worth catching.
- **A general Marktplaats scraper.** Returns every match every run. You pay for the same unchanged
  listings again and again, and you diff them yourself.
- **The parent actor,**
  [Marktplaats Scraper](https://apify.com/accountable_eel/marktplaats-listing-lookup). Same engine,
  everything switched on: every current listing on a search, full descriptions, raw seller ID and
  name on request, the sold signal (`changeType: gone`, `gonePresumedSold`, last known price) with a
  watchlist sell-through rate, and up to 1,000 listings per search. Use it when you want the whole
  search; use this one when you want the drops.

### Data & privacy

- **No login, no cookies, no account.** There is no input field that could take a Marktplaats
  session, and none is needed: everything here comes from Marktplaats' public search results.
- **No seller names or IDs.** This variant does not offer the parent's raw-seller-info switch, so
  `sellerId` and `sellerName` are not returned at all. You get `sellerType`, `sellerVerified` and an
  anonymous hash.
- **The price memory holds listing IDs and prices only**, in your own account's storage, and only for
  the watchlists you run.

### FAQ

**Nothing came back on the first run. Is it broken?**
No. The first run has no earlier price to compare with, so it stores what it finds and returns one
summary row with `listingCount: 0`. Drops start from the second run.

**How small a drop will it catch?**
Whatever you set. The default is 5%.

**Why did a bidding listing never produce a drop?**
Because a bid is not a comparable price. Drops are reported for fixed-price and asking-price listings
only; see "Price types" above.

**Can I get new listings too?**
Yes — turn on *Also return listings that are brand new*. They come back marked `changeType: new` and
are billed like any other row.

**Does it tell me when something sold?**
No. Disappeared-listing detection and `gonePresumedSold` live in the parent actor; this one is about
price changes on live listings. See **Related actors**.

**Can I keep it to my own region?**
Yes — set a Dutch postcode and a distance in kilometres.

### Related actors

- **[Marktplaats Scraper: New Listing & Price Alerts](https://apify.com/accountable_eel/marktplaats-listing-lookup)**
  — the parent, and the full-capability version: every current listing on a search, descriptions, raw
  seller ID and name on request, the sold signal with `gonePresumedSold` and days listed, watchlist
  sell-through rate, and up to 1,000 listings per search.
- **[Vinted Price Monitor](https://apify.com/accountable_eel/vinted-price-monitor)** — the same
  price-drop idea on Vinted, with Discord, Slack and Telegram delivery.
- **[OLX New Listing Alert](https://apify.com/accountable_eel/olx-new-listing-alert)** — new ads only,
  on OLX classifieds.

# Actor input Schema

## `searches` (type: `array`):

One search per line: keywords like "iphone", or paste a marktplaats.nl search URL (its filter fragment after # is not read; use the Postcode / Distance / Price type fields below instead). Each line becomes a watchlist: the first run remembers the prices it finds, and every run after it returns only the listings that got cheaper. Accepted formats: iphone, racefiets, https://www.marktplaats.nl/q/iphone/. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. One keyword per line, case-insensitive. A listing is kept only if its title contains at least one of these. Leave empty to keep every title.

## `excludeKeywords` (type: `array`):

Optional. One keyword per line, case-insensitive. A listing whose title contains any of these is dropped. Leave empty to drop nothing.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `maxListingsPerSearch` (type: `integer`):

Marktplaats returns up to 100 listings per request (the real, confirmed ceiling: 101 is rejected); this actor pages automatically above that, up to 1000 per search. This is how deep the watchlist looks, not how many rows you get back: you only pay for the listings whose price actually fell.

## `minPrice` (type: `integer`):

Optional. Drop listings priced below this. Leave empty for no minimum. Applied after fetching (no confirmed API price-range parameter).

## `maxPrice` (type: `integer`):

Optional. Drop listings priced above this. Leave empty for no maximum. Applied after fetching (no confirmed API price-range parameter).

## `conditions` (type: `array`):

Optional. One per line: new\_with\_tags, new, like\_new, good, fair, unknown. Leave empty to keep every condition. Matched against Marktplaats' own Dutch labels (Nieuw, Zo goed als nieuw, Gebruikt, Niet werkend, Refurbished — there is no "with tags" grade, so new\_with\_tags never matches). A listing with no condition attribute is unknown.

## `cities` (type: `array`):

Optional. One city name per line, case-insensitive, matched as a "contains" against the listing's own city. Leave empty to keep every location.

## `sortBy` (type: `string`):

Optional. Sorts the price drops this run found, after filtering. Leave empty to keep Marktplaats' own newest-first ordering (the existing default behaviour, unchanged).

## `priceType` (type: `string`):

Optional. Keep only listings of this price type. Price-drop detection only ever fires on a fixed price or an asking price, so setting this to "Fixed price" is the cleanest way to run this watchlist. FIXED, MIN\_BID, FAST\_BID and SEE\_DESCRIPTION were observed live; BID, FREE, ASKING, TRADE and RESERVED are Marktplaats' other documented values. Applied after fetching.

## `postcode` (type: `string`):

Optional. A Dutch postcode (e.g. "1011AB") — confirmed live to change every listing's distance and re-center results. Leave empty to search all of the Netherlands.

## `distanceKm` (type: `integer`):

Only used when "Postcode to search near" is set. Marktplaats' own UI offers 3, 5, 10, 15, 25, 50, 100 km — any positive number works on the API.

## `deltaMode` (type: `boolean`):

On by default: this is what the actor is for. The first run remembers every listing and price it finds and returns a single summary row. From the second run on, a listing comes back only when its price has fallen by at least the percentage below since it was last seen, with the old price, the new price and the drop percentage on the row. Unchanged listings are dropped before you are billed, so a quiet run costs only the start fee. Turn this off to get every matching listing instead, like an ordinary search.

## `deltaName` (type: `string`):

Leave empty and we derive one from this run's filters, so two schedules with different filters keep separate memories. Type your own name to keep one memory across a filter change, or to have two schedules share one.

## `minPriceDropPct` (type: `integer`):

Only fires for a fixed-price or asking-price listing where both the old and the new price are set (never for bids, free, or "see description" listings). Default 5%: a 200 euro item has to fall by at least 10 euro.

## `alertOnPriceDrop` (type: `boolean`):

On by default, and the whole point of this actor. Turning it off with the checkbox above on leaves nothing to return.

## `alertOnNew` (type: `boolean`):

Off by default, so your results stay price drops only. Turn it on to also get listings this watchlist has never seen, each marked new rather than price-drop. They are billed like any other row.

## `skipFirstRun` (type: `boolean`):

The first run of a watchlist has no earlier price to compare with, so it returns one summary row and no listings either way. This matters only if you also turned on "Also return listings that are brand new": with it on, the first run banks everything silently instead of returning a hundred rows at once.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each listing found gets its own row instead of being grouped under its search. You're still only charged once per search, no matter how many rows it produces.

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

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "searches": [
    "iphone"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "maxListingsPerSearch": 100,
  "conditions": [],
  "cities": [],
  "sortBy": "",
  "priceType": "",
  "postcode": "",
  "deltaMode": true,
  "deltaName": "",
  "minPriceDropPct": 5,
  "alertOnPriceDrop": true,
  "alertOnNew": false,
  "skipFirstRun": false,
  "columns": [
    "searchQuery",
    "listingCount",
    "priceDropCount",
    "medianPrice",
    "listings",
    "listingId",
    "url",
    "title",
    "price",
    "currency",
    "previousPrice",
    "priceDropPct",
    "priceType",
    "city",
    "countryName",
    "postedAt",
    "postedText",
    "imageUrl",
    "imageCount",
    "condition",
    "conditionRaw",
    "conditionBucket",
    "category",
    "sellerHash",
    "sellerVerified",
    "sellerType",
    "isPromoted",
    "changeType",
    "firstSeenAt",
    "lastSeenAt",
    "daysListed"
  ],
  "expandRows": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "searches": [
        "iphone"
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
    "conditions": [],
    "cities": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/marktplaats-price-monitor").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 = {
    "searches": ["iphone"],
    "includeKeywords": [],
    "excludeKeywords": [],
    "conditions": [],
    "cities": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/marktplaats-price-monitor").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 '{
  "searches": [
    "iphone"
  ],
  "includeKeywords": [],
  "excludeKeywords": [],
  "conditions": [],
  "cities": []
}' |
apify call accountable_eel/marktplaats-price-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/marktplaats-price-monitor"
        }
    }
}
```

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/Eg9Vwh8ZRFiBvHGnz/builds/Kchewt4AlD4kcIGtw/openapi.json
