# Vinted Scraper — search & extract listings (`serene_trombone/vinted-scraper`) Actor

Scrape Vinted marketplace listings across 14 countries. Extract prices, brands, seller data, images, and more from the second-hand fashion platform.

- **URL**: https://apify.com/serene\_trombone/vinted-scraper.md
- **Developed by:** [Steven Bennett](https://apify.com/serene_trombone) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 some-events

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

> Extract listings from [Vinted](https://www.vinted.co.uk/) — Europe's largest second-hand fashion marketplace with 80M+ members across 16 countries.

**No existing Vinted scraper on Apify Store.** First-mover advantage in this niche.

![Vinted Scraper demo](screenshot.jpg)

***

### Features

- 🔍 **Search anything** — keyword, brand, size, price range, condition filters
- 🌍 **14 country domains** — UK, France, Germany, Netherlands, Italy, Spain, Poland, US, Czechia, Austria, Lithuania, Luxembourg, Portugal, Belgium
- 📊 **Rich data** — price (incl. buyer protection fee), brand, size, condition, photos, seller info, favourites, view count, promoted status
- 🔄 **Smart sorting** — newest, price low→high, price high→low, relevance
- 🛡️ **Anti-bot resistant** — headless browser with session rotation handles Cloudflare
- 📦 **No full detail needed** — catalog pages already contain all item data
- 💰 **Pay-per-event** — you only pay for what you use

### Pricing

| Event | Price |
|-------|-------|
| **Start** | $0.50 per run |
| **Per item** | $0.0015 per listing ($1.50 / 1,000 items) |

A typical search for "jeans" (960 results) would cost **~$1.94**. A small search (50 results) costs **~$0.58**.

### Quick Start

#### Via Apify Console

1. Go to [Vinted Scraper](https://console.apify.com/actors/QWfxGzSOiY05QAjGI) in Apify Console
2. Click **Run** and fill in the fields:
   - `search` — what to look for (e.g. "Levi's 501")
   - `country` — Vinted domain (e.g. `co.uk`, `fr`, `de`)
   - `maxItems` — how many listings to scrape
3. Wait for the run to complete
4. Download results as JSON, CSV, or Excel

#### Via API

```bash
curl -X POST "https://api.apify.com/v2/acts/~vinted-scraper/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "search": "Levi's 501",
    "country": "co.uk",
    "maxItems": 100,
    "order": "price_low_to_high"
  }'
```

#### Via Apify SDK (Node.js)

```javascript
import { Actor } from 'apify';

const run = await Actor.call('~vinted-scraper', {
  search: 'Levi\'s 501',
  country: 'co.uk',
  maxItems: 100,
});

const { items } = await Actor.openDataset(run.defaultDatasetId);
console.log(items);
```

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `search` | `string` | **required** | Search keyword or phrase |
| `country` | `string` | `co.uk` | Vinted domain: `co.uk`, `fr`, `de`, `nl`, `it`, `es`, `pl`, `com`, `cz`, `at`, `lt`, `lu`, `pt`, `be` |
| `maxItems` | `number` | `100` | Max listings to scrape (1–100,000) |
| `order` | `string` | `newest_first` | Sort: `newest_first`, `price_low_to_high`, `price_high_to_low`, `relevance` |
| `brand` | `string` | — | Filter by brand name |
| `size` | `string` | — | Filter by size ID |
| `minPrice` | `number` | — | Minimum price |
| `maxPrice` | `number` | — | Maximum price |
| `condition` | `string` | — | `new_with_tags`, `new_without_tags`, `very_good`, `good`, `satisfactory` |
| `scrapeFullDetails` | `boolean` | `false` | Visit each item's detail page for descriptions |
| `proxyConfiguration` | `object` | Apify proxy | Proxy configuration (recommended) |

### Output Schema

Each scraped listing returns the following fields:

#### Basic Fields (all modes)

| # | Field | Type | Description |
|---|-------|------|-------------|
| 1 | `id` | `number` | Unique Vinted item ID |
| 2 | `title` | `string \| null` | Listing title |
| 3 | `brand` | `string \| null` | Brand name (e.g. Levi's, Zara) |
| 4 | `price` | `number \| null` | Item price |
| 5 | `currency` | `string \| null` | Currency code (GBP, EUR, USD) |
| 6 | `totalPrice` | `number \| null` | Price + buyer protection fee |
| 7 | `serviceFee` | `number \| null` | Vinted's buyer protection fee |
| 8 | `size` | `string \| null` | Size label (e.g. "M / UK 12-14") |
| 9 | `condition` | `string \| null` | Item condition (New, Very good, Good, Satisfactory) |
| 10 | `image` | `string \| null` | Main photo URL |
| 11 | `images` | `string[]` | All photo URLs (up to 20) |
| 12 | `url` | `string \| null` | Direct link to the listing on Vinted |
| 13 | `favouriteCount` | `number` | Number of favourites/likes |
| 14 | `viewCount` | `number` | Number of views |
| 15 | `promoted` | `boolean` | Whether the item is promoted (boosted) |
| 16 | `sellerId` | `number \| null` | Vinted user ID of the seller |
| 17 | `sellerUsername` | `string \| null` | Seller's username |
| 18 | `sellerAvatar` | `string \| null` | Seller's profile picture URL |
| 19 | `sellerBusiness` | `boolean` | Whether seller has a business account |
| 20 | `country` | `string` | Country domain scraped (e.g. `co.uk`, `fr`) |
| 21 | `scrapedAt` | `string` | ISO 8601 timestamp of when the item was scraped |

#### Detail Fields (when `scrapeFullDetails: true`)

| # | Field | Type | Description |
|---|-------|------|-------------|
| 22 | `description` | `string \| null` | Full item description text |
| 23 | `material` | `string \| null` | Material composition (if available) |
| 24 | `colour` | `string \| null` | Item colour (if available) |
| 25 | `brandSize` | `string \| null` | Brand-specific size label |
| 26 | `specificFields` | `object \| null` | Key-value pairs from item specifics table |

### Sample Output

```json
{
  "id": 9316064421,
  "title": "Nike Pro Fit Orange Activewear Tank Top Size XXL",
  "brand": "Nike",
  "price": 7.0,
  "currency": "GBP",
  "totalPrice": 8.05,
  "serviceFee": 1.05,
  "size": "XXL",
  "condition": "Very good",
  "image": "https://images1.vinted.net/t/06_012fc_.../f800/1783154961.webp",
  "images": [
    "https://images1.vinted.net/t/06_012fc_...1/f800/1783154961.webp",
    "https://images1.vinted.net/t/03_00f7f_...2/f800/1783154961.webp"
  ],
  "url": "https://www.vinted.co.uk/items/9316064421-nike-tank-top",
  "favouriteCount": 0,
  "viewCount": 0,
  "promoted": false,
  "sellerId": 189006959,
  "sellerUsername": "louisloftus",
  "sellerAvatar": "https://images1.vinted.net/t/01_00cb7_.../f800/1779568859.webp",
  "sellerBusiness": false,
  "country": "co.uk",
  "scrapedAt": "2026-07-04T11:30:18.220Z"
}
```

### Use Cases

- **Reseller research** — find underpriced items, track trends
- **Brand monitoring** — track how much your brand trades for second-hand
- **Market analysis** — fashion economics, price distribution studies
- **Competitive intelligence** — monitor competitor products
- **Data collection** — AI/ML training datasets for fashion models

### Rate Limits & Anti-Bot

Vinted uses Cloudflare protection. This Actor handles it with:

- ✅ Headless Playwright browser (full JS rendering)
- ✅ Session rotation with Apify proxy
- ✅ Retry logic with backoff
- ✅ Stealth plugin to avoid detection

Using the Actor without Apify proxy may result in blocking.

### Technical Details

The scraper extracts data from Vinted's **React Server Components (RSC)** streaming payload — the same data the frontend renders. This means:

- No fragile CSS selector dependency
- No DOM parsing errors
- Clean, structured JSON extraction
- Fast page-level data collection (no per-item requests unless `scrapeFullDetails` is enabled)

**Stack:** Crawlee (PlaywrightCrawler) · Node.js 20 · Apify SDK

### Changelog

#### v1.0 — 2026-07-04

- Initial release
- 14 country domain support
- Full search/filter pipeline
- RSC payload extraction
- Detail page scraping (optional)

***

*Built with 🛠️ by Meester Bot · Not affiliated with Vinted*

# Actor input Schema

## `search` (type: `string`):

What to search for on Vinted (e.g. 'Levi's jeans', 'Adidas trainers')

## `country` (type: `string`):

Vinted domain to scrape (e.g. 'co.uk', 'fr', 'de', 'nl', 'it', 'es')

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

Maximum number of listings to scrape. 0 = unlimited (scrapes all available pages).

## `brand` (type: `string`):

Filter by brand name (e.g. 'Levi's', 'Zara', 'Nike'). Leave empty for all brands.

## `size` (type: `string`):

Filter by size (e.g. 'M', '8', '34', 'S/M'). Leave empty for all sizes.

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

Minimum price in the local currency. Leave empty for no minimum.

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

Maximum price in the local currency. Leave empty for no maximum.

## `condition` (type: `string`):

Filter by item condition. Leave empty for all conditions.

## `order` (type: `string`):

How to sort results on Vinted

## `scrapeFullDetails` (type: `boolean`):

Visit each item page to get full description, all images, seller info, and item specifics. Takes longer but gives richer data.

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

⚠️ Vinted blocks datacenter IPs. Use residential proxies for reliable scraping (Apify Proxy Residential add-on, or bring your own).

## Actor input object example

```json
{
  "search": "Levi's jeans",
  "country": "co.uk",
  "maxItems": 100,
  "order": "newest_first",
  "scrapeFullDetails": false
}
```

# 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 = {
    "search": "Levi's jeans"
};

// Run the Actor and wait for it to finish
const run = await client.actor("serene_trombone/vinted-scraper").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 = { "search": "Levi's jeans" }

# Run the Actor and wait for it to finish
run = client.actor("serene_trombone/vinted-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "search": "Levi'\''s jeans"
}' |
apify call serene_trombone/vinted-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=serene_trombone/vinted-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/QWfxGzSOiY05QAjGI/builds/H1K3O4OPHk5FpHy7S/openapi.json
