Vinted Scraper - Listings, Prices, Sellers & Reviews
Pricing
from $1.20 / 1,000 results
Vinted Scraper - Listings, Prices, Sellers & Reviews
Scrape Vinted across 27 country marketplaces by keyword, filters, item or seller URL. Extract prices, currencies, brands, sizes, conditions, views, favourites, seller ratings and profiles. Supports brand, price and condition filters, plus full seller feedback history.
Pricing
from $1.20 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
7
Total users
4
Monthly active users
7 days ago
Last modified
Categories
Features
Share
Vinted Scraper: Listings, Sellers & Reviews Across 27 Markets
Vinted Scraper turns Vinted, Europe's C2C secondhand fashion marketplace, into structured listing, seller and review data across all 27 of its country marketplaces. Search by keyword with brand, price and condition filters, paste item, seller or catalogue links directly, or pull a seller's complete feedback history. Every listing carries price, currency, brand, size, condition, favourite count and photos, with full description and seller-profile depth available on request. Export to JSON, CSV or Excel, or read results straight through the API.
Why This Scraper?
- Three ways in. Keyword search with source-side brand, price and condition filters; paste any item, seller/member or catalogue link; or fetch a seller's full feedback history.
- 27 country marketplaces, one actor. Each market has its own catalogue, currency and language, and item and seller ids resolve across all of them.
- Depth on demand. Switch on full item description plus seller reputation, response time and bundle discount per run, and pay the enrichment charge only when you use it.
- Mixed-market URL runs. Paste links from several countries in one URL-mode run; each link keeps its own market instead of falling back to a single country.
- Built for schedules. Incremental mode returns only new, changed and reappeared listings on recurring runs, and, with Emit expired on, a sold or removed listing comes back marked EXPIRED once a full scan confirms it is gone.
- Loud failures, not silent empties. A run that could not read the marketplace fails with a clear message instead of returning an empty dataset that looks like "no results".
- Resume without re-billing. Continue one interrupted run from its own previous dataset without re-collecting or re-charging what it already delivered.
Use Cases
- Resale price research: track a keyword or brand across a market to benchmark asking prices, sizes and condition mix.
- Deal and restock alerts: schedule a search with incremental mode on and get notified only about new or changed listings.
- Seller due diligence: pull a seller's profile and complete feedback history before buying from or partnering with them.
- Marketplace analytics: build a dataset of brand, price and condition trends across one or several country marketplaces.
- Closet monitoring: watch one seller's whole listing catalogue for new items through URL mode.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
itemId | "0000000000" |
title | "Sample knitted winter sweater" |
brandTitle | "Sample Brand" |
priceAmount, serviceFee, totalPrice | 12.5, 1.2, 13.7 (price, buyer fee, all-in price shown on the card) |
currency, condition | "EUR", "Very good" |
brandId, categoryId, sizeId, statusId, categoryBreadcrumbs, colors, isReserved, isHidden | Ids behind brand, category, size and condition, the category path and colours as lists, and the reserved/hidden flags (item detail, when the page provides them) |
conditionSchema | "UsedCondition" (item detail, when the page provides it) |
size | "M" |
color | "Green" (item detail) |
description | full listing text (item detail, when Fetch item detail is on) |
uploadDate | "12 h" (item detail) |
favouriteCount | 18 |
viewCount | null (the site no longer publishes view counts, so this is reported as unknown rather than a fake 0) |
promoted | false |
image | main photo URL |
photos, photoCount | photo list with id, url, fullSizeUrl, dominantColor, width and height, and the number of photos |
url | link to the listing |
sellerId, sellerUrl | "0000000001" (with item detail or seller profiles on; otherwise in seller.id) and the seller's member page link |
seller.username, seller.business | "sample_seller", false |
seller.feedbackReputation, seller.feedbackCount | 4.9, 312 (seller profile, when enabled) |
seller.city | "Sample City" (seller profile, when enabled) |
seller.bundleDiscount | 0.1, a fraction, present only when the seller has the bundle discount switched on (seller profile, when enabled) |
seller.lastLogedOnTs, seller.soldItemCount, seller.boughtItemCount, seller.followingBrandsCount, seller.isOnHoliday, seller.isEmailVerified, seller.isFacebookVerified, seller.isGoogleVerified | 1790000000 (last login, epoch seconds), 122 sold, 57 bought, 0 followed brands, false, true, false, false (seller profile, when enabled) |
sellerBadges | ["ACTIVE_LISTER"], the seller badges shown on the item page (item detail, when enabled; absent when the page shows none) |
changeType | "NEW" (also "UPDATED", "UNCHANGED", "REAPPEARED", "EXPIRED"; incremental mode only) |
Reviews mode returns a different row shape: one entry per feedback with reviewId, rating, body, createdAt, reviewerUsername, plus the seller's own sellerFeedbackRating and sellerFeedbackCount repeated on every row.
How to Use
- Pick a Mode:
search(keyword),url(paste links) orreviews(a seller's feedback). - Search mode: type Search keywords, and optionally narrow with Category ID, Brand ID, Condition or price. URL mode: paste item, seller/member, catalogue, category or brand links. URL mode with the URLs field left untouched now works through one example of each supported URL form (the three item-page forms resolve to one listing, returned once) (item, member, catalogue search with page, sort and filters, category page, brand page, on several markets); clear the list and paste your own links to scrape only those. Links the site does not serve (the m. mobile host, member /items and /feedback sub-pages) are skipped with a warning in the log. Category ID and Brand ID accept either the numeric id or the name as typed on the site; a name with no match stops the run with a clear message. Reviews mode: paste seller ids or member links.
- Pick the Country marketplace, and switch on Fetch item detail or Fetch seller profiles for extra depth.
- Set Max items to control run size and cost, then click Start.
Search a keyword with filters:
{"mode": "search","queries": ["nike air max"],"conditions": ["2"],"minPrice": 10,"maxPrice": 60,"country": "de","maxItems": 50}
Paste links (item and seller, mixed markets):
{"mode": "url","urls": ["https://www.vinted.fr/items/0000000000-sample-knitted-winter-sweater","https://www.vinted.de/member/0000000001"],"fetchDetails": true,"fetchSellerProfiles": true}
A seller's full feedback history:
{"mode": "reviews","sellers": ["0000000001"],"country": "de"}
Recurring monitoring of a search, with expiry tracking on:
{"mode": "search","queries": ["vintage denim jacket"],"country": "fr","incrementalMode": true,"emitExpired": true}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/vinted-marketplace-scraper").call(run_input={"mode": "search", "queries": ["nike air max"], "country": "de"})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], item["priceAmount"], item["currency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/vinted-marketplace-scraper').call({mode: 'search', queries: ['nike air max'], country: 'de',});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Supported URL shapes (url mode)
Each link keeps its own market from its hostname (vinted.de, .co.uk, .com and the others, with or without www).
| Shape | Example path |
|---|---|
| Catalogue search | /catalog?search_text=nike |
| Catalogue search, page | /catalog?search_text=nike&page=2 |
| Catalogue search, sort | /catalog?search_text=nike&order=newest_first |
| Catalogue search with filters | /catalog?search_text=nike&catalog[]=1242&brand_ids[]=53&price_to=50&status_ids[]=6 |
| Brand filter only | /catalog?brand_ids[]=53 |
| Category page | /catalog/1242-sneakers |
| Category page, page and sort | /catalog/1242-sneakers?page=2&order=newest_first |
| Category page with brand filter | /catalog/1242-sneakers?brand_ids[]=53 |
| Brand page | /brand/53-nike |
| Item | /items/10566802080-nike-sneaker |
| Item, id only | /items/10566802080 |
| Item on another market | vinted.co.uk/items/... |
| Member | /member/3162455054 |
| Member with slug | /member/3162455054-vrna21 |
| Member, page | /member/3162455054?page=2 |
| Other market catalogue | vinted.co.uk/catalog?search_text=nike |
| US market catalogue | vinted.com/catalog?search_text=nike |
| Host without www | vinted.de/catalog?search_text=nike |
The URLs field is pre-filled with one example of each of these 18 URL forms, so a run started without editing it works through all of them (a non-empty default). The three item-page examples (id-slug, numeric id only, other market) point to the same listing, so that listing is returned once, not three times. Clear the list and paste your own links to scrape only those. The m. mobile host and the /member/<id>/items and /member/<id>/feedback sub-pages are not served by the site and are skipped with a warning.
Filters and sorts (search mode)
Filters: Category ID and Brand ID (numeric id or the name as typed on the site), Condition (New with tags, New without tags, Very good, Good, Satisfactory), minimum and maximum price. Sort: Relevance, Newest first, Price low to high or Price high to low. Alternate input names are accepted: query, priceMin, priceMax, catalogId, condition, startUrls, includeItemDetails, includeSellerDetails.
Output views
The dataset has four views: Overview (listings), Reviews, Detail (item description and seller depth) and Changes (incremental classification and changed fields).
How the item budget is split across multiple targets
Max items is the run's total cap. When a run carries more than one target, meaning more than one search keyword, several pasted seller or catalogue links, or several sellers in reviews mode, that cap is divided evenly across them so a multi-target run returns a share from each instead of spending the whole budget on the first one. Pasted item links return one record each and count against the same total. Max pages additionally limits how many result pages each individual target may walk. In reviews mode, Max reviews per seller (default 20, up to 10000) additionally limits the feedback fetched for each seller.
A note on overlapping targets under a low cap
A result page holds 48 listings. When a target's share of Max items runs out part-way through a page (with the default Max items of 20 that happens on the very first page), the rest of that page's listings are recognised as already looked at for the remainder of the run, even though they were never returned. With a single target this is invisible, because nothing runs after it. It only matters when you combine several overlapping listing targets in one run (for example two keyword searches that both match the same dual-branded listing, or a pasted catalogue link and a seller link that share an item): a listing left over on the first target's cut-short page is then silently skipped by a later target too. Example: searches "nike" and "adidas" with Max items 10 give each a share of 5; "nike" returns its first 5 listings, and if listing number 7 on that page also appears in the "adidas" results, neither search returns it. Reviews mode is not affected, since each review belongs to exactly one seller. This never causes a false EXPIRED row (expiry detection only runs after every target reached its genuine natural end, which a cut-short target never does) and it does not affect Resume (which reads back the previous run's own dataset, not this in-run bookkeeping). Workaround: give overlapping searches or links a generous Max items, or run them separately, rather than combining them under a tight shared cap in a single run.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips everything that run already collected, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same search, URLs or sellers. Each listing is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED, meaning sold or removed, only after a run that scanned the whole tracked scope and only withemitExpiredon.stateKeynames or shares the stored state; leaving it empty derives one automatically from the mode, country and target settings.ignoreFieldsForChangeslets you exclude extra fields from change detection (a dotted name such asseller.cityorphotos.widthignores that key inside the nested value); view and favourite counters, the relative upload label, signed photo and avatar links and live seller counters (last seen online, followers, item count, sold and bought counts, followed brands) are already excluded by default, stay in the output, and never cause a falseUPDATED. With incremental mode off, output is exactly as before.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify -> Settings -> Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search, url, or reviews. |
country | string | de | Country marketplace to search, and the fallback market for URLs that don't name one. |
queries | array | ["nike"] | Search keywords (search mode). The budget splits evenly across them. |
categoryId | string | (none) | A catalogue id. Narrows a search, or browses a whole category alone (search mode). |
brandId | string | (none) | A brand id (search mode). |
conditions | array | (none) | Restrict results to these conditions (search mode). |
minPrice | integer | (none) | Only items priced at or above this amount (search mode). |
maxPrice | integer | (none) | Only items priced at or below this amount (search mode). |
sortBy | string | relevance | relevance or newest_first (search mode). |
urls | array | one example per supported URL form | Item, seller/member, catalogue/search, category (/catalog/<id>-<name>) or brand (/brand/<id>-<name>) links (url mode). Each keeps its own market. |
maxReviews | integer | 20 | Reviews mode: most reviews fetched per seller (1 to 10000); Max items still caps the whole run. |
sellers | array | (none) | Seller numeric ids or member links to fetch feedback for (reviews mode). |
fetchDetails | boolean | false | Add full description, colour, upload date and schema condition per listing. Billed as the detail-enrichment surcharge. |
fetchSellerProfiles | boolean | false | Add seller depth (reputation, response time, bundle discount and more) per listing. Also billed as the detail-enrichment surcharge. |
maxPages | integer | (none) | Stop each search/URL/seller after this many result pages. 0 or empty = as many as needed. |
maxItems | integer | 20 | Hard cap on total records returned across the whole run. 0 = unlimited. |
proxy | object | Apify residential proxy | Connection settings. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
resumeFromRunId | string | (none) | Continue one interrupted run without re-collecting or re-charging its records. |
incrementalMode | boolean | false | Return only new, changed, reappeared and expired records on scheduled runs. |
stateKey | string | (none) | Name or share an incremental-mode state; auto-derived when left empty. |
ignoreFieldsForChanges | array | [] | Incremental mode only. Extra field names (or dotted nested names such as seller.city) to leave out of change detection, on top of the built-in exclusions. |
emitUnchanged | boolean | false | Also return (and bill) unchanged records. |
emitExpired | boolean | false | Also return (and bill) records no longer found after a complete scan. |
query | string | (none) | Alias of queries; used only when queries is empty. |
priceMin | integer | (none) | Alias of minPrice; used only when minPrice is empty. |
priceMax | integer | (none) | Alias of maxPrice; used only when maxPrice is empty. |
catalogId | string | (none) | Alias of categoryId; used only when categoryId is empty. |
condition | array | (none) | Alias of conditions; used only when conditions is empty. |
startUrls | array | (none) | Alias of urls; used when urls is empty or still holds its prefilled example list. Any other urls value wins. |
includeItemDetails | boolean | (none) | Alias of fetchDetails; true turns on Fetch item detail (billed as the detail-enrichment surcharge per returned listing). A fetchDetails that is already on stays on. |
includeSellerDetails | boolean | (none) | Alias of fetchSellerProfiles; true turns on Fetch seller profiles (billed as the detail-enrichment surcharge per returned listing). A fetchSellerProfiles that is already on stays on. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"itemId": "0000000000","title": "Sample knitted winter sweater","url": "https://www.vinted.de/items/0000000000-sample-knitted-winter-sweater","path": "/items/0000000000-sample-knitted-winter-sweater","brandTitle": "Sample Brand","priceAmount": 12.5,"currency": "EUR","size": "M","condition": "Very good","conditionSchema": "UsedCondition","color": "Green","description": "Sample listing description text.","uploadDate": "12 h","favouriteCount": 18,"viewCount": null,"promoted": false,"serviceFee": 1.2,"totalPrice": 13.7,"photos": [{ "id": 1, "url": "https://images.example/sample.jpg", "fullSizeUrl": "https://images.example/sample-full.jpg", "dominantColor": "#a1b2c3", "width": 800, "height": 800 }],"photoCount": 1,"sellerUrl": "https://www.vinted.de/member/0000000001","image": "https://images.example/sample.jpg","sellerId": "0000000001","seller": {"id": "0000000001","username": "sample_seller","business": false,"city": "Sample City","feedbackReputation": 4.9,"feedbackCount": 312,"bundleDiscount": 0.1,"soldItemCount": 122,"boughtItemCount": 57,"isEmailVerified": true},"sellerBadges": ["ACTIVE_LISTER"],"scrapedAt": "2026-01-01T00:00:00+00:00"}
Plan Requirement
The default connection uses the Apify residential proxy pool pinned to the market's country, and it works out of the box on a paid Apify plan. The standard datacenter pool also served the marketplace in our checks, so you can select it in the proxy field for a cheaper run; residential stays the default because it is the more reliable choice. Apify free plans do not include residential proxies. When the selected pool is unavailable to your account, the run logs this warning and continues on a backup connection:
The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable.
When pages are then read over the backup, the log says: "Served over the backup connection (the default connection was unavailable)." If no page can be read at all, the run fails with one of three messages instead of returning an empty dataset: the proxy connection was refused for this account (your plan does not include proxy access); no results because residential proxies are unavailable and the backup connection could not load the pages; or "Could not load any results page (the requests failed)... a connection problem, not an empty search". You can also paste your own proxy URLs, which are used as given.
FAQ
How much does it cost?
You pay per result row returned (a listing or a review, charged once per row delivered, with volume tiers by Apify plan), plus the detail-enrichment event (per listing, only when delivered) only on listings where you switched on item detail and/or seller profiles. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Vinted?
This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Vinted's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing text, prices and seller ratings belong to their respective users.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, changed and reappeared records, and unchanged ones are not billed. With Emit expired on, sold or removed listings come back marked EXPIRED once a run has fully scanned the tracked scope.
Why does my dataset have fewer rows than I expected when I combine several searches, URLs or sellers in one run?
First, Max items is split evenly across every target in the run, so each keyword or link gets only its share. Second, when a target's share runs out part-way through a 48-listing result page, the rest of that page is treated as already looked at for the rest of the run. That is harmless for a single target, but a listing that also matches a later target in the same run is then skipped by that target too: for example, searches "nike" and "adidas" with Max items 10 return 5 each, and a listing sitting 7th on the "nike" page that also shows up under "adidas" is returned by neither. Give overlapping searches or links a generous Max items, or run them separately, to avoid it.
Why did my run fail instead of returning an empty dataset?
If the marketplace refuses every request, the run stops with a clear message so "no listings for my search" is never confused with "nothing could be read". Run it again in a few minutes. If only some pages were refused but real rows were delivered, you still get what was found, reported as partial results.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
π Want more Vinted data?
Pair this actor with these related scrapers from the same team:
| π·οΈ Vinted.fr Scrape Vinted.fr, France's C2C second-hand fashion marketplace: search with... | π·οΈ Curtsy Fashion Resale Scraper Scrape Curtsy, the US secondhand fashion marketplace: listings with brand, size, list vs... |
| π·οΈ Poshmark Scraper Scrape Poshmark fashion-resale listings: keyword search, brand and category browse, sold... | π·οΈ Daangn Scraper Scrape Daangn (λΉκ·Ό) marketplace listings by keyword and region. Returns 35+ fields per... |
| π·οΈ ThredUp Scraper Scrape ThredUp resale listings by keyword, department, brand, size, condition, price or... | π·οΈ Wildberries Scraper Scrape Wildberries marketplace: product search with prices (wallet vs retail), discounts... |
π Browse all abotapi scrapers
π¬ Support
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email contact@abotapi.com.
- β Enjoying it? A quick review on the actor page helps other users find it.