# Vinted Listings & Price Scraper (`xtracto/vinted-listings`) Actor

Scrape Vinted second-hand listings across 16 country sites: title, brand, size, condition, asking price, buyer total, seller and engagement counts. Filter by keyword, catalog, brand and price.

- **URL**: https://apify.com/xtracto/vinted-listings.md
- **Developed by:** [Farhan Febrian Nauval](https://apify.com/xtracto) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Listings & Price Scraper

Track what second-hand fashion actually sells for on **Vinted** — Europe's largest peer-to-peer clothing marketplace. Search any of **16 country sites** and get title, brand, size, condition, asking price, the real buyer total, seller info and engagement counts.

### ⚠️ Proxy Requirement

**Residential proxy is required on Apify.** Vinted refuses Apify's datacenter IP ranges outright — a run without a residential proxy returns a single `blocked` record rather than listings. The input ships with `RESIDENTIAL` pre-selected; set `apifyProxyCountry` to match the marketplace you are searching (`GB` for `vinted.co.uk`, `FR` for `vinted.fr`, and so on).

Verified 2026-08-26: datacenter IP → blocked on every fingerprint; GB residential → 20/20 listings with descriptions.

### Why Use This Actor?

- **Both prices, never conflated.** Vinted adds a buyer-protection fee on top of the seller's asking price. You get `price` (what the seller asks), `serviceFee` and `totalPrice` (what the buyer actually pays) as separate fields — so your margin maths is correct.
- **16 marketplaces, local currency.** The same query across `vinted.co.uk`, `vinted.fr`, `vinted.de` and more, each with its own inventory and currency — the basis for cross-border arbitrage analysis.
- **Demand signals, not just prices.** `favouriteCount` and `viewCount` show what buyers are actually watching.
- **Business vs private sellers.** `sellerIsBusiness` separates professional resellers from individuals.
- **Optional descriptions.** Turn on `includeDescription` when you need the seller's own text (flaws, measurements, authenticity notes).
- **No browser.** Plain HTTP against the site's own catalogue API. Fast and cheap.

### What It's Good For

- **Resale pricing** — what does a used Nike Air Max in size 9 fetch this week?
- **Cross-border arbitrage** — compare the same brand across UK, French and German inventory.
- **Brand health** — track volume, average price and likes for a brand over time.
- **Competitor monitoring** — follow business sellers' catalogues and pricing.
- **Sourcing** — find underpriced listings sorted newest-first.

### How It Works

Vinted's catalogue API refuses a cold request. The actor first loads the homepage exactly as a first-time visitor's browser would, which mints an anonymous session, then pages the catalogue with that session. No account and no credentials are involved. If the session ages out mid-run it is refreshed automatically rather than failing the run.

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `domain` | string | `www.vinted.com` | Which country marketplace to search. |
| `searchText` | string | – | Keyword, e.g. `nike air max`. |
| `order` | string | `relevance` | `relevance`, `newest_first`, `price_low_to_high`, `price_high_to_low`. |
| `priceFrom` / `priceTo` | integer | – | Asking-price bounds in the site's currency. |
| `catalogIds` / `brandIds` / `statusIds` | array | – | Vinted's own filter IDs — copy them from a Vinted search URL. |
| `includeDescription` | boolean | `false` | Also fetch each listing's description (one extra request per listing). |
| `maxItems` | integer | `200` | Maximum listings to return. |
| `proxyConfiguration` | object | Residential | **Required on Apify.** Set the country to match `domain`. |

**At least one of `searchText`, `catalogIds` or `brandIds` is required** — the source does not support an unfiltered catalogue sweep, so the actor refuses it up front rather than returning a confusing empty result.

#### Example input

```json
{
  "domain": "www.vinted.co.uk",
  "searchText": "nike air max",
  "order": "newest_first",
  "priceTo": 50,
  "maxItems": 200,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "GB" }
}
```

### Output

One row per listing:

```json
{
  "itemId": 9770335632,
  "title": "Nike Air Max Pink Trainers UK 5.5",
  "url": "https://www.vinted.co.uk/items/9770335632-nike-air-max-pink-trainers",
  "brand": "Nike Air",
  "size": "5.5",
  "condition": "New without tags",
  "price": 20.0,
  "currency": "GBP",
  "totalPrice": 21.7,
  "serviceFee": 1.7,
  "favouriteCount": 3,
  "viewCount": 41,
  "isPromoted": false,
  "sellerId": 118273645,
  "sellerLogin": "sneakervault",
  "sellerUrl": "https://www.vinted.co.uk/member/118273645",
  "sellerIsBusiness": false,
  "photoUrl": "https://images1.vinted.net/...",
  "photoCount": 4,
  "domain": "www.vinted.co.uk",
  "description": "Need a bit of a clean.",
  "_scrapedAt": "2026-08-26T12:56:12.113Z"
}
```

#### Field reference

| Field | Type | Description |
|---|---|---|
| `price` | number | Seller's asking price. |
| `serviceFee` | number | Buyer-protection fee Vinted adds. |
| `totalPrice` | number | What the buyer actually pays (`price` + `serviceFee`). |
| `condition` | string | Vinted's condition label, e.g. `Good`, `New without tags`. |
| `favouriteCount` / `viewCount` | integer | Likes and views — demand signal. |
| `isPromoted` | boolean | `true` for listings the seller paid to boost. |
| `sellerIsBusiness` | boolean | `true` for professional sellers. |
| `description` | string | Only present when `includeDescription` is on. |
| `_error` | string | Present only on failures (`no_filter`, `no_results`, `blocked`, `session_failed`, `http_*`). |

### Known Limits

- **~960 results per search.** The source stops a single search at roughly 48 pages regardless of how many items match — `total_entries` reports 960 even for very broad queries. To go deeper, slice by price band, brand or category and run several searches.
- **`viewCount` and `favouriteCount` are often `0`** on brand-new listings; that is the source's value, not a parsing failure.
- **Descriptions cost a request each.** Leave `includeDescription` off for large sweeps.
- **Inventory is country-specific.** A search on `vinted.fr` will not return UK stock — run one job per marketplace.
- **Datacenter IPs are refused.** This is an IP-reputation gate, not a fingerprint problem — no TLS profile clears it, so a residential proxy is mandatory on the platform.
- **Sold listings are not searchable.** The catalogue exposes active listings only, so this measures asking prices, not realised sale prices.

### Scope & Compliance

- **Public listings only.** The actor reads the same public catalogue an anonymous visitor sees. No account, no login, no credentials.
- **Seller fields are public shop data** — the display name and public profile link shown on every listing. No emails, phone numbers or private contact details are collected.
- **No security control is defeated.** Ordinary HTTPS requests with a browser-accurate TLS fingerprint. No CAPTCHA solving, no forged authentication.
- **Rate limits are respected.** Requests are paced between pages.
- Use the output in line with Vinted's Terms of Service and applicable law.

### Related Actors

| Actor | Marketplace |
|---|---|
| [`grailed-listings`](https://apify.com/xtracto/grailed-listings) | Grailed menswear resale |
| [`poshmark-listings`](https://apify.com/xtracto/poshmark-listings) | Poshmark |
| [`stockx-search-scraper`](https://apify.com/xtracto/stockx-search-scraper) | StockX sneakers & streetwear |
| [`chrono24-market-intel`](https://apify.com/xtracto/chrono24-market-intel) | Chrono24 luxury watches |
| [`ebay-sold-comps-scraper`](https://apify.com/xtracto/ebay-sold-comps-scraper) | eBay realised sale prices |

# Actor input Schema

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

Which Vinted marketplace to search. Each country has its own inventory and currency.

## `searchText` (type: `string`):

What to search for, e.g. 'nike air max', 'levis 501', 'ralph lauren shirt'.

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

Result ordering.

## `priceFrom` (type: `integer`):

Lowest asking price to include, in the site's currency.

## `priceTo` (type: `integer`):

Highest asking price to include, in the site's currency.

## `catalogIds` (type: `array`):

Optional Vinted category IDs. Take them from the catalog\_ids parameter in a Vinted search URL.

## `brandIds` (type: `array`):

Optional Vinted brand IDs, taken from the brand\_ids parameter in a Vinted search URL.

## `statusIds` (type: `array`):

Optional Vinted condition IDs, taken from the status\_ids parameter in a Vinted search URL.

## `includeDescription` (type: `boolean`):

Also open each listing page to collect its description. Accurate but adds one request per listing, so runs take noticeably longer.

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

Maximum listings to return. A single search maxes out around 960 results on the source; use filters to slice past that.

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

Required on the Apify platform. Vinted refuses datacenter IPs, so leave this on Residential and pick the country matching your chosen site.

## Actor input object example

```json
{
  "domain": "www.vinted.co.uk",
  "searchText": "nike air max",
  "order": "newest_first",
  "includeDescription": false,
  "maxItems": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# Actor output Schema

## `title` (type: `string`):

Title of the item.

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

Brand name.

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

Size of the item.

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

Condition of the item.

## `price` (type: `string`):

Price of the item. Numeric value.

## `currency` (type: `string`):

ISO currency code of the price.

## `totalPrice` (type: `string`):

Total price including fees. Numeric value.

## `favouriteCount` (type: `string`):

Favourite Count. Whole number.

## `url` (type: `string`):

Direct link to the scraped item.

## `serviceFee` (type: `string`):

Service Fee as reported by the source.

## `isPromoted` (type: `string`):

Is Promoted. Boolean value.

## `sellerIsBusiness` (type: `string`):

Seller Is Business.

## `description` (type: `string`):

Short description or summary.

## `itemId` (type: `string`):

Item Id as reported by the source.

## `viewCount` (type: `string`):

View count. Whole number.

## `sellerId` (type: `string`):

Seller Id as reported by the source.

## `sellerLogin` (type: `string`):

Seller Login as reported by the source.

## `sellerUrl` (type: `string`):

Link to the seller profile.

## `photoUrl` (type: `string`):

Link to the photo.

## `photoCount` (type: `string`):

Photo Count. Whole number.

## `source` (type: `string`):

Name of the source the row came from.

## `_error` (type: `string`):

Set only on diagnostic rows - why that target produced no data.

## `_query` (type: `string`):

The query parameters used for this row.

## `_scrapedAt` (type: `string`):

UTC timestamp of the scrape, ISO 8601.

## `_message` (type: `string`):

Human-readable explanation of the error.

# 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 = {
    "domain": "www.vinted.co.uk",
    "searchText": "nike air max",
    "order": "newest_first",
    "includeDescription": false,
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("xtracto/vinted-listings").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 = {
    "domain": "www.vinted.co.uk",
    "searchText": "nike air max",
    "order": "newest_first",
    "includeDescription": False,
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("xtracto/vinted-listings").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 '{
  "domain": "www.vinted.co.uk",
  "searchText": "nike air max",
  "order": "newest_first",
  "includeDescription": false,
  "maxItems": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call xtracto/vinted-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xtracto/vinted-listings"
        }
    }
}

```

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/NZl4Uy6OC97cZlb7A/builds/nuTeLiLiH9hMPC4hj/openapi.json
