Vinted Scraper — Listings, Prices & Seller Data avatar

Vinted Scraper — Listings, Prices & Seller Data

Pricing

Pay per event

Go to Apify Store
Vinted Scraper — Listings, Prices & Seller Data

Vinted Scraper — Listings, Prices & Seller Data

Scrape Vinted listings, prices, sellers and reviews across 27 country markets. Goes past Vinted's hard 960-item search cap and reports exactly how complete each run was. Export to CSV, Excel, JSON or API.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Blackcube Agency AB

Blackcube Agency AB

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Scrape Vinted listings, prices, sellers and reviews across 27 country markets, and get past the hard 960-item cap that silently truncates every other Vinted tool.

Paste a Vinted URL or type a keyword. Get clean JSON, CSV or Excel — with a per-query report telling you exactly how complete the result was.

  • Past the 960-item cap — 6.4× more items than any single Vinted query can return, measured.
  • Coverage you can audit — every run says what it reached and what is genuinely unreachable.
  • condition in English on every market — Vinted returns Très bon état / Sehr gut / Bardzo dobry; a multi-market dataset is unfilterable without this, and no other Vinted tool does it.
  • Listings, sellers, closets and reviews in one actor, with the two real sale signals the API leaks.

Failed inputs are free. A row that could not be scraped is written to the dataset with a reason and is never charged. If a run returns nothing, it costs nothing.

Unofficial and not affiliated with, endorsed by, or connected to Vinted. This tool reads only publicly visible marketplace data.

How this compares

This actorTypical Vinted actor
More than 960 items from a single query
Reports how complete each query actually was
Separates "we stopped at your limit" from "Vinted cannot reach it"
Any number of markets in one run
Item condition in English on every market
Seller's completed-sales count next to their live listings
Marks Vinted's automatic review entries, so cancellations aren't read as sales
No actor-start fee — a run that returns nothing costs nothing


The 960-item cap, and why your current export is incomplete

Vinted's catalog API returns 96 items per page and stops at page 10. Page 11 answers HTTP 400. So any single Vinted search returns at most 960 items, however much stock actually matches.

Worse, the API reports total_entries: 960 for every saturated query — so a tool that trusts that number tells you it found "960 of 960" and looks complete when it is not.

We measured it. Every one of these broad queries reports exactly 960:

Querytotal_entries reported
nike960
zara960
dress960
a960

You will see it claimed that this field is simply a display constant with no meaning. It is not, and that matters: narrow queries report a true count, which is exactly what makes the cap detectable and the fix possible.

Querytotal_entries reported
supreme box logo hoodie red298
chanel haute couture vintage 19874
zxcvbnmqwerty1

Deep mode uses that: it splits a saturated query into price bands, checks each one, and keeps splitting until every band fits under the cap.

Measured on nike / vinted.fr on 2026-08-13:

Result
Distinct items collected6,125
What one Vinted query can ever return960
Multiplier6.4×
Requests used129 (0.021 per item)
Duplicates in output0

That run stopped because it hit its 6,000-item target — not because the data ran out. It had covered only €1.00–€2.20 of the price range with 11 bands still queued, so 6.4× is a floor, not a ceiling.

It tells you when it did not get everything

Every run writes a RUN_SUMMARY record with per-query coverage, and the log says so plainly:

"nike" (fr): returned 2501 items but the result set was not exhausted
- 17 price band(s) were left unwalked because maxItems was reached - raise it for more.

Three different things are reported separately, because conflating them is how tools mislead you:

  • unexploredBands — reachable; the run stopped at a budget. stopReason says which: targetItems means raise maxItems, probeBudget means narrow the query or set a price range.
  • truncatedBands — genuinely unreachable; more than 960 items share one exact price, so no price split can separate them. An honest limit, stated rather than hidden.
  • failedBands — a price range whose size could not be read because the request failed. Those items are unaccounted for, and the run says so instead of counting the band as empty.

How to scrape Vinted search results

Type keywords, pick markets, run.

{
"searchQueries": ["nike air max", "adidas samba"],
"markets": ["fr"],
"maxItems": 500
}

For a complete pull of a large query, turn on deep mode and raise the ceiling:

{
"searchQueries": ["nike"],
"markets": ["fr"],
"deep": true,
"maxItems": 20000
}

How to scrape a Vinted URL

Paste any Vinted URL — filtered catalog, item, or member page. Filters in the URL are carried over, and the country comes from the domain.

{
"startUrls": [
"https://www.vinted.fr/catalog?search_text=levis&price_to=25&brand_ids=7",
"https://www.vinted.pl/items/9651715467-nike-air-max-720",
"https://www.vinted.de/member/3175818454-someseller"
]
}

How to scrape a Vinted seller's closet and reviews

{
"startUrls": ["https://www.vinted.fr/member/3175818454-someseller"],
"includeSellerProfile": true,
"includeSellerReviews": true,
"maxReviewsPerSeller": 50
}

Returns the seller's profile, their listings, and the reviews buyers left — three row types most Vinted tools do not return at all.

The two real sale signals. Vinted has no sold-listings search, but two fields leak actual transactions:

  • soldItemCount on a seller row is their lifetime completed sales, next to itemCount (still listed). Together they are a genuine sell-through ratio.
  • Each review carries itemId and createdAt — a review only exists after a transaction on that item. Check isAutomatic first: Vinted posts system feedback for cancellations too ("Évaluation automatique : l'acheteur a annulé la transaction"), so only isAutomatic: false rows evidence a completed sale.

How to scrape Vinted item descriptions

Descriptions are not in the search response. Turn on includeItemDetail and each item gets one extra fetch:

{ "searchQueries": ["carhartt jacket"], "includeItemDetail": true, "maxItems": 50 }

Output

One row per listing. Every field is either a real value or null — never a guess.

{
"type": "listing",
"id": "9650298818",
"url": "https://www.vinted.fr/items/9650298818-nike-air-max-blanche",
"title": "Nike air max blanche",
"brand": "Nike Air",
"size": "44",
"condition": "New with tags",
"price": 64,
"currency": "EUR",
"buyerProtectionFee": 3.9,
"totalPrice": 67.9,
"favourites": 5,
"views": 0,
"photoCount": 7,
"photos": ["https://images1.vinted.net/t/05_0209f_.../f800/1786616038.jpeg"],
"listedAt": "2026-08-13T10:13:58.000Z",
"sellerId": "3168303451",
"sellerLogin": "arkalimal",
"sellerUrl": "https://www.vinted.fr/member/3168303451-arkalimal",
"sellerIsBusiness": false,
"isPromoted": false,
"market": "fr",
"description": null,
"color": null,
"scrapedAt": "2026-08-13T13:28:29.908Z"
}

Three details worth knowing:

  • condition is in English on every market. Vinted localizes it (Très bon état, Sehr gut, Bardzo dobry), which makes a multi-market dataset impossible to filter. The session requests English, so you get Very good everywhere.
  • totalPrice is what the buyer actually paysprice plus Vinted's Buyer Protection fee. Comparing raw price across listings understates the real cost.
  • listedAt is an approximate listing date. Vinted's search response has no creation timestamp at all; this is the upload time of the item's first photo, which is the closest proxy the API exposes. Accurate to the day, not the second.

Which markets exist, and the one thing nobody tells you about them

27 markets, verified live on 2026-08-13 — the domain resolved, returned HTTP 200, and yielded listings:

fr de uk us pl lt es it nl be cz sk at lu pt se dk fi ro hu gr ie hr si lv ee au

Currencies observed: EUR, GBP, USD, PLN, CZK, SEK, DKK, RON, HUF, AUD.

Not included, and why: vinted.no, vinted.ch and vinted.com.tr do not resolve; vinted.ca returns HTTP 403; vinted.bg serves the Swedish catalog in SEK (98% of its listings are identical to vinted.se, versus 0% overlap with vinted.fr), so it is not a Bulgarian market and is excluded.

Vinted is one catalog, not 27 marketplaces

This matters for your bill, so here is the measurement rather than the marketing.

ComparisonCommon item IDsSame price and currency
nl vs be9191
fr vs de6868

Identical listings, identical prices. And where the currency differs, the price is a straight conversion:

ItemSwedenDenmark
9651853828285.42 SEK193.28 DKK
9651868165181.63 SEK123.00 DKK

Median implied rate 0.6772 across 93 shared items — the actual SEK→DKK rate, with a 2.4% spread that is rounding.

Two consequences:

  1. Adding EU markets multiplies your cost far more than it adds unique listings. Scrape fr and you have most of what de, nl and be would return. We put this in the input schema too, rather than selling you a bigger number.

  2. A "cross-country price gap" computed on the same item ID is an FX artifact, not arbitrage. Any tool comparing raw numbers across markets without normalizing currency reports noise as opportunity.

    To be precise about what this does and does not say: cross-border reselling is a real business. What is not real is a same-listing price gap. Genuine dispersion is within a market (two sellers pricing the same model differently) and across platforms (Vinted versus eBay sold). Both need the full price distribution for a query — which is what deep mode exists to give you, and what a 960-item sample cannot.


What this actor does not do, and why

These are commonly advertised. We could not make them work against the public API, so we do not ship them rather than shipping something that returns nothing.

  • A searchable sold-listings feed. Vinted deletes sold listings from search and exposes no sold flag, so there is no sold-price history to scrape from the public API. We checked the endpoints this actor uses and found no sold filter that returns data. What this actor does give you is the two genuine sale signals the API leaks, both documented below rather than dressed up as a sold feed: a seller's lifetime soldItemCount, and per-review itemId + timestamp.
  • Cross-country arbitrage signals. See the measurement above: within the shared EU pool the same item is the same listing at a converted price. We return price, currency and totalPrice so you can normalize deliberately, rather than shipping a gap number that is mostly FX.
  • Item measurements and full attribute sets. Not exposed by the endpoints this actor uses.

Using it from Python

There are good open-source Vinted wrappers. They break when Vinted changes its session handling or tightens Datadome, and you maintain that yourself. If you would rather not:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("vonsensey/vinted-scraper-api").call(run_input={
"searchQueries": ["nike air max"],
"markets": ["fr"],
"deep": True,
"maxItems": 5000,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["title"], item["price"], item["currency"])

Node.js, direct HTTP, CSV/Excel download, webhooks and scheduling all work the same way — the dataset is a standard Apify dataset.


Notes on reliability

Residential proxy is required, and it is the default. Here is the measurement rather than a vague warning: Vinted is fronted by Datadome, and from an Apify datacenter IP the very first API call is answered HTTP 403 — with browser-shaped TLS and Chrome headers, not just with a plain HTTP client. The identical build through Apify Proxy RESIDENTIAL returns data on the first try.

Configuration (run on Apify, 2026-08-13)Result
Datacenter IP, plain fetchHTTP 403, 0 rows
Datacenter IP, browser TLS + Chrome headersHTTP 403, 0 rows
Apify Proxy RESIDENTIAL20 rows, first request, no retries

That is our measurement on Apify's infrastructure, and it is why the residential default is set for you — you do not need to configure anything. If you run this code somewhere else, measure it there before assuming a proxy is optional.

  • A blocked run costs you nothing. Blocked requests produce free error rows, never charges. The 403 runs above billed $0.00.
  • Blocks are detected by content, not status code. An HTTP 200 carrying a Datadome interstitial is treated as a block and the session is rebuilt, rather than being recorded as zero results.
  • Migration-safe. Apify restarts containers routinely. Delivered rows are checkpointed, so a resumed run does not re-deliver or re-charge them.

What a run costs

Pricing is per event. Rows that arrive in bulk from one request are cheap; rows that need their own request cost more.

EventWhat it isFREE tierVolume tiers down to
listingA listing row, arriving 96 per request$0.0030$0.0012
seller-reviewA review row, also arriving in bulk$0.0030$0.0012
sellerA seller profile — its own request$0.0060$0.0024
item-detailA listing upgraded with its description$0.0200$0.0140

Why item-detail is the expensive one. Vinted publishes descriptions only on the item page, never in the search API, and that page is ~350 KB over a residential proxy — roughly 70× the bandwidth of a listing row. We measured it at $5.50 per 1,000 rows to serve, against $0.071 per 1,000 for plain listings. The price reflects that honestly rather than burying it. Leave includeItemDetail off unless you need descriptions.

There is no actor-start fee, so a run that returns nothing costs nothing — that promise only works without one.

item-detail replaces the listing charge for that row, it is not added on top. You are never billed twice for one row.

Deep mode costs nothing extra. It is the product, not an upsell.

Input reference

FieldTypeDefaultWhat it does
searchQueriesarray["nike"]Keywords, run against every selected market
startUrlsarrayAny Vinted catalog, item or member URL
marketsarray["fr"]Country markets for keyword searches
maxItemsinteger100Hard ceiling on billable rows. 0 = unlimited
deepbooleanfalseSplit past the 960-item cap
priceMin / priceMaxintegerPrice filter, in the market's currency
sortByenumrelevancerelevance, newest_first, price_low_to_high, price_high_to_low
includeItemDetailbooleanfalseFetch descriptions and colour
includeSellerProfilebooleanfalseEmit seller rows for member URLs
includeSellerReviewsbooleanfalseEmit review rows for member URLs
maxReviewsPerSellerinteger25Cap on reviews per seller
maxConcurrencyinteger5Targets in flight at once
requestDelayMsinteger250Pause between requests per market

Reads only publicly visible Vinted pages — no login, no private data, no personal data behind authentication. You are responsible for how you use the output, including GDPR obligations where seller information counts as personal data. Not affiliated with Vinted.