# Vinted Sold Listings Tracker: Sold Prices & Time to Sell (`epicscrapers/vinted-sold-listings-tracker`) Actor

Track any Vinted search on a schedule and get the listings that sold, each confirmed by Vinted's completed-sale record: last asking price, first price, brand, size, condition, seller, days on market and sale date. 26 countries, no account needed.

- **URL**: https://apify.com/epicscrapers/vinted-sold-listings-tracker.md
- **Developed by:** [Epic Scrapers](https://apify.com/epicscrapers) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 sold listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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?

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 Sold Listings Tracker: find what sells on Vinted, with price, time on market and sale confirmation

Vinted Sold Listings Tracker turns Vinted sellers and searches into a spreadsheet of listings that sold. Paste a seller's profile link, a search link or a keyword, schedule the actor, and each run reports the listings that were sold since the last run. Each row has the last asking price, brand, size, condition, seller, how many days it took to sell, and the time Vinted recorded the completed sale. It is for resellers, price researchers and anyone who wants sold prices on Vinted, not asking prices.

Vinted does not show sold items in search results. Once an item sells, it disappears. This actor watches a search over time and confirms each sale with Vinted, so you get sold listings instead of guesses.

- **Sale confirmation, not guesswork.** A listing is reported as `sold` only when Vinted confirms it: either the listing page shows it can no longer be bought (usually the same day), or Vinted has a completed-transaction record for that exact item. Listings that were deleted are not reported as sold.
- **Time on market.** `daysOnMarket`, plus `lastSeenForSaleAt` and `disappearedAt`, show how fast items sell and narrow down when.
- **Price drops included.** `firstSeenPrice` is the price when the tracker first saw the listing and `price` is the last asking price, so you see what sellers accepted.
- **Keeps its own state.** Tracking state is saved in a named key-value store, so it persists between scheduled runs. Give it a fixed **Tracker name** to edit the searches later without losing history.
- **26 Vinted countries.** Track keywords on any Vinted country site, or paste URLs with your own filters.
- **No Vinted account or proxy setup.** Export to JSON, CSV, Excel or Google Sheets.

### Best for tracking sellers

The tracker works best on **sellers**: competitors, suppliers or shops you want to learn from. A seller URL reads the seller's whole shop on every run, so every listing is tracked from the moment it appears until it sells, and no sale is missed between runs.

**Tracking a search?** Schedule it to run **very often** (every hour for busy searches). A search only returns its newest listings (up to **Listings per search**), and on a popular search new listings push older ones out of that window within hours. A listing first listed and sold between two runs, or that fell out of the window before the tracker ever saw it, is never reported. The more often the search runs, the fewer sales you miss.

**Scope:** This actor reports sales only for listings it saw before they sold. Vinted does not expose past sales for a search, so the first run saves a baseline and reports nothing. It does not scrape active listings for their own sake; for deal alerts on active listings use [Vinted Scraper](https://apify.com/epicscrapers/vinted-search-scraper).

### What can you do with Vinted Sold Listings Tracker?

| Goal                                  | How                                                                                            |
| ------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Price an item by what it sold for     | Track the brand and model, then read `price` and `totalPrice` of `sold` rows.                  |
| See how fast items sell               | Sort by `daysOnMarket`, or compare `lastSeenForSaleAt` and `disappearedAt`.                    |
| Find the real discount sellers accept | Compare `firstSeenPrice` with `price`.                                                         |
| Find what sells in a category         | Track a category URL sorted by newest, and count sold rows per `brand`, `size` or `condition`. |
| Spot top sellers                      | Use the **Sellers** view or group by `seller.login`.                                           |
| Check demand before buying stock      | Read `favouriteCount` and `viewCount` next to the sale.                                        |

### How it works

1. **First run: baseline.** The actor records every listing currently for sale in your searches. No sold listings are output yet.
2. **Every later run: detect sales.** The actor scans the sellers and searches again. For each tracked listing that is no longer in the results, it checks the seller's shop:
   - Still for sale (it only dropped out of the search window): tracking continues.
   - Reserved: tracking continues.
   - Gone: the actor looks for Vinted's completed-transaction record for that item. When it finds one, the listing is output as `sold`.
3. **No record yet: check the listing page.** Vinted records a completed transaction a few days after purchase, so for gone listings without one the actor opens the listing page. If it can no longer be bought, the listing is output as `sold` right away. If the page no longer exists, the seller deleted it. If it is back for sale, tracking continues. A listing whose seller is in holiday mode is not reported as sold, since holiday mode also blocks buying.
4. Listings that are still unconfirmed keep being checked for the **sale confirmation window** (14 days by default).

Each run's dataset contains the sales detected in that run. Views: **Sold listings**, **Pricing**, **Sale timeline** and **Sellers**.

### Quick start

1. Add one or more **Vinted URLs** (seller profiles, or search and catalog pages with your filters) and/or **keywords**.
2. Optionally set a fixed **Tracker name**.
3. Run it once to create the baseline.
4. In Apify Console, go to **Schedules** and run the actor or a saved task on a schedule, for example hourly.

Track a seller:

```json
{
    "startUrls": [{ "url": "https://www.vinted.fr/member/12345678-sellername" }],
    "trackerName": "competitor-fr",
    "maxProducts": 960
}
```

Track a search:

```json
{
    "startUrls": [{ "url": "https://www.vinted.fr/catalog?search_text=nike%20dunk&order=newest_first" }],
    "trackerName": "nike-dunk-fr",
    "maxProducts": 200
}
```

For a seller, set **Listings per search** above the number of listings in the shop. For a search, sort by newest first, use a high **Listings per search**, and run it often: the more often it runs, the fewer listings drop out of the window unseen and the more precise the sale time.

Common schedules:

| Use case                       | Frequency     | Cron expression |
| ------------------------------ | ------------- | --------------- |
| Busy search (sneakers, brands) | Every hour    | `0 * * * *`     |
| Niche search                   | Every 6 hours | `0 */6 * * *`   |
| Seller shop                    | Daily         | `0 8 * * *`     |

### Input reference

Supply at least one URL or one keyword.

| Field                    | Type             | Default | Effect                                                                                                               |
| ------------------------ | ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `startUrls`              | Array of objects | Empty   | Vinted seller (`/member/…`) URLs, or search and catalog URLs used as provided with their own filters.                |
| `keywords`               | Array of strings | Empty   | Each keyword is a separate search, newest first, on the selected country site.                                       |
| `country`                | String           | `"it"`  | Vinted site for keyword searches. Doesn't change URLs.                                                               |
| `minPrice` / `maxPrice`  | Number           | Empty   | Price range for keyword searches, in the country's currency.                                                         |
| `maxProducts`            | Integer          | `200`   | Listings read from each seller or search per run, from 1 to 960.                                                     |
| `trackerName`            | String           | Empty   | Name of the saved state. Empty means it is derived from the searches, so changing the searches starts a new tracker. |
| `confirmationWindowDays` | Integer          | `14`    | How long a disappeared listing is checked for a completed sale (1 to 60).                                            |
| `includeDisappeared`     | Boolean          | `false` | Also output listings that vanished without a confirmed sale (`status` is `disappeared`).                             |
| `maxTrackingDays`        | Integer          | `60`    | Stop tracking a listing this many days after it was first seen (1 to 365).                                           |
| `maxTrackedItems`        | Integer          | `10000` | Maximum listings kept in the tracker, 100 to 20,000. The least recently active are dropped first.                    |
| `maxSellerChecks`        | Integer          | `300`   | Maximum sellers checked per run, 1 to 5,000. Sellers waiting longest go first; the rest are checked on the next run. |

Country codes are the same as in [Vinted Scraper](https://apify.com/epicscrapers/vinted-search-scraper): `at`, `be`, `hr`, `cz`, `dk`, `ee`, `fi`, `fr`, `de`, `gr`, `hu`, `ie`, `it`, `lv`, `lt`, `lu`, `nl`, `pl`, `pt`, `ro`, `sk`, `si`, `es`, `se`, `gb`, `us`.

### Output

Each run's default dataset contains the sales detected during that run. This example is illustrative, not a live listing:

```json
{
    "status": "sold",
    "id": "10027204892",
    "title": "Nike Dunk Low Panda",
    "url": "https://www.vinted.fr/items/10027204892",
    "price": 65,
    "firstSeenPrice": 75,
    "totalPrice": 69.95,
    "currency": "EUR",
    "brand": "Nike",
    "size": "42",
    "condition": "Très bon état",
    "photo": "https://images1.vinted.net/...",
    "seller": { "id": 3152018056, "login": "seller", "business": false },
    "favouriteCount": 12,
    "viewCount": 140,
    "search": "“nike dunk” on vinted.fr",
    "domain": "https://www.vinted.fr",
    "firstSeenAt": "2026-09-20T10:00:00.000Z",
    "lastSeenForSaleAt": "2026-09-26T09:00:00.000Z",
    "disappearedAt": "2026-09-26T10:00:00.000Z",
    "saleConfirmedAt": "2026-09-29T19:45:39+02:00",
    "saleConfirmedBy": "feedback",
    "daysOnMarket": 6,
    "detectedAt": "2026-09-29T20:00:00.000Z"
}
```

#### Notes on fields

- `status` is `sold`, or `disappeared` when `includeDisappeared` is on.
- The sale happened between `lastSeenForSaleAt` and `disappearedAt`. `saleConfirmedBy` is `feedback` when Vinted's completed-transaction record confirmed it (`saleConfirmedAt` is then when Vinted recorded it), or `item_page` when the listing page showed it can no longer be bought (`saleConfirmedAt` is `null`). Both are `null` for `disappeared` rows.
- `price` is the last seen asking price, which is not necessarily the amount paid if the buyer used an offer. `totalPrice` is the price with Vinted's buyer fee. `firstSeenPrice` shows price drops.
- `daysOnMarket` counts from when the tracker first saw the listing. For listings that were already online during the first run, it is a lower bound.
- `condition` is in the language of the Vinted site. `id` is a string.
- `search` and `domain` show which search and Vinted site the listing came from.

The `OUTPUT` record in the run's key-value store has a run summary: `newListings`, `relistedListings`, `soldDetected`, `disappearedWithoutSale`, `awaitingSaleConfirmation`, `trackedListings`, `sellersChecked`, `sellersFailed`, `sellersDeferred` (left for the next run when the run neared its timeout), `itemPagesChecked`, `soldConfirmedByItemPage` and the name of the state store.

### Run the tracker on a schedule

The tracker finds sales by comparing each run with the previous one, so it only works when it runs repeatedly. Apify can run it on a schedule and send the results wherever you need them.

#### 1. Save your input as a task

Open the actor, set your searches and options, then click **Save as a new task**. A task is a saved input you can run again with one click or on a schedule. Keep using the same task so it keeps the same tracked-listings state.

#### 2. Schedule the task

In Apify Console, go to **Schedules**, click **Create new**, choose how often to run (for example daily at 06:00 in your time zone), and add your task. See [Schedules](https://docs.apify.com/platform/schedules) and [How to create a schedule](https://help.apify.com/en/articles/7120817-how-to-create-a-schedule).

Watch how to schedule an Actor:

https://www.youtube.com/watch?v=1jI7WcVQmwM

Or schedule a saved task:

https://www.youtube.com/watch?v=GRFW_Loo2dk

Common schedules:

| Use case                         | Frequency       | Cron expression |
| -------------------------------- | --------------- | --------------- |
| Busy search (sneakers, consoles) | Every hour      | `0 * * * *`     |
| Niche search                     | Every 6 hours   | `0 */6 * * *`   |
| Seller shop                      | Daily           | `0 6 * * *`     |
| Slow seller (furniture, vintage) | Weekly (Monday) | `0 6 * * 1`     |

#### 3. Send the results to a spreadsheet

Connect Google in the task's **Integrations** tab to save every run to Google Sheets or Google Drive automatically:

https://www.youtube.com/watch?v=IFTeKdj6ZGM

#### 4. Compare runs

Every row has `id` and `detectedAt`, so runs are easy to join:

- **Sell-through speed:** `daysOnMarket` per `brand` or `search`.
- **Real prices:** `price`, `totalPrice` and `firstSeenPrice` per `id`, to see how much sellers drop before a sale.
- **Demand signals:** `favouriteCount` and `viewCount` on sold items.
- **Confirmed sales:** rows with `saleConfirmedAt` set, against `disappeared` rows when `includeDisappeared` is on.
- **Top sellers:** count of sold rows per `seller.id`.

### FAQ

#### Why did my first run return nothing?

The first run only records what is for sale now. Sold listings appear from the second run on.

#### Why are some sold items missing?

The actor reports sales only for listings it saw before they sold. A listing that sells and vanishes between two runs is still caught, but one that was never inside the **Listings per search** window of any run is not. This only affects searches: track sellers instead, or run the search more often, raise `maxProducts`, or narrow the search so it fits in the window.

#### Why do some disappeared listings never show as sold?

A sale is confirmed when the transaction completes. If the order is cancelled, never completed, or the seller deleted the listing, there is no completed-transaction record. Turn on `includeDisappeared` to see those rows with `status` `disappeared`.

#### Why does a sale show up days after the listing vanished?

Most sales are confirmed the same day from the listing page. When the page can't be loaded, or the seller is in holiday mode, the actor waits for Vinted's completed-transaction record, which comes a few days after purchase. Gone listings are checked until the confirmation window ends.

#### Does it log in to Vinted?

No. The actor uses Vinted's public JSON endpoints and public listing pages with anonymous cookies, through a residential connection in the country of the Vinted site.

#### Can I run several trackers?

Yes. Use a different **Tracker name** for each. Runs with the same name continue the same tracker.

#### Is it legal?

The actor collects publicly visible listing and feedback data. You are responsible for how you use it, including Vinted's terms and laws such as GDPR.

### Related Actors

- [Vinted Scraper](https://apify.com/epicscrapers/vinted-search-scraper): active listings, cross-country prices, new listing and price drop alerts, and optional item details.
- [Vinted Books Scraper](https://apify.com/epicscrapers/vinted-books-scraper): Vinted book listings with ISBN, author, title and language.
- [eBay Sold Listings API](https://apify.com/epicscrapers/ebay-sold-listings-api): sold prices on eBay, to compare with Vinted.

### Cost

This actor uses pay-per-event pricing, with no subscription. Prices depend on your Apify plan:

| Event          | Free plan | Bronze   | Silver   | Gold and above | Charged when                                                                |
| -------------- | --------- | -------- | -------- | -------------- | --------------------------------------------------------------------------- |
| Actor start    | $0.00005  | $0.00005 | $0.00005 | $0.00005       | Once per run.                                                               |
| Tracked search | $0.02     | $0.018   | $0.016   | $0.015         | Once per URL or keyword per run, including the first (baseline) run.        |
| Result         | $0.01     | $0.008   | $0.007   | $0.006         | A sold listing (or, with `includeDisappeared`, a disappeared one) is saved. |

Examples on the Free plan: one search checked hourly costs about $0.48 a day plus $0.01 per sale found; one search checked daily costs $0.02 a day plus $0.01 per sale. Set a maximum cost per run; the actor skips the remaining searches when it's reached. The **Pricing** tab always shows the current prices for your plan.

### Support

Report problems in the **Issues** tab. Include the run ID, the input and what you expected.

This actor is not affiliated with or endorsed by Vinted. "Vinted" is a trademark of Vinted UAB.

# Actor input Schema

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

Vinted seller URLs (https://www.vinted.fr/member/12345678-name) and search or catalog URLs to track. Country and price options from the keyword section do not apply to these URLs.

## `keywords` (type: `array`):

Enter one or more keywords. Each keyword is tracked as a separate Vinted search, sorted by newest first.

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

Select the Vinted country site used for keyword searches.

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

Enter the lowest listing price in the selected country's currency. Leave empty for no minimum.

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

Enter the highest listing price in the selected country's currency. Leave empty for no maximum.

## `maxProducts` (type: `integer`):

Maximum listings read from each URL or keyword on every run. For a seller URL, set it above the number of listings in the shop. Listings that later drop out of this window are still checked, so a smaller value mostly reduces how many new listings are picked up per run.

## `trackerName` (type: `string`):

Name of the saved tracking state. Runs with the same name continue the same tracker. Leave empty to derive the name from your searches; changing the searches then starts a new tracker. Use a fixed name if you want to edit the searches later and keep the history.

## `confirmationWindowDays` (type: `integer`):

How long to keep checking a listing that disappeared for a confirmed sale. Vinted confirms a sale when the transaction completes, which is usually a few days after purchase.

## `includeDisappeared` (type: `boolean`):

Also output listings that disappeared but were never confirmed as sold within the confirmation window. These are usually deleted listings, but can include sales that Vinted did not confirm.

## `maxTrackingDays` (type: `integer`):

Stop tracking a listing this many days after it was first seen.

## `maxTrackedItems` (type: `integer`):

Upper limit of listings kept in the tracker. The least recently active listings are dropped first.

## `maxSellerChecks` (type: `integer`):

Each missing listing is checked against its seller's shop. Sellers waiting longest are checked first; the rest are checked on the next run.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.vinted.fr/catalog?search_text=nike%20dunk&order=newest_first"
    }
  ],
  "country": "it",
  "maxProducts": 200,
  "confirmationWindowDays": 14,
  "includeDisappeared": false,
  "maxTrackingDays": 60,
  "maxTrackedItems": 10000,
  "maxSellerChecks": 300
}
```

# Actor output Schema

## `soldListings` (type: `string`):

No description

## `summary` (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 = {
    "startUrls": [
        {
            "url": "https://www.vinted.fr/catalog?search_text=nike%20dunk&order=newest_first"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("epicscrapers/vinted-sold-listings-tracker").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 = { "startUrls": [{ "url": "https://www.vinted.fr/catalog?search_text=nike%20dunk&order=newest_first" }] }

# Run the Actor and wait for it to finish
run = client.actor("epicscrapers/vinted-sold-listings-tracker").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 '{
  "startUrls": [
    {
      "url": "https://www.vinted.fr/catalog?search_text=nike%20dunk&order=newest_first"
    }
  ]
}' |
apify call epicscrapers/vinted-sold-listings-tracker --silent --output-dataset

```

## MCP server setup

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

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/GrbdhZFnqgsPjKTq9/builds/ekKY3wznWnUkhQcwE/openapi.json
