# Vinted Scraper — Prices, Fees, Demand & Changes (`danielmachad/vinted-market-intel`) Actor

Scrape Vinted across 12 country sites: brand, size, condition, photos, favourites. Price split into asking price, buyer-protection fee and real total. Reports what changed since your last run.

- **URL**: https://apify.com/danielmachad/vinted-market-intel.md
- **Developed by:** [Daniel](https://apify.com/danielmachad) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 85.7% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 item-scrapeds

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/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 — Prices, Fees & Demand

Scrape Vinted listings across any of its twelve country marketplaces: brand, size, condition, photos, favourites, and a price broken into what the seller asks and what a buyer actually pays.

### The number most Vinted exports get wrong

Vinted adds a buyer-protection fee on top of every asking price. An export with a single `price` field is reporting the seller's number, not the buyer's — and the two are not close.

In our own test run on `vinted.co.uk`, the median asking price for "nike trainers" was **£25.00** and the median fee was **7.8% on top**. Price a listing against the asking-price column and you are consistently undercutting yourself by that margin, or misreading what your competition really costs.

This Actor returns all three: `price`, `serviceFee` and `totalPrice`, and they reconcile on every row.

### What you get

**Per item** — title, brand, size, condition, asking price, buyer-protection fee, total price, currency, favourite count, promoted flag, photo URLs, direct link.

**Market position** — each item's price percentile and distance from the median, both on the asking price and on the total, plus a market summary with median, quartiles, brand breakdown and condition breakdown.

**What changed since your last run** — price moves in currency and percent, new favourites, and a `new` / `changed` / `unchanged` status. Items that disappeared between runs are counted as `soldOrRemoved`, which for a marketplace is the closest available read on what is actually selling.

**Demand velocity** — favourites gained per day. Vinted exposes no sales data, so this is the honest proxy: how fast an item is being saved by buyers. It appears from the second run onwards.

### Sample output

```json
{
  "itemId": "9617839240",
  "title": "Air max 95s",
  "brand": "Nike",
  "size": "5",
  "condition": "Very good",
  "price": 25,
  "serviceFee": 2.05,
  "totalPrice": 27.05,
  "currency": "GBP",
  "favouriteCount": 12,
  "isPromoted": false,
  "photoCount": 4,
  "pricePercentile": 42.7,
  "priceVsMarketMedianPct": -12.5,
  "status": "changed",
  "priceChange": -2,
  "priceChangePct": -8,
  "favouriteCountChange": 14,
  "daysSincePreviousRun": 7,
  "favouriteVelocityPerDay": 2,
  "demandBasis": "run_delta",
  "market": {
    "itemCount": 96,
    "priceMedian": 25,
    "priceP25": 15,
    "priceP75": 34.99,
    "avgFavourites": 13.83,
    "soldOrRemoved": 8,
    "newListings": 11
  },
  "url": "https://www.vinted.co.uk/items/9617839240"
}
```

### Who uses this

- **Resellers** — price against the live market instead of guessing, and see which items are gaining favourites before you buy stock.
- **Brand and trend analysts** — secondhand pricing by brand, size and condition, tracked over time.
- **Developers and data teams** — a clean per-item feed with no scraping infrastructure to maintain.

### Input

| Field | Default | Notes |
|---|---|---|
| `searchText` | `nike trainers` | What you would type into Vinted's search box. |
| `domain` | `vinted.co.uk` | Twelve country marketplaces; each has its own inventory and currency. |
| `maxItems` | `96` | Caps results and cost. Ceiling is 960 per search. |
| `priceFrom` / `priceTo` | none | Optional bounds in the site's currency. |
| `brandIds` | none | Optional Vinted brand IDs, taken from the brand filter URL. |
| `order` | `relevance` | Relevance, newest, or price ascending/descending. |
| `trackChanges` | `true` | Stores a snapshot so the next run reports what moved. |

The defaults run as-is and return a usable UK market scan without editing anything.

### Pricing

Pay per event, **$1.50 per 1,000 items**. A 96-item scan costs $0.14.

Market percentiles, change tracking and demand velocity are included. You pay per item and for nothing else.

### Change tracking

Snapshots are keyed by the exact search: term, country site, brand filter and price bounds together. Run the same configuration again and you get the deltas. Change any of it and you are asking a different question, so comparison restarts.

Run it weekly against the same query and you accumulate a price and demand history for your niche instead of a series of disconnected exports.

### Limits, stated plainly

- **960 items per search, maximum.** Vinted serves 96 per page and stops paginating at 10 pages. That is its own ceiling, not one added here. To go deeper, split the search — by brand, by price band, or by a narrower term.
- **`soldOrRemoved` counts disappearance, not sales.** An item can leave the results because it sold, because the seller delisted it, or because it fell out of the ranking for your query. Treat it as a signal, not a receipt.
- **Favourite velocity needs two runs at least a day apart.** Below that a single new favourite would imply dozens per day, so the field stays null with `demandBasis: "insufficient_history"`.
- **`view_count` is not returned.** Vinted's catalog endpoint reports it as zero on every row; it only exists on the item page. A field that always reads zero is worse than an absent one.

### Data and privacy

This Actor returns **no personal data**. Seller usernames, IDs, avatars and profile links are dropped before anything is written, deliberately. What comes back describes an item for sale: brand, size, condition, price, photos and how many people saved it.

It reads Vinted's own public catalog endpoint — the same one the website's search page uses — logged out. No account, no login, no bypassed restriction.

### FAQ

**Which country should I choose?**
The one you trade in. Inventory and pricing differ substantially between marketplaces; a UK scan tells you little about the German market.

**Can I run it on a schedule?**
Yes, and it is built for it. Use Apify Schedules with the same input and each run reports what changed since the last.

**Why is `favouriteVelocityPerDay` empty?**
Either this is the first run for that search, or the previous run was under a day ago. Both are stated in `demandBasis`.

**Do I need a proxy?**
No. Proxy is optional and automatic by default. If it is unavailable the run continues rather than failing.

# Actor input Schema

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

What to search for, exactly as you would type it on Vinted — for example "nike trainers", "levis 501", "zara dress". Broad terms return more items; a specific term returns a tighter market to compare within.

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

Vinted runs a separate marketplace per country, each with its own inventory, prices and currency. Pick the one you sell or buy in.

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

Upper bound on items returned, and therefore on cost — billing is per item. Vinted serves 96 per page and stops at 10 pages, so 960 is the ceiling for a single search.

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

Optional lower bound, in the currency of the chosen country site.

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

Optional upper bound, in the currency of the chosen country site. Must be greater than or equal to the minimum.

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

Optional Vinted brand IDs to restrict the search. Find an ID in the brand filter URL on Vinted itself.

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

How Vinted should rank the results before they are collected.

## `trackChanges` (type: `boolean`):

Stores a snapshot of this exact search so a later run can report price moves, items that sold or were delisted, and how fast each item is gaining favourites. Every change field is empty on the first run for a given search — there is no history to compare against yet. Favourite velocity additionally needs the runs to be at least a day apart.

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

Optional. The automatic setting is what this Actor is tuned for. Residential proxy is deliberately ignored: Vinted does not block Apify's shared addresses, so it adds cost without improving results. Supply proxyUrls to route through your own infrastructure.

## Actor input object example

```json
{
  "searchText": "nike trainers",
  "domain": "vinted.co.uk",
  "maxItems": 96,
  "order": "relevance",
  "trackChanges": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "searchText": "nike trainers"
};

// Run the Actor and wait for it to finish
const run = await client.actor("danielmachad/vinted-market-intel").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 = { "searchText": "nike trainers" }

# Run the Actor and wait for it to finish
run = client.actor("danielmachad/vinted-market-intel").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 '{
  "searchText": "nike trainers"
}' |
apify call danielmachad/vinted-market-intel --silent --output-dataset

```

## MCP server setup

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

```

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/GVQgbd9mbrQGUDihs/builds/2b7pn5UR4cTqt3WcY/openapi.json
