# Vinted Scraper — Listings, Prices & Sellers (All Countries) (`tortuga/vinted-scraper`) Actor

Returns Vinted listings from any country (vinted.fr, .de, .co.uk, .it, .es, .pl...): title, price and total incl. buyer fee, brand, size, condition, photos, likes, seller and rating. Search by keyword or catalog URL with filters, or a seller's items; optional description, category, color, material.

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

## Pricing

from $1.80 / 1,000 listing scrapeds

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/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

## Vinted Scraper — Listings, Prices & Sellers (All Countries)

Scrape Vinted listings from every Vinted country site (vinted.fr, vinted.de, vinted.co.uk, vinted.it, vinted.es, vinted.nl, vinted.pl, vinted.be, vinted.at, vinted.cz, vinted.lt, vinted.pt and 15 more) into a clean dataset: title, price and currency, total price including Vinted's buyer protection fee, brand, size, condition, favourites count, promoted flag, photo, and the seller's username, id and profile link. Search by keyword with Vinted's own filters (category, brand, size, condition, color, material, price range, sort), paste any Vinted catalog URL you set up in the browser, or list everything a seller has for sale. Turn on item details for the full description, category path, color, material, upload time, all photos, shipping price and the seller's rating, review count and location.

No login and no browser: the Actor reads the same JSON the Vinted website loads, 96 listings per request. Download the results as JSON, CSV or Excel, or pull them through the API into your reselling, price-tracking or alerting pipeline. You pay per listing you get.

### What data does Vinted Scraper extract?

Every listing from a search or catalog URL gives you:

| Field | Description |
|---|---|
| `id`, `url` | Vinted item id and the item URL on the country site you searched |
| `title` | Listing title |
| `price`, `currency` | Item price in the site's currency (EUR, GBP, PLN, CZK, SEK, ...) |
| `serviceFee`, `totalPrice` | Buyer protection fee and the total the buyer pays before shipping, as Vinted shows it |
| `brand` | Brand name (`null` when the seller picked no brand) |
| `size` | Size as shown, e.g. `"M"`, `"42"`, `"W32"`, `"10 ans / 140 cm"` |
| `condition` | Condition as shown on that site, e.g. `"New with tags"`, `"Très bon état"`, `"Sehr gut"` |
| `likes` | How many members added the listing to their favourites |
| `isPromoted` | `true` for a paid "bumped" listing |
| `thumbnail`, `photos` | Main photo (thumbnail and full size; all photos with details on) |
| `sellerId`, `sellerName`, `sellerUrl`, `sellerIsBusiness` | Seller's public member id, username, profile link and Pro (business) flag |
| `domain`, `country` | Vinted site the listing came from, e.g. `vinted.de`, `DE` |
| `searchQuery`, `searchUrl`, `scrapedAt`, `detailsFetched` | The search the listing came from and when |

With **Include seller stats** on (and always with item details or seller runs), each listing also gets the seller's public profile: `sellerRating` (0-5 stars), `sellerRatingCount` (reviews), `sellerCountry`, `sellerCity` and `sellerLocation` (when the seller shows them), `sellerItemCount`, `sellerFollowers` and `sellerLastSeen`.

With **Include item details** on, each listing also gets:

| Field | Description |
|---|---|
| `description` | Full description text |
| `categoryId`, `categoryPath` | e.g. `1819`, `"Herren > Kleidung > Jeans > Gerade geschnittene Jeans"` |
| `color`, `material`, `brandId` | As the seller entered them |
| `attributes` | Every detail row as shown on the item page, e.g. `{"Brand": "Levi's", "Size": "W34", "Material": "Cotton, Elastane", "Uploaded": "a day ago"}` |
| `uploadedText` | When the listing was uploaded, as Vinted shows it ("2 hours ago", "Il y a 5 minutes") |
| `photos`, `photoCount` | All photos |
| `shippingPrice`, `shippingCurrency`, `shippingType`, `multipleShippingOptions`, `pickUpOnly` | The "shipping from" price Vinted shows on the item page |
| `isReserved`, `isSold` | Reserved / sold flags |
| `originalPrice`, `originalCurrency` | The seller's own price when the listing comes from another country (e.g. 50 AUD shown as 26.70 GBP) |
| `sellerBadges` | e.g. `["ACTIVE_LISTER", "SPEEDY_SHIPPING"]` |

Seller runs (member ids or profile URLs) return every item the seller has for sale with brand, size, condition, all photos, `isReserved` and `createdAt` (upload time of the listing's photos), plus the seller's public stats on every row.

### How to scrape Vinted listings

1. Pick the **Country (Vinted site)**, type one or more **Search terms** and set any filters (price range, condition, category, brand, size, color or material ids) and **Sort**.
2. Or open Vinted in your browser, search and filter there, and paste the URL from the address bar into **Start URLs**. Catalog URLs from every Vinted country work, with all their filters (`catalog[]`, `brand_ids[]`, `size_ids[]`, `status_ids[]`, `color_ids[]`, `material_ids[]`, `price_from`, `price_to`, `order`).
3. To get all items of a seller, add the member id or profile URL (`https://www.vinted.fr/member/3170877842-siramodas`) to **Sellers**. Single item URLs (`https://www.vinted.co.uk/items/10325777819-vintage-levis-jeans`) are returned with full details.
4. Set **Max items** and click **Start**. Download the results as JSON, CSV, Excel or HTML, or read them through the API.

### Input example

```json
{
  "searchQueries": ["levis 501", "carhartt jacket"],
  "country": "uk",
  "sort": "newest_first",
  "priceFrom": 10,
  "priceTo": 60,
  "conditions": ["new_with_tags", "very_good"],
  "startUrls": [{ "url": "https://www.vinted.fr/catalog?search_text=nike&brand_ids[]=53&size_ids[]=207&order=newest_first" }],
  "sellers": ["https://www.vinted.de/member/58026434-johnnyswardrobe"],
  "maxItems": 500,
  "maxItemsPerSearch": 100,
  "includeDetails": false,
  "includeSellerDetails": true
}
```

### Output example

A listing from a vinted.de search with **Include item details** on (photo list shortened):

```json
{
  "id": "10351353706",
  "url": "https://www.vinted.de/items/10351353706-levis-501-vintage-jeans-denim-hose-schwarz-black-w36-l34-baggy",
  "title": "Levi's 501 Vintage Jeans Denim Hose Schwarz Black W36 L34 Baggy",
  "price": 28,
  "currency": "EUR",
  "serviceFee": 2.1,
  "totalPrice": 30.1,
  "brand": "Levi's",
  "brandId": "10",
  "size": "L",
  "condition": "Gut",
  "likes": 0,
  "isPromoted": false,
  "isReserved": false,
  "isSold": false,
  "thumbnail": "https://images1.vinted.net/t/02_001f9_PuF94d8XgqfJcTPXVffVLHvx/310x430/34d9e5cd.webp?s=6e122d24585c52d787b7ce365f8da320c5dd34e0",
  "photos": ["https://images1.vinted.net/t/02_001f9_PuF94d8XgqfJcTPXVffVLHvx/f800/34d9e5cd.webp?s=da0ef52bd550e3ff0acdc2bc26d8cb782bd98487"],
  "photoCount": 11,
  "sellerId": "58026434",
  "sellerName": "johnnyswardrobe",
  "sellerUrl": "https://www.vinted.de/member/58026434-johnnyswardrobe",
  "sellerIsBusiness": false,
  "sellerRating": 5,
  "sellerRatingCount": 424,
  "sellerCountry": "Deutschland",
  "sellerCity": "Münster",
  "sellerLocation": "Münster, Deutschland",
  "sellerLastSeen": "2026-10-12T17:54:25+02:00",
  "sellerItemCount": 107,
  "sellerFollowers": 962,
  "description": "Ein paar Informationen zum Artikel: Marke: Levi's 501, Material: 100% Baumwolle ...",
  "categoryId": "1819",
  "categoryPath": "Herren > Kleidung > Jeans > Gerade geschnittene Jeans > Levi's Gerade geschnittene Jeans",
  "color": "Schwarz",
  "material": null,
  "attributes": { "Marke": "Levi's", "Größe": "L", "Zustand": "Gut", "Farbe": "Schwarz", "Hochgeladen": "1 Min." },
  "uploadedText": "1 Min.",
  "shippingPrice": 0,
  "shippingCurrency": "EUR",
  "shippingType": "all",
  "domain": "vinted.de",
  "country": "DE",
  "searchQuery": "levis 501",
  "searchUrl": null,
  "detailsFetched": true,
  "scrapedAt": "2026-10-12T16:37:05Z",
  "sellerBadges": ["ACTIVE_LISTER"]
}
```

### Monitor changes on a schedule

Turn on **Only new or changed items** and save the input as a task with a Schedule (for example every 15 minutes or every hour). The Actor remembers what earlier runs of the same search returned and outputs only new listings and listings whose price changed, so you see fresh Vinted deals and price drops without the listings you already know. Unchanged listings are not output and not charged, so a quiet run costs next to nothing. Each output item has `changeType` (`new` or `changed`) and, for price changes, `previousValues` with the old price. Use **Sort: Newest first** and set **Max items** to how many of the newest listings to check per run; **Monitoring key** keeps several watches on the same search apart. Connect the dataset to Slack, Telegram, email or a webhook through Apify integrations to get an alert for every new listing.

### Which Vinted countries are supported?

All of them: France, Germany, United Kingdom, Italy, Spain, Netherlands, Poland, Belgium, Austria, Czechia, Lithuania, Portugal, Slovakia, Sweden, Romania, Hungary, Denmark, Finland, Ireland, Greece, Croatia, Luxembourg, Estonia, Latvia, Slovenia, the US site (vinted.com) and Australia (vinted.com.au). Pick the country for search terms, or paste URLs from any Vinted domain; one run can mix countries. Prices, sizes and condition names come exactly as that site shows them, in its currency and language. Vinted shows listings from sellers in other countries converted to the site's currency; the item details add the seller's own price.

### How many results can I get per search?

Vinted serves at most 960 listings per search (10 pages of 96), even when it says more match. To get more, split a search by price range, brand, size, category or condition, or add several searches; **Max items per search** caps each one so a busy keyword does not use up the run. Seller runs have no such limit.

### Does it work without login?

Yes. The Actor sees exactly what an anonymous visitor sees and needs no Vinted account, cookies or API key. It gets Vinted's anonymous visitor session itself (one small request per country per run).

### Pricing

Pay per result, no subscription and no start fee:

- **$1.80 per 1,000 listings** (event `result`).
- **+$1.20 per 1,000 item pages** when **Include item details** is on, and for single item URLs (event `detail`).

Seller stats are free. Platform usage is small: about $0.008 per 1,000 listings on top (plus residential proxy traffic if a site falls back to it, see below). Apify's free plan is enough to try it.

### Proxy note

The default Apify Proxy (datacenter) works. Cloudflare in front of Vinted refuses some datacenter IPs; the Actor drops a refused IP and retries on a new one, and when one country site keeps refusing them it moves that site's remaining requests to Apify residential proxy in the same country automatically. Residential traffic is billed by Apify per GB: a search page of 96 listings is about 50 KB (a few cents per 10,000 listings), but an item page is about 300 KB, so turn on item details only when you need them.

### Integrations and API

Use the results in Zapier, Make, n8n or Google Sheets, or call the Actor from Python or Node.js with the Apify client. See the **API** tab for ready-made snippets.

### Is it legal to scrape Vinted?

The Actor collects only data that Vinted shows publicly to any visitor without logging in: listings, prices, photos and the public seller profile (username, rating, review count, and country or city only when the seller made them public). It never logs in and never reads messages, addresses, orders or anything behind a login. You are responsible for how you use the data and for complying with Vinted's terms and the law that applies to you (for example GDPR when you store usernames).

### Support

Found a bug or need a field or filter added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords as you would type them into the Vinted search box, one search per line, e.g. "nike air max", "levis 501", "zara dress". Searched on the Vinted site chosen in Country, with the filters below.

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

Which Vinted site the search terms and bare seller ids use. Prices come in that site's currency (EUR, GBP, PLN, CZK, ...). Start URLs always use the site of their own domain, so any other Vinted domain (vinted.lu, .hr, .ee, .lv, .si, .com.au) works there.

## `startUrls` (type: `array`):

Vinted pages from any country site: catalog/search pages with the filters you set in the browser (https://www.vinted.fr/catalog?search_text=nike\&brand_ids\[]=53\&order=newest_first), member profiles (https://www.vinted.de/member/12345678) for all items a seller has for sale, or single item pages (https://www.vinted.co.uk/items/1234567890-title), returned with full details.

## `sellers` (type: `array`):

Scrape every item a seller has for sale, with the seller's public rating, review count, country, followers and last-seen time. Member ids ("3170877842", searched on the Country site) or profile URLs (https://www.vinted.fr/member/3170877842-name).

## `sort` (type: `string`):

Order of the search results (and of seller items). Newest first is the best choice for monitoring new listings. Start URLs keep the order in their own URL.

## `priceFrom` (type: `number`):

Used with the search terms: lowest item price, in the currency of the chosen Vinted site.

## `priceTo` (type: `number`):

Used with the search terms: highest item price, in the currency of the chosen Vinted site.

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

Used with the search terms: only these conditions. Empty = all.

## `catalogIds` (type: `string`):

Used with the search terms: Vinted category ids, comma-separated, as in a Vinted URL (catalog\[]=1904 is Women, 5 is Men, 1206 is Men's shoes). With no search term, the category is browsed.

## `brandIds` (type: `string`):

Used with the search terms: Vinted brand ids, comma-separated, as in a Vinted URL (brand_ids\[]=53 is Nike, 14 is adidas). With no search term, the brand is browsed.

## `sizeIds` (type: `string`):

Used with the search terms: Vinted size ids, comma-separated, as in a Vinted URL (size_ids\[]=207 is S).

## `colorIds` (type: `string`):

Used with the search terms: Vinted color ids, comma-separated, as in a Vinted URL (color_ids\[]=1 is black).

## `materialIds` (type: `string`):

Used with the search terms: Vinted material ids, comma-separated, as in a Vinted URL (material_ids\[]=...).

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

Stop after this many listings in total (across all searches and sellers). Keeps cost predictable. Vinted serves at most 960 listings per search; split big searches by price range, brand or category to get more.

## `maxItemsPerSearch` (type: `integer`):

Optional cap for each search term, URL or seller, so one busy search does not use up Max items for the others (e.g. the 50 newest listings for each of 10 keywords). Empty = no per-search cap.

## `includeDetails` (type: `boolean`):

Also open every item page for the full description, category path, color, material, upload time, all photos and the seller's rating, review count, location and badges. One extra request per listing; charged as an extra 'detail' event (see pricing).

## `includeSellerDetails` (type: `boolean`):

Add each seller's public rating (0-5), review count, country, city (when public), followers, item count and last-seen time to every listing. One small request per distinct seller, no extra charge.

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price changed (new listings and price drops). Use with a Schedule; unchanged items are not charged. With this on, Max items is the number of listings checked per run (e.g. the newest 100).

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input

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

Apify Proxy (datacenter) is the default. Cloudflare refuses some datacenter IPs; the Actor then retries on new IPs and, if a country site keeps refusing them, switches that site to Apify residential proxy in the same country automatically (about 50 KB per 96 listings, about 300 KB per item page with details on).

## Actor input object example

```json
{
  "searchQueries": [
    "nike air max"
  ],
  "country": "fr",
  "startUrls": [],
  "sellers": [],
  "sort": "newest_first",
  "conditions": [],
  "maxItems": 100,
  "includeDetails": false,
  "includeSellerDetails": false,
  "onlyNewOrChanged": false,
  "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 = {
    "searchQueries": [
        "nike air max"
    ],
    "startUrls": [],
    "sellers": [],
    "conditions": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/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 = {
    "searchQueries": ["nike air max"],
    "startUrls": [],
    "sellers": [],
    "conditions": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/vinted-scraper").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 '{
  "searchQueries": [
    "nike air max"
  ],
  "startUrls": [],
  "sellers": [],
  "conditions": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/vinted-scraper --silent --output-dataset

```

## MCP server setup

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

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/QMOTKZaXvrGehjiIc/builds/WVI6LdgA8YSzd3xt1/openapi.json
