# Vinted Scraper & New Listing Monitor (`trovevault/vinted-scraper-monitor`) Actor

Monitor multiple Vinted searches across countries and return only listings discovered since the previous successful run.

- **URL**: https://apify.com/trovevault/vinted-scraper-monitor.md
- **Developed by:** [Trove Vault](https://apify.com/trovevault) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 products

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 Scraper & New Listing Monitor

Scrape current Vinted listings on demand or monitor searches and receive only listings that were not present in the previous successful monitoring run. The Actor works across 26 Vinted countries and extracts structured listing data including price, buyer-protection price, brand, size, condition, image, country, and direct URL.

Use **Scrape current listings** for research, catalog exports, resale sourcing, price comparison, and one-off searches. Use **Monitor new listings** with an Apify schedule when speed matters and you want a clean feed of newly discovered items instead of downloading the same results every minute.

The Actor reads public search pages without a Vinted login. It does not interact with listings or accounts.

### Scraper mode and monitor mode

#### Scrape current listings

This is the default mode. Every run returns the current listings found for each configured search, up to \`maxResultsPerSearch\`. It does not consult or update monitoring history. Running the same input twice can therefore return the same listings twice, which is expected for a scraper.

#### Monitor new listings

Monitor mode keeps a private list of previously observed listing IDs for each distinct search and country. On later successful runs, it emits only listings whose IDs were not in that search's stored history. Monitoring works best with an Apify schedule, for example every minute, every five minutes, or hourly.

The first monitoring run has two possible behaviors:

- \`return\_current\`: return the current matching listings and store them as the initial baseline.
- \`establish\_baseline\`: store the current matching listings without output, so later runs emit only subsequent discoveries.

Monitoring state is updated only after a search succeeds. A failed request does not erase or replace the last known baseline. State belongs to this Actor and is shared by its scheduled and manual runs, so use stable search inputs for a stable monitoring stream.

### Supported countries

The Actor supports France, Germany, Portugal, Spain, Italy, the Netherlands, the United Kingdom, the United States, Belgium, Luxembourg, Austria, Poland, Czechia, Slovakia, Lithuania, Latvia, Estonia, Sweden, Denmark, Finland, Hungary, Romania, Croatia, Greece, Ireland, and Slovenia.

### Input

| Field | Type | Description |
| --- | --- | --- |
| \`mode\` | string | \`scrape\_current\` returns current results every run. \`monitor\_new\` keeps state and returns only newly discovered listings after the baseline. |
| \`searchTerms\` | string\[] | Keywords, brands, models, or product descriptions. Every term runs in every selected country. |
| \`countries\` | string\[] | One or more supported Vinted country codes. |
| \`searchUrls\` | request list | Optional complete Vinted catalog URLs containing filters configured on Vinted. |
| \`minPrice\` | number | Optional minimum price for keyword-based searches. |
| \`maxPrice\` | number | Optional maximum price for keyword-based searches. |
| \`maxResultsPerSearch\` | integer | Maximum newest listings checked per search, from 1 to 500. |
| \`firstRunMode\` | string | First-run behavior for monitor mode only: \`return\_current\` or \`establish\_baseline\`. |
| \`proxyConfiguration\` | object | Optional Apify Proxy settings for blocked cloud requests. |
| \`datasetId\` | string | Optional existing dataset that receives a second copy of every row. |
| \`runId\` | string | Optional workflow identifier copied to every row. |

At least one usable search term or filtered search URL is required. Blank terms are removed and duplicate terms, countries, and URLs are normalized. Price filters apply to keyword searches; parameters already included in pasted Vinted URLs are preserved.

#### Example: scrape current listings

```json
{
  "mode": "scrape_current",
  "searchTerms": ["Barbour jacket", "Carhartt Detroit"],
  "countries": ["fr", "de", "pt"],
  "minPrice": 20,
  "maxPrice": 180,
  "maxResultsPerSearch": 96
}
```

This creates six searches: two terms across three markets. The Actor returns the current results found in all searches and deduplicates listings that overlap within the run.

#### Example: monitor new listings

```json
{
  "mode": "monitor_new",
  "searchTerms": ["Arc'teryx Beta"],
  "countries": ["fr", "de", "it", "es"],
  "maxResultsPerSearch": 96,
  "firstRunMode": "establish_baseline",
  "runId": "arcteryx-europe"
}
```

Schedule this input to run repeatedly. The first run creates the baseline without output. Later runs output only IDs that were not previously observed for those searches.

### Output

Results are stored in the run's default dataset. Each row represents one listing observed in one Vinted market.

```json
{
  "itemId": "1234567890",
  "title": "Barbour Bedale wax jacket",
  "brand": "Barbour",
  "size": "M",
  "condition": "Very good",
  "price": 85,
  "priceWithBuyerProtection": 89.2,
  "currency": "EUR",
  "country": "fr",
  "url": "https://www.vinted.fr/items/1234567890-barbour-bedale-wax-jacket",
  "imageUrl": "https://images1.vinted.net/...",
  "matchedSearches": ["Barbour jacket"],
  "discoveryReason": "current_snapshot",
  "observedAt": "2026-08-15T10:30:00.000Z",
  "runId": null
}
```

| Field | Meaning |
| --- | --- |
| \`itemId\` | Stable public Vinted listing identifier. |
| \`title\` | Listing title derived from the public item URL. |
| \`brand\` | Brand shown in the search result, when available. |
| \`size\` | Displayed size, when available. |
| \`condition\` | Condition label displayed in the selected market. |
| \`price\` | Listing price before buyer protection and shipping. |
| \`priceWithBuyerProtection\` | Displayed price including buyer protection, when available; shipping is excluded. |
| \`currency\` | Currency associated with the selected market. |
| \`country\` | Vinted market where the listing was observed. |
| \`url\` | Direct public listing URL. |
| \`imageUrl\` | Primary image URL, when available. |
| \`matchedSearches\` | All configured searches that matched the listing during the run. |
| \`discoveryReason\` | \`current\_snapshot\`, \`initial\_snapshot\`, or \`new\_since\_previous\_run\`. |
| \`observedAt\` | UTC time when this run observed the listing, not Vinted's publication time. |
| \`runId\` | Optional identifier copied from the input. |

Fields that Vinted does not expose consistently are returned as \`null\`. Monetary values are numbers, while \`currency\` supplies their context. Buyer protection and shipping rules can vary by country and buyer, so treat the displayed buyer-protection value as an observation rather than a checkout quote.

### Deduplication and monitoring state

Within one run, the Actor identifies a listing by \`country\` plus \`itemId\`. If several configured searches find the same listing, one row is emitted and \`matchedSearches\` contains all matching labels.

In monitor mode, each search keeps its own state key. Search terms, countries, filtered URLs, and price settings are part of that identity. Materially changing a search can create a new baseline, which is safer than applying unrelated history to a new query.

The monitor retains up to 10,000 observed IDs per search. This is designed for frequent new-listing detection, not as a permanent historical database. Store emitted results in a dataset, database, webhook workflow, or other destination if you need long-term history.

### API

Run the Actor through the Apify API with the slug \`trovevault~vinted-scraper-monitor\`:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/trovevault~vinted-scraper-monitor/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "scrape_current",
    "searchTerms": ["Barbour jacket"],
    "countries": ["pt"],
    "maxResultsPerSearch": 20
  }'
```

### Reliability and partial failures

Searches run independently: successful results are saved even if another country fails, and \`RUN\_SUMMARY\` records failures. Vinted can change page structure, rate limits, and access behavior without notice. Coverage is bounded by \`maxResultsPerSearch\` and the newest pages inspected. Start without a proxy; enable a suitable Apify Proxy only if a market repeatedly blocks cloud requests.

### Limitations

- This Actor reads public search results, not private accounts, messages, favorites, orders, or checkout data.
- It does not claim the exact Vinted publication timestamp. \`observedAt\` is the time of this run.
- Search metadata can be absent or localized, so brand, size, condition, image, or buyer-protection price may be \`null\`.
- Deleted or sold listings may disappear between runs; monitor mode is optimized for additions, not removals.
- Monitoring compares IDs inside the newest result window. If more new listings arrive between runs than the configured depth can cover, some may never enter that window.
- Results and currencies are market-specific. Do not combine prices across currencies without conversion.
- The Actor does not bypass access controls and cannot guarantee uninterrupted access to third-party pages.

### Troubleshooting

- No scraper results: loosen filters, verify the term on that market, or paste the complete filtered Vinted URL.
- Empty first monitor run: expected with \`establish\_baseline\`; later runs emit new discoveries.
- Empty repeated monitor: no unseen ID was found in the checked window. Use \`scrape\_current\` for a full current snapshot.
- Repeated scraper rows: expected because scraper mode is stateless. Use monitor mode or downstream deduplication.
- One country fails: inspect \`RUN\_SUMMARY\`, test it separately, and consider a suitable proxy if direct access remains blocked.

### Responsible use

Follow applicable law, Vinted's terms, and Apify's policies. Use reasonable schedules and process only data you are entitled to collect.

# Actor input Schema

## `mode` (type: `string`):

Scrape current listings on every run, or keep a private baseline and return only newly discovered listings on later runs.

## `searchTerms` (type: `array`):

Keywords to scrape or monitor, such as a brand, model, or product description. Every term is checked in every selected country.

## `countries` (type: `array`):

Vinted markets in which every search term should run. Select several countries to search across markets.

## `searchUrls` (type: `array`):

Complete Vinted catalog URLs to scrape or monitor when you need filters such as brand, category, size, color, or condition. Create the search in Vinted, copy its URL, and paste it here.

## `minPrice` (type: `number`):

Exclude listings below this price for keyword-based searches. Currency follows the selected country.

## `maxPrice` (type: `number`):

Exclude listings above this price for keyword-based searches. Currency follows the selected country.

## `maxResultsPerSearch` (type: `integer`):

Maximum number of the newest listings returned or checked for each term-country or pasted URL. Higher values increase coverage, requests, and cost.

## `firstRunMode` (type: `string`):

Choose whether a search returns its current listings on the first run or stores them silently as the initial baseline. Later runs always return only newly discovered listings.

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

Optional Apify Proxy settings. Start without a proxy; enable residential access if a selected Vinted market blocks cloud requests.

## `datasetId` (type: `string`):

Append output rows to an existing Apify dataset in addition to the default run dataset.

## `runId` (type: `string`):

Workflow, campaign, or external job identifier copied into every output row.

## Actor input object example

```json
{
  "mode": "scrape_current",
  "searchTerms": [
    "barbour jacket"
  ],
  "countries": [
    "fr"
  ],
  "maxResultsPerSearch": 20,
  "firstRunMode": "return_current"
}
```

# Actor output Schema

## `dataset` (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 = {
    "mode": "scrape_current",
    "searchTerms": [
        "barbour jacket"
    ],
    "countries": [
        "fr"
    ],
    "maxResultsPerSearch": 20,
    "firstRunMode": "return_current"
};

// Run the Actor and wait for it to finish
const run = await client.actor("trovevault/vinted-scraper-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 = {
    "mode": "scrape_current",
    "searchTerms": ["barbour jacket"],
    "countries": ["fr"],
    "maxResultsPerSearch": 20,
    "firstRunMode": "return_current",
}

# Run the Actor and wait for it to finish
run = client.actor("trovevault/vinted-scraper-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 '{
  "mode": "scrape_current",
  "searchTerms": [
    "barbour jacket"
  ],
  "countries": [
    "fr"
  ],
  "maxResultsPerSearch": 20,
  "firstRunMode": "return_current"
}' |
apify call trovevault/vinted-scraper-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,trovevault/vinted-scraper-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/epD76RKa6ddZuxSiv/builds/mShpUdL6CjEn8uAmR/openapi.json
