# Vinted Deal Monitor (`lowlanddata/vinted-deal-monitor`) Actor

Sweeps one Vinted search each run, computes the query's live median price, and delivers the listings priced far below it - each deal with the median and discount percent attached. Scheduled hourly it is an underpriced-listing alert feed. Finds, never auto-buys. No seller data.

- **URL**: https://apify.com/lowlanddata/vinted-deal-monitor.md
- **Developed by:** [Lowland Data](https://apify.com/lowlanddata) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.79 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Vinted Deal Monitor — underpriced-listing alerts

Watch one Vinted search and get alerted to **new listings priced well below the market**. Each run sweeps the search newest-first, computes the query's current median asking price, and delivers only the listings at least N% under it — each deal carrying the median it was scored against and its discount percent. Put it on an hourly Schedule and it becomes a deal alert feed: quiet when nothing is cheap, loud when something is.

Built on the [Vinted Scraper](https://apify.com/lowlanddata/vinted-scraper) and its privacy guarantee: **no seller personal data, ever** — no usernames, no user IDs, no profile links, by design.

There are paid Vinted "sniping" tools that log into your account and buy for you. This is the API-first, no-auto-buy version: it finds, you decide. Structured JSON, standard Apify scheduling, and your own eyes on the listing photos before any money moves.

### Quick start (30 seconds)

1. Put your target search into **searchQuery** — e.g. `nike air max 90`. Narrow queries give sharper medians.
2. Pick your **domain** — `fr`, `de`, `co.uk`, `be`... (23 country sites).
3. Click **Start**. The first run establishes the baseline and shows every current deal; open the dataset's **Overview** tab for the table.
4. Add an hourly **Schedule** with the same input — from then on, each run delivers only the deals that appeared since the last one.

Real example: `nike air max 90` on vinted.fr scored against a median of 60.00 EUR over 286 sampled listings — the first sweep alone surfaced 25+ listings priced 40% or more below it.

### How it works

One sweep serves both sides of the comparison:

- The actor reads `samplePages` catalog pages of your search, newest-first. Page 1 carries the new listings; the extra pages steady the median.
- From that sample it computes the **current median asking price** — live market price, this hour, not a stale reference.
- Every listing the actor has not seen before is scored against that median. At or past your `discountThresholdPct`, it is delivered as a deal with `queryMedianCents` and `discountPct` attached.
- A cross-run memory (a named key-value store) remembers which listings were already evaluated, so each listing is judged exactly once. Entries expire after a month — sold or bumped away long before that.

The median needs at least 20 priced listings in the sample; with fewer, there is no market price worth scoring against, and the run fails with a readable message telling you to broaden the query or raise `samplePages`.

Run statuses say plainly what happened: `"12 deals in the current snapshot (baseline established)"` on the first run, `"3 new deals at least 30% below the median"` after that.

### Honest limits

- **Minutes, not milliseconds.** Latency is your schedule cadence. An hourly schedule means a deal can be up to an hour old when you see it. That beats refreshing search pages by hand; it does not beat a logged-in bot that buys in two seconds — and this actor will never be that bot. No auto-buy, no Vinted account, no checkout, deliberately.
- **A discount is a lead, not a verdict.** A listing far below median can be a genuine bargain — or damaged, fake, or a different model than the title says. The output gives you price, condition, brand, size and up to 8 photos; the photos are the judge.
- **The median moves.** It is computed from the live sample each run, so it drifts with the market and with what happens to be listed. A narrow query and a few sample pages keep it steady; a vague query makes it noisy.

### Who uses it

- **Resellers sourcing stock.** Watch the models you flip; buy only what lands 30–50% under market. The median and discount are already computed — your sourcing rule becomes a filter, not a judgment call.
- **Bargain hunters after one item.** Watching for a specific jacket in your size? Set the query, set the threshold, schedule it, and get an email when a cheap one appears — instead of checking the app ten times a day.
- **Dropship-style flippers.** Feed the deal stream into a pipeline: the JSON carries everything needed to score, filter and act on a listing without opening a browser.

### What you get

Each deal is one dataset item — the full listing card plus the two scoring fields:

```json
{
  "itemId": "9720000001",
  "url": "https://www.vinted.fr/items/9720000001-nike-air-max-90",
  "title": "Nike Air Max 90",
  "brand": "Nike",
  "size": "42",
  "condition": "Très bon état",
  "priceCents": 2500,
  "currency": "EUR",
  "serviceFeeCents": 195,
  "totalPriceCents": 2695,
  "businessSeller": false,
  "promoted": false,
  "favouriteCount": 3,
  "imageUrls": ["https://images1.vinted.net/t/example/f800/1.webp"],
  "queryMedianCents": 6000,
  "discountPct": 58
}
```

Field notes:

- `queryMedianCents` is the query's median asking price at the moment this deal was scored — the market context travels with the deal, so a row still makes sense a week later.
- `discountPct` is how far below that median the asking price sits.
- `priceCents` is the asking price in minor units; `totalPriceCents` includes Vinted's buyer-protection fee — what you actually pay.
- `condition` and `size` arrive in the site's language, exactly as displayed.
- `favouriteCount` is a live demand signal — a deep discount with favourites already piling up will not last the hour.
- `url` is the direct link. Deals go fast; the link is the point.
- `businessSeller` separates professional sellers from private ones. Seller identity is never collected.

### How much does it cost?

$1.99 per 1,000 deals delivered, pay-as-you-go. You pay for deals, not for looking: a quiet run that finds nothing new costs nothing beyond the actor start. That is the economics a monitor should have — 24 hourly sweeps of a slow niche might deliver five deals all day, and you pay for five.

The price is all-inclusive — platform usage is covered, no separate compute or proxy charges, and standard datacenter proxies are sufficient.

Free-plan runs are limited to 25 deals per run, enough to see the baseline sweep and the output format against your real query.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "Vinted Deal Monitor" actor on Apify
(https://apify.com/lowlanddata/vinted-deal-monitor). Guide me one step at a time.

What I want deal alerts for: [E.G. "Nike Air Max 90 on vinted.fr, at least 30% below market"]

Guide me to:
1. Propose my input values: searchQuery (narrow beats vague - the median is sharper),
   domain (fr, de, co.uk, be, ...), discountThresholdPct (30 is a good start),
   an optional priceMin/priceMax band, and samplePages (3 is fine).
2. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start a run - the first run establishes the baseline.
3. Set up an HOURLY Schedule in the Apify Console with the same input, plus an
   email or Slack integration on the runs, so every new deal reaches me within
   the hour it appears.
4. Show me how to export deals as CSV/Excel, or read them from the API if I code.
5. If it works, remind me at the end to leave a quick rating on the actor page,
   and to report anything broken on its Issues tab.
```

### Input

| Field                   | Description                                                                                                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `searchQuery`           | The market slice to hunt deals in, as you would type it in Vinted's search box. Required. Narrower = sharper median.                                                   |
| `domain`                | National site: `fr` (default), `be`, `de`, `nl`, `es`, `it`, `co.uk`, `pl`, `at`, `pt`, `cz`, `sk`, `lt`, `se`, `dk`, `fi`, `ie`, `lu`, `hu`, `ro`, `gr`, `hr`, `com`. |
| `priceMin` / `priceMax` | Only watch listings inside this price band (site currency). Also tightens the median.                                                                                  |
| `discountThresholdPct`  | Minimum percent below the median to count as a deal. 10–80, default 30 — catches real bargains without noise.                                                          |
| `samplePages`           | Catalog pages swept per run, 1–10, default 3. Page 1 carries the new listings; extra pages steady the median.                                                          |
| `stateStoreName`        | Named store remembering which listings were already evaluated. Use a different name per watched query.                                                                 |
| `resetState`            | Forget the tracked listings and re-seed the baseline on this run. Default `false`.                                                                                     |
| `maxItems`              | Upper bound on deals delivered per run (default 100; free plan 25). Deals over the cap stay pending and arrive next run.                                               |
| `proxyConfiguration`    | Proxy settings; keep Apify proxy enabled.                                                                                                                              |

A run minimally needs a `searchQuery`; a sample too thin to define a market price fails immediately with the reason in the run's status message.

### Use it from your code

Run the monitor and get the deals straight back with one HTTP call:

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~vinted-deal-monitor/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"searchQuery": "nike air max 90", "domain": "fr", "discountThresholdPct": 30}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/vinted-deal-monitor').call({
  searchQuery: 'nike air max 90',
  domain: 'fr',
  discountThresholdPct: 30,
});
const { items: deals } = await client.dataset(run.defaultDatasetId).listItems();
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/vinted-deal-monitor").call(
    run_input={"searchQuery": "nike air max 90", "domain": "fr", "discountThresholdPct": 30})
deals = client.dataset(run["defaultDatasetId"]).list_items().items
```

Schedules, webhooks and the Make/Zapier/n8n integrations all work out of the box — this is a standard Apify actor. A webhook on run completion is the natural hookup: it fires only when there is something to act on.

### Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run this monitor as a tool through Apify's hosted MCP server: the agent sets the watch, reads the deals and reasons about them — no glue code.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/vinted-deal-monitor"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/vinted-deal-monitor
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp).

Prompts that work once connected:

- "Check for new 'nike air max 90' deals on vinted.fr at least 40% below market and summarize the best three."
- "Run my 'levis 501' deal watch on vinted.de and tell me if anything is worth buying, given the condition fields."
- "Compare the deals against their photos' listed condition and flag the ones that look too cheap to be right."

### Is it legal to monitor Vinted prices?

Public asking prices, brands, sizes and conditions are public commercial information, and this actor is built so the hard part of the question never arises: **no personal data enters your dataset in the first place.** No usernames, no user IDs, no profile links — the same fixed-whitelist extraction as the parent Vinted Scraper, with the median and discount computed on top. Requests are paced, load on the site is negligible, and no anti-bot protection is bypassed.

### Is there a Vinted API for deals?

Vinted publishes no public API, and no endpoint anywhere serves "listings below market price" — the market price has to be computed. This actor is that computation as a service: one HTTP call, a schedule, or an MCP tool, returning only the listings worth a look, each with the median it was scored against.

### Does Vinted block scrapers?

Vinted protects some routes aggressively, and this actor deliberately stays on the openly served search pages: paced requests, standard datacenter proxies, sessions rotated on failure. If a run is blocked before anything could be fetched, the status says so honestly and a retry a few minutes later usually lands on a clean session. On a schedule, one blocked run costs you nothing and the next run catches up — unseen listings are still unseen.

### How do I get Vinted deal alerts?

This actor **is** the alert — the scheduling is the delivery. Set your input, add an hourly Schedule in the Apify Console, and attach an email or Slack integration to the runs. Quiet hours produce quiet runs; when a run delivers deals, the notification carries them. The AI-assistant prompt above walks a non-technical user through exactly this. Watching several queries? One Schedule each, each with its own `stateStoreName`.

### FAQ

**How do I find underpriced items on Vinted?** Define the market slice as a search query, compute its current median asking price, and flag new listings far below it. That is literally what this actor does each run — you set the query and the threshold, it does the arithmetic.

**Is there a Vinted sniping tool?** Several paid ones exist, most requiring your Vinted login and some buying automatically. This is the API-first alternative: no login, no auto-buy, structured deal data on your own schedule. It finds; you decide.

**Why doesn't it buy automatically?** Deliberately. Auto-buying needs your Vinted account, violates the platform's terms, and spends your money on a listing no human looked at. A very cheap listing can be mispriced — or misdescribed. The discount is a lead; the listing photos are the judge.

**How is the median calculated?** From the priced listings in the run's own sample — `samplePages` pages of your search, newest-first. It is the market price of this query at this hour, not a stored reference. At least 20 priced listings are required, or the run fails with a readable message.

**What exactly counts as a deal?** A listing the actor has not evaluated before, priced at least `discountThresholdPct` percent below the run's median. Both the median and the resulting `discountPct` ship with each deal.

**What threshold should I set?** Start at the default 30%. Too many marginal hits: raise it to 40–50 and only the outliers get through. Silence for days in an active niche: drop toward 20. The range is 10–80.

**What is the baseline run?** The first run against a fresh state store scores everything currently listed — expect a burst of deals and the status "N deals in the current snapshot (baseline established)". Every run after that delivers only listings that are new since the last sweep.

**Will I ever get the same deal twice?** No. Each listing is evaluated exactly once and remembered in the state store for a month. Delete the store or set `resetState` to start over.

**What happens when a run finds more deals than maxItems?** The overflow is not lost. Undelivered deals stay pending and arrive on the next run — relevant mostly for the baseline burst on a free plan's 25-deal cap.

**Can I watch several searches at once?** Yes — one Schedule per query, each with its own `stateStoreName`. The state is keyed to the query, so separate stores keep separate memories.

**How often should I schedule it?** Hourly is the sweet spot for most niches: fresh enough that good deals are usually still available, cheap because quiet runs cost nothing beyond the start. A fast-moving query can justify every 15–30 minutes; a slow one, every few hours.

**How fast will I see a new listing?** Within one schedule interval — minutes, not seconds. This is a monitor, not a sniper; if two-second reaction time is the requirement, no polling tool honestly delivers it.

**Why did my run fail with "too few priced listings"?** The sample held fewer than 20 priced listings, so no meaningful median exists. Broaden the query, widen the price band, or raise `samplePages`.

**Can a flagged deal be a scam or a mistake?** Yes — that is exactly why there is no auto-buy. Deep discounts correlate with genuine urgency *and* with damage, fakes and mislabeled items. Check the photos and condition field before paying.

**Does the median change between runs?** Yes, it follows the live sample: new listings arrive, cheap ones sell. A narrow query with `samplePages` at 3 or more keeps it steady. Each deal records the median it was scored against, so past rows stay interpretable.

**How much does it cost?** $1.99 per 1,000 deals delivered. Runs that find nothing new cost nothing beyond the actor start — you pay for deals, not for watching.

**Do I need a Vinted account or API key?** No. The monitor reads openly served search pages; the only account involved is your Apify account, and the free plan is enough to test with.

**Can I export deals to Excel or CSV?** Yes — every dataset exports as CSV, Excel, JSON or XML from the Apify Console or API, and the Overview tab shows price, median and discount side by side.

**Can I get seller names or profiles?** No — by design, and it is inherited from the parent scraper's whitelist. Deal data you can store and process without a privacy review.

### Related scrapers

The same privacy guarantee across the Vinted family:

- [Vinted Scraper](https://apify.com/lowlanddata/vinted-scraper) — the parent: full search extraction, price bands, AI-normalized fields.
- [Vinted Arbitrage Scanner](https://apify.com/lowlanddata/vinted-arbitrage-scanner) — the same query priced across countries, to see where an item is cheap to buy and dear to sell.
- [Vinted Sold Detector](https://apify.com/lowlanddata/vinted-sold-detector) — tracks listings until they sell, for real sale-through data.

### Troubleshooting

The actor fails fast with the reason in the run's status message:

- **"Only N priced listings in the sample - too few to define a market price for this query. Broaden the query or raise samplePages."** — the sample was under 20 priced listings; widen the query or the price band, or raise `samplePages`.
- **"Vinted blocked the run before any results could be fetched."** — a temporary block; retry in a few minutes. On a schedule the next run catches up automatically.
- **A flood of deals on the first run** — that is the baseline sweep scoring everything currently listed. Subsequent runs deliver only what is new.
- **Fewer deals than expected on a free plan** — the 25-deal free cap; the overflow arrives on following runs, and paid plans deliver up to `maxItems` at once.

### Support

Found an issue or missing a field you need? Open an issue on the actor's **Issues tab** — reports get fixed, this actor is actively maintained.

Working well for you? A **rating on this page** takes ten seconds and helps other buyers find the no-login, no-auto-buy option among the sniping tools — and it is the clearest signal of what to build next.

# Actor input Schema

## `searchQuery` (type: `string`):

The market slice to hunt deals in, exactly as you would type it in Vinted's search box, e.g. "nike air max 90". Narrower queries give sharper medians.

## `domain` (type: `string`):

Which national Vinted site to watch.

## `priceMin` (type: `integer`):

Watch only listings at or above this price (site currency) - the standard way to narrow a broad query.

## `priceMax` (type: `integer`):

Watch only listings at or below this price (site currency).

## `stateStoreName` (type: `string`):

Named store remembering which listings were already evaluated, so scheduled runs alert each deal once. Use a different name per watched query.

## `resetState` (type: `boolean`):

Forget the tracked listings and re-seed the baseline on this run.

## `maxItems` (type: `integer`):

Upper bound on deals delivered per run.

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

Proxy settings. Keep Apify proxy enabled.

## `discountThresholdPct` (type: `integer`):

A listing must be at least this far below the query's current median to count as a deal. 30 catches real bargains without noise.

## `samplePages` (type: `integer`):

Catalog pages swept per run (1-10). Page 1 carries the new listings; extra pages steady the median.

## Actor input object example

```json
{
  "searchQuery": "nike air max 90",
  "domain": "fr",
  "stateStoreName": "vinted-deal-monitor-state",
  "resetState": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "discountThresholdPct": 30,
  "samplePages": 3
}
```

# Actor output Schema

## `deals` (type: `string`):

Underpriced listings, one JSON object per deal.

# 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 = {
    "searchQuery": "nike air max 90",
    "domain": "fr",
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "discountThresholdPct": 30,
    "samplePages": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/vinted-deal-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 = {
    "searchQuery": "nike air max 90",
    "domain": "fr",
    "proxyConfiguration": { "useApifyProxy": True },
    "discountThresholdPct": 30,
    "samplePages": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/vinted-deal-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 '{
  "searchQuery": "nike air max 90",
  "domain": "fr",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "discountThresholdPct": 30,
  "samplePages": 3
}' |
apify call lowlanddata/vinted-deal-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lowlanddata/vinted-deal-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/I5USuDXjmhIW12aAt/builds/0bmqnQfQ71AOOZVk0/openapi.json
