# Vinted Scraper - Listings, Prices, Sizes & Brands in 9 Markets (`s-r/vinted-scraper`) Actor

Export Vinted search and catalog results to a dataset: title, brand, size, condition, asking price, the total price with buyer protection, photo and link. Nine country markets, up to 1440 listings per run. Built for resellers, price research and second-hand market analysis.

- **URL**: https://apify.com/s-r/vinted-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** E-commerce, Business
- **Features:** Limited permissions
- **Stats:** 7 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 run start fees

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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: Export Vinted Listings, Prices and Brands

This Vinted scraper turns Vinted search and catalog results into a clean dataset for resellers, price researchers and anyone tracking the second-hand fashion market. It searches nine Vinted country markets, accepts catalog links from additional Vinted countries, and returns item titles, brands, sizes, conditions, prices, photos, listing links and visible favourite counts.

Use a search term to explore current listings, or paste a catalog URL after selecting filters on Vinted. The output keeps the original item identifiers and market labels, so repeated exports can be joined by `item_id`. Listings can disappear, sell or move between pages while a search runs; this actor returns what the catalog shows during the run.

### What the Vinted scraper returns

Every row is one listing as a buyer sees it in the catalog: the seller's title, the brand, the size, the condition, the asking price and, unlike a plain price export, the price a buyer actually pays including buyer protection. You also get the item link, the primary photo, how many members favourited it, the market it came from and when it was collected. Up to 96 listings arrive per catalog page and up to 1440 per run. There is no browser to install and no Vinted account or login is needed.

Supported markets: the Netherlands (`nl`), Belgium (`be`), Germany (`de`), France (`fr`), Spain (`es`), Italy (`it`), Poland (`pl`), the United Kingdom (`co.uk`) and the United States (`com`).

### Vinted Scraper input

Provide `query`, `url`, or both. A search term such as `jas` searches the selected market. Choose a term in that market's language for useful results. If both fields are present, the catalog URL controls the search and `query` is retained as an output label. Neither field has a default that silently starts an unrelated search.

`market` defaults to `nl`. Supported values are `nl`, `be`, `de`, `fr`, `es`, `it`, `pl`, `co.uk` and `com`. These correspond to the Netherlands, Belgium, Germany, France, Spain, Italy, Poland, the United Kingdom and the United States. Field labels and condition names follow the catalog's language. A pasted URL from another supported market uses that site's labels; the `market` field still preserves the value supplied in your input, and `country` identifies the catalog actually read.

Catalog URLs from other Vinted countries, including Austria (`vinted.at`), Ireland (`vinted.ie`) and Sweden (`vinted.se`), also work. For these links, `country` follows your selected `market`. Choose a listed market with matching field labels when possible; brand, size and condition may be null when the catalog uses different labels. Item links keep the country host from your catalog URL.

`sort` defaults to `relevance`. Set it to `newest`, `price_asc` or `price_desc` to use Vinted's ordering. `price_min` and `price_max` are optional non-negative integer price bounds in the catalog's currency. Zero leaves that bound unset. Existing filters in a pasted URL remain available.

`limit` defaults to 96 and accepts values from 1 to 1440. This is the maximum number of unique listings to return, rather than a guarantee about availability. Each catalog page normally contains 96 cards, but the site's available pages, repeated cards and changing listings can produce fewer results. `retries` defaults to 4 and accepts 2 to 8 attempts per page, subject to the run's request budget.

A minimal input used in an actual recorded run is:

```json
{"query":"jas","limit":96,"retries":4}
```

For a category, paste a real Vinted catalog URL in `url` and choose the corresponding market. Category, brand and size filters already present in that URL are retained. The actor reads catalog cards; it does not open every item's detail page or collect private account information.

An input with every option, also from a recorded run:

```json
{"query":"nike air max","market":"de","sort":"price_asc","price_min":20,"price_max":60,"limit":150,"retries":6}
```

### Output and dataset fields

Each dataset row represents one unique listing. `item_id` is Vinted's item identifier, `url` is its item link, and `position` is the one-based position after removing duplicate identifiers across pages. The title comes from the seller's text, while `brand`, `condition` and `size` come from the catalog's localized labels.

`price` is the asking price as a JSON number. `price_with_protection` is the displayed price including buyer protection. Shipping is excluded. `currency` preserves the displayed symbol, such as € or £; `currency_code` supplies EUR, GBP, USD or PLN when a price is available. Do not add asking price and protected price together: the protected price already includes the asking price.

`image` is the primary catalog image URL and `image_url` repeats it for integrations using that field name. `favourites` contains the visible favourite count, or null when the card shows no numeric count. A missing count should not be interpreted as zero. `summary_raw` preserves the original decoded card summary so you can inspect the source text alongside the parsed fields.

`market` and `query` preserve your input labels. `source` identifies this scraper, `listing_id` repeats the stable item identifier, `country` gives the two-letter catalog country for the nine listed markets (or your selected market for other catalog hosts), and `fetched_at` records when the result was collected in UTC. Missing optional values remain null. Numeric prices remain numbers even when the amount is a whole number.

The default key-value store also contains `summary`, including returned items, pages requested and served, counts with price, brand and size, and fetch duration. When individual pages fail, successful listings remain available and the `errors` record explains the failures. The run output reports partial delivery and warnings where relevant. Check those records when completeness matters to your workflow.

#### Example output row

A real row from a run with `{"query":"jeans","market":"com","limit":10}`:

```json
{
  "item_id": "10172865687",
  "url": "https://www.vinted.com/items/10172865687-wrangler-flare-jeans",
  "price": 25,
  "currency": "$",
  "price_with_protection": 26.95,
  "title": "Wrangler flare jeans",
  "brand": "Wrangler",
  "condition": "New with tags",
  "size": "Other",
  "image": "https://images1.vinted.net/t/01_01fbc_H2n5i8Z7qKk4W6GEgi1znbC8/310x430/c3827df0.webp?s=a110cb063f88e4b319b9774ec3d695027933e93f",
  "favourites": 13,
  "summary_raw": "Wrangler flare jeans, Brand: Wrangler, Condition: New with tags, Size: Other, 25.00 $, 26.95 $",
  "market": "com",
  "query": "jeans",
  "position": 1,
  "source": "vinted-scraper",
  "fetched_at": "2026-10-02T06:52:12.070Z",
  "listing_id": "10172865687",
  "country": "US",
  "currency_code": "USD",
  "image_url": "https://images1.vinted.net/t/01_01fbc_H2n5i8Z7qKk4W6GEgi1znbC8/310x430/c3827df0.webp?s=a110cb063f88e4b319b9774ec3d695027933e93f"
}
```

You can download the dataset as JSON, CSV, Excel or XML, or read it through the Apify API from your own code, a spreadsheet or an automation tool.

### Use cases for a Vinted scraper

- **Reselling and sourcing.** Find underpriced items by brand, size and condition, sorted by newest or by price, and act before someone else does.
- **Price research.** Compare asking prices for the same brand or category across countries. Because `price_with_protection` is included, you compare what buyers really pay, not just the sticker price.
- **Market and trend analysis.** Track how many listings a brand has, which sizes dominate and how prices move over time by running the same search on a schedule and joining on `item_id`.
- **Valuation and price guides.** Build your own Vinted price guide for a category before listing your own items.
- **Brand monitoring.** Watch how a brand's items are resold second-hand, including condition and favourite counts as a demand signal.

### How this Vinted scraper compares

Copying listings by hand works for a handful of items but not for hundreds across several countries. Open-source Vinted libraries exist, but you run, host and maintain them yourself, and they break when the site changes. Vinted's own Pro integrations are intended for professional sellers managing their own items, not for searching the public catalog. This actor runs on Apify with nothing to install: you give it a search or a catalog URL and get a structured dataset, with scheduling, webhooks and API access included. Compared with other Vinted scrapers in the Store, it adds the buyer-protection price, a normalized `currency_code`, the raw card summary for auditing, and a per-run summary of what was returned.

### Pricing

Pricing remains $0.0005 for the `run_start` event and $0.0015 for each delivered `listing` event. The start fee is charged once per run, including empty runs. Listings are charged only after delivery to your dataset; a run returning no listings has no listing charge. The actor does not charge separate events for image links, favourite counts or the protected price.

Users without a paid Apify plan receive at most 10 listings per run. Only those delivered listings are counted for the listing event. Paid users can request the configured limit. This cap concerns the delivered results, so splitting a broad collection into several runs also incurs a start fee for each run.

### Limitations and empty results

Vinted's catalog changes continuously. A limit of 1440 cannot create additional pages when the site exposes fewer. Repeated promoted cards are removed by item identifier, which can reduce the final count further. Searching an unusual phrase may still return fuzzy matches; an unrelated-looking phrase is not proof of an empty catalog.

An empty catalog completes successfully with zero dataset rows. Invalid input, an expired catalog URL or an unavailable upstream can also complete with an empty result and an explanatory error. A partial run keeps the rows already fetched and exposes warnings. Use a lower limit when a large request repeatedly ends with partial delivery.

### FAQ

#### Can I search without a catalog URL?

Yes. Supply `query` and optionally `market`, sorting and price filters. The default market is the Netherlands.

#### Can I paste the URL from my browser?

Yes. Use a Vinted catalog URL, including links from countries beyond the nine market selections. HTTP links are upgraded to HTTPS. Its existing filters are retained, and it takes precedence over a query for fetching.

#### Why are fewer listings returned than my limit?

The limit is a ceiling. Available pages, duplicate cards, removed items and a partially completed request can reduce the final dataset. Consult `summary` and warnings for the run's actual delivery.

#### Does the protected price include shipping?

No. `price_with_protection` includes the catalog's buyer protection amount, while shipping is a separate cost outside these cards.

#### Are empty runs charged for listings?

No. An empty run only incurs the existing $0.0005 start fee. There are no listing charges without delivered dataset rows.

#### Is there an official Vinted API for searching listings?

Not for the public catalog. Vinted offers integrations for professional sellers to manage their own items. This Vinted scraper reads the same public search and catalog pages any visitor sees and returns them as structured data.

#### Can I run the Vinted scraper on a schedule?

Yes. Use an Apify schedule to run the same input every hour or every day, then join the datasets on `item_id` to see new listings, price drops and items that sold or disappeared.

#### Is it legal to scrape Vinted?

The actor only collects publicly visible listing data and no personal account information. You are responsible for how you use the data, including compliance with privacy law and Vinted's terms where they apply to you.

# Actor input Schema

## `query` (type: `string`):

What to search for. Use the market's own language for the best results.

## `market` (type: `string`):

Which Vinted country site to read; field labels are localized for that market.

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

A Vinted catalog URL to read instead of a search term. Paste it from your browser after applying filters.

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

Vinted's own ordering.

## `price_min` (type: `integer`):

Lower price bound in the market's currency.

## `price_max` (type: `integer`):

Upper price bound in the market's currency.

## `limit` (type: `integer`):

Maximum listings (default 96). Values are clamped to 1–1440; 0 uses the default. Availability and pagination can return fewer.

## `retries` (type: `integer`):

Attempts per page, 2 to 8 (default 4), bounded by the shared request budget.

## Actor input object example

```json
{
  "query": "jas",
  "market": "nl",
  "url": "https://www.vinted.nl/catalog?catalog[]=1904",
  "sort": "relevance",
  "limit": 96,
  "retries": 4
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Vinted listing.

## `summary` (type: `string`):

Market, pages served, and how many rows carried a price, a brand and a size.

## `errors` (type: `string`):

Per-page failures with a code and a redacted message.

# 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 = {
    "query": "jas",
    "limit": 96,
    "retries": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/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 = {
    "query": "jas",
    "limit": 96,
    "retries": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/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 '{
  "query": "jas",
  "limit": 96,
  "retries": 4
}' |
apify call s-r/vinted-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/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/NtK7vO8J51udfDbuo/builds/TJ1tNHGPJr89Tma9t/openapi.json
