Vestiaire Collective Scraper: Sold Items & Seller Intelligence avatar

Vestiaire Collective Scraper: Sold Items & Seller Intelligence

Pricing

from $16.00 / 1,000 listing results

Go to Apify Store
Vestiaire Collective Scraper: Sold Items & Seller Intelligence

Vestiaire Collective Scraper: Sold Items & Seller Intelligence

Scrape public Vestiaire Collective live and sold listings across 70 markets. Extract prices, seller countries, conditions, product details, price history, and duplicate/suspicious seller signals.

Pricing

from $16.00 / 1,000 listing results

Rating

0.0

(0)

Developer

KazKN

KazKN

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 hours ago

Last modified

Share

Vestiaire Collective Sold Items, Price Tracker & Seller Intelligence

Track public Vestiaire Collective listings across all supported market countries, sold-search results, sold-items pages, public price changes, seller-level benchmarks, and conservative duplicate risk signals.

This Actor is built for resale pricing research, sourcing workflows, seller benchmarking, and recurring watchlists. It uses public data only, supports separate market-country and seller-country filtering, and keeps durable tracking state between runs so repeated schedules can detect price changes and listings that move from active to missing or likely sold.

What You Can Extract

  • Live listing records from search terms and public Vestiaire start URLs.
  • Searches across all 70 supported Vestiaire countries by default, or selected markets only.
  • Seller/item country filtering with sellerCountries, independent from searched markets.
  • Item condition filtering with Vestiaire condition IDs.
  • Optional title/model precision filtering with requiredKeywords.
  • Product detail enrichment from public product pages.
  • Sold item records from Vestiaire's public sold search filter and public sold-items pages.
  • Public price history and likely_sold tracking across repeated runs.
  • Tracking records that preserve seller metadata when known and respect seller-country filters.
  • Seller summary records from observed listings and sold items.
  • Duplicate/risk signal records from descriptive public-record similarity.
  • Automatic deduplication when the same listing appears across several markets.
  • Diagnostic records when public requests fail before any records are collected.
  • Dataset views for listings, sold items, price history, seller summaries, risk signals, and run diagnostics.

How To Run

  1. Add one or more searchTerms, or add public Vestiaire startUrls.
  2. Leave countries as ["ALL"] to search every supported Vestiaire market, or pass explicit codes such as ["FR", "US", "GB"].
  3. Leave sellerCountries as ["ALL"] to include every seller location, or pass explicit seller/item country codes such as ["FR", "IT"].
  4. Optionally set itemConditions to restrict results by Vestiaire item condition.
  5. Optionally set requiredKeywords when the search query is too broad, for example ["classic flap"] to exclude Trendy CC Flap results.
  6. Set maxListings for the number of listing-like records to collect, and maxDatasetRecords for the total dataset rows to push.
  7. Enable includeDetails, includeSellerInfo, includeDuplicateSignals, or includeSoldItems depending on the records you need.
  8. Schedule repeat runs with the same trackingStoreName to build price history and likely-sold tracking over time.

Dataset results can be exported from Apify as JSON, CSV, Excel, or consumed through the Apify API.

Reading The Output

Every dataset row includes recordType, displayStatus, isSold, itemSummary, and priceText.

  • recordType tells you what the row is: listing, detail, sold_item, seller_summary, risk_signal, or diagnostic data.
  • displayStatus and isSold make active vs sold records clear in the Apify table.
  • itemSummary is a compact human-readable line for quick review.
  • country is the searched Vestiaire market/locale. sellerCountry is the seller or item location returned by Vestiaire.
  • condition is the item condition returned by Vestiaire when available. conditionFilter shows the selected condition filter, and conditionSource explains whether the condition came from Vestiaire or from the selected filter fallback.
  • Apify dataset views select columns; they do not filter rows. For sold analysis, filter exported data or API results with recordType === "sold_item" and isSold === true.
  • OUTPUT includes maxListings, maxDatasetRecords, listingRecordsCollected, duplicateRecordsSkipped, sellerCountryRecordsSkipped, and precisionRecordsSkipped so runs are easier to debug.

Country Selection

countries is optional.

  • Omit countries, pass [], or pass ["ALL"] to search all 70 supported Vestiaire countries.
  • Pass explicit country codes such as ["FR", "US", "GB"] to restrict the run.
  • countries controls the Vestiaire market/locale searched. It is not the same as seller location.
  • sellerCountries controls the seller/item location shown in sellerCountry.
  • Omit sellerCountries, pass [], or pass ["ALL"] to include every seller country.
  • Pass explicit seller country codes such as ["FR"] to keep only those sellers.
  • Do not combine ALL with explicit country codes.
  • Unknown country codes are rejected.
  • startUrls can point to any valid public Vestiaire Collective URL regardless of selected countries.
  • Duplicate active listings returned by several markets are deduplicated by listingId.
  • When the same seller-country filter is active, historical tracking records with unknown seller country are skipped instead of being emitted as sellerCountry: null.

Supported Vestiaire countries: AD, AU, AT, BH, BE, BR, BG, CA, IC, CN, HR, CY, CZ, DK, EE, FI, FR, GF, PF, DE, GI, GR, GP, GG, HK, HU, ID, IE, IM, IL, IT, JP, JE, KW, LV, LB, LI, LT, LU, MY, MT, MQ, YT, MC, NL, NC, NZ, NO, PH, PL, PT, QA, RE, RO, SA, SG, SK, SI, ZA, KR, ES, BL, MF, SE, CH, TW, TH, AE, GB, US.

Currency note: some selected countries use a supported Vestiaire display currency such as EUR or USD when the local currency returns zero-price records from Vestiaire's public search API.

Item Condition Filter

itemConditions is optional.

  • Omit itemConditions or pass [] to include every item condition.
  • Pass one or more Vestiaire condition IDs to restrict active searches and sold-search collection.
  • Supported values: 1 = Jamais portรฉ avec รฉtiquette, 2 = Jamais portรฉ, 3 = Trรจs bon รฉtat, 4 = Bon รฉtat, 5 = Correct.
  • When Vestiaire does not return a condition but exactly one condition filter was selected, the Actor uses that selected condition as a conservative fallback and marks conditionSource as selected_filter.
  • When multiple condition filters are selected, conditionFilter keeps the selected labels and conditionSource can be multi_selected_filter if Vestiaire does not return a precise condition.

Precision Filter

requiredKeywords is optional.

  • Leave requiredKeywords empty to keep all results returned by Vestiaire for the search query.
  • Add one or more words or phrases to require them in the public title or model.
  • All required keywords must match. ["classic flap"] keeps Chanel Classic Flap handbag and removes Chanel Trendy CC Flap handbag.
  • Matching is case-insensitive and accent-insensitive.

Run Limits

  • maxListings limits listing-like records: listing, sold_item, and tracking rows.
  • maxDatasetRecords limits total dataset rows pushed, including product detail, seller_summary, risk_signal, and diagnostics.
  • maxItems is still accepted for backward compatibility as an alias of maxDatasetRecords. If maxDatasetRecords is set, it wins.
  • With countries: ["ALL"], every country/requรชte combination gets at least a one-listing search budget while the global maxListings cap still controls total output.
  • If includeDetails, includeSellerInfo, or includeDuplicateSignals is enabled, set maxDatasetRecords higher than maxListings so enrichment rows are not capped out.

Example Input: All Markets

{
"searchTerms": ["chanel classic flap", "gucci jackie bag"],
"countries": ["ALL"],
"maxListings": 100,
"maxDatasetRecords": 250,
"maxPagesPerCountry": 2,
"includeDetails": true,
"includeSellerInfo": true,
"includeDuplicateSignals": true,
"proxyConfiguration": {
"useApifyProxy": true
},
"missingRunsThreshold": 2
}

Example Input: Selected Markets And Seller Countries

{
"searchTerms": ["loewe puzzle bag"],
"countries": ["FR", "US", "GB"],
"sellerCountries": ["FR", "IT", "GB"],
"itemConditions": ["3", "4"],
"maxListings": 50,
"maxDatasetRecords": 75,
"maxPagesPerCountry": 1,
"includeDetails": false,
"includeSellerInfo": true
}
{
"searchTerms": ["chanel classic flap"],
"countries": ["ALL"],
"sellerCountries": ["FR"],
"itemConditions": ["3", "4"],
"requiredKeywords": ["classic flap"],
"maxListings": 20,
"maxDatasetRecords": 40,
"maxPagesPerCountry": 2,
"includeDetails": false,
"includeSellerInfo": false,
"includeDuplicateSignals": false,
"includeSoldItems": false
}

This searches all Vestiaire markets but only keeps listings whose seller/item country is France. If the market returns the same listing several times, only one listing row is pushed.

Example Input: Sold Items Page

{
"startUrls": [
{
"url": "https://us.vestiairecollective.com/c/vip-sold-items-12125/"
}
],
"countries": ["US"],
"maxListings": 25,
"maxDatasetRecords": 25,
"includeSoldItems": true,
"includeDetails": false
}

With search terms, includeSoldItems also queries Vestiaire's public sold-search filter. With start URLs, it only parses URLs whose path is a sold-items page. Normal category, search, and product URLs are never forced into sold records.

Output Examples

Listing:

{
"recordType": "listing",
"sourceMode": "SEARCH_API",
"country": "FR",
"query": "chanel classic flap",
"listingId": "101",
"title": "Chanel classic flap bag",
"brand": "Chanel",
"condition": "Trรจs bon รฉtat",
"conditionSource": "vestiaire_field",
"price": 4200,
"currency": "EUR",
"status": "available",
"displayStatus": "Available",
"url": "https://fr.vestiairecollective.com/women-bags/handbags/chanel/classic-flap-101.shtml",
"sellerUsername": "pariscloset",
"sellerCountry": "FR"
}

Sold item:

{
"recordType": "sold_item",
"sourceMode": "SOLD_SEARCH_API",
"country": "US",
"listingId": "303",
"title": "Saffiano leather tote",
"brand": "Prada",
"price": 650,
"currency": "USD",
"status": "sold",
"isSold": true,
"soldDisplayedPrice": 650,
"lastPublicPrice": 650,
"soldDetectedAt": "2026-06-06T12:01:00.000Z",
"soldSource": "api-search",
"soldConfidence": "api_sold_filter_verified"
}

Price history:

{
"recordType": "listing",
"sourceMode": "TRACKING",
"listingId": "101",
"status": "likely_sold",
"sellerUsername": "pariscloset",
"sellerCountry": "FR",
"lastPublicPrice": 3900,
"currency": "EUR",
"likelySoldDetectedAt": "2026-06-06T12:01:00.000Z",
"priceHistory": [
{ "price": 4200, "currency": "EUR", "observedAt": "2026-06-01T12:00:00.000Z" },
{ "price": 3900, "currency": "EUR", "observedAt": "2026-06-04T12:00:00.000Z" }
]
}

Seller summary:

{
"recordType": "seller_summary",
"sellerId": "seller-1",
"sellerUsername": "pariscloset",
"sellerCountry": "FR",
"activeListingCountObserved": 12,
"soldListingCountObserved": 4,
"avgActivePrice": 1820,
"avgSoldPriceObserved": 1540,
"activeToSoldRatioObserved": 0.25
}

Duplicate risk signal:

{
"recordType": "risk_signal",
"duplicateClusterId": "cluster-4c8f8e90a1c4f0b0d3c01f23",
"duplicateSignalScore": 0.95,
"riskSignalLevel": "medium",
"duplicateReasons": ["same_title_brand_category", "same_image_url", "similar_price_band"],
"similarListingIds": ["101", "102"],
"sellerUsername": "pariscloset"
}

Run diagnostic:

{
"recordType": "run_diagnostic",
"diagnosticType": "public_request_error",
"ok": false,
"message": "Public Vestiaire request failed before any dataset records could be collected.",
"publicRequestErrors": [
{
"url": "https://fr.vestiairecollective.com/search/?q=chanel&page=1",
"statusCode": 403,
"message": "Vestiaire public request failed with HTTP 403"
}
]
}

Output Views

  • listings: live listing and tracking records.
  • sold_items: public sold item records.
  • product_details: detail enrichment columns for product descriptions, material, authentication, shipping, and breadcrumbs. Use rows with recordType === "detail".
  • price_history: tracking states and public price observations.
  • seller_summary: observed seller-level aggregates.
  • risk_signals: conservative duplicate signals from public-record similarity.
  • diagnostics: non-charged run diagnostics when public requests fail before records are collected.

Tracking Behavior

The Actor stores durable state in the named key-value store set by trackingStoreName, defaulting to vestiaire-smart-tracker.

  • First observation records the listing as active unless the page explicitly marks it sold.
  • Repeated observations append public price changes.
  • A disappeared listing becomes missing first.
  • It becomes likely_sold only after missingRunsThreshold consecutive missing runs.
  • An explicit sold page state remains sold in later runs.
  • Seller fields are stored in tracking state when Vestiaire returns them, so later TRACKING records can preserve sellerId, sellerUsername, sellerCountry, and sellerUrl.
  • Seller-country filters also apply to TRACKING rows. Old tracking states without seller country are skipped when a restrictive sellerCountries filter is active.
  • The same listing can be seen through several market countries, but pushed listing/tracking rows are deduplicated by listingId.
  • Failed public requests and maxListings or maxDatasetRecords interruptions do not mark previous listings as missing.

Billing And Limits

This Actor uses Pay Per Event billing. It charges successfully processed search/start pages and charges before pushing each valuable dataset record. If a user charge limit is reached, it stops processing paid work and writes the run summary to OUTPUT.

Live Pay Per Event setup:

Event nameTriggerFREEBRONZESILVERGOLD+
search-pageOne successfully fetched and parsed search, sold-search, or start URL page$0.0020$0.0018$0.0015$0.0012
listing-resultOne active listing or tracking result pushed to the dataset$0.025$0.020$0.018$0.016
sold-itemOne public sold item result pushed to the dataset$0.030$0.025$0.022$0.020
detail-enrichmentOne product detail enrichment row pushed to the dataset$0.007$0.006$0.005$0.004
seller-profileOne seller summary row pushed to the dataset$0.006$0.004$0.003$0.002
duplicate-clusterOne duplicate/risk signal row pushed to the dataset$0.006$0.004$0.003$0.002

Billing notes:

  • listing-result is the primary buyer-facing event.
  • At BRONZE tier, listing-only runs are about $20.08 / 1,000 results assuming roughly 24 results per search page; listing + details is about $26.08 / 1,000. At GOLD+ tier, listing + details is about $20.05 / 1,000.
  • Keep the synthetic apify-actor-start event enabled at its default price.
  • Disable apify-default-dataset-item or set it to 0 because this Actor already charges explicit dataset-record events.
  • OUTPUT.searchPagesProcessed and OUTPUT.searchPagesCharged help verify page-level billing in smoke runs.
  • Memory is capped at 512-1024 MB in actor.json to avoid paying 4 GB run costs for lightweight HTTP scraping.

Limits:

  • Works with public pages only.
  • No login, cookies, private account data, or hidden seller data.
  • Sold prices are public displayed prices, not private settlement amounts.
  • Duplicate/risk signals are heuristics from public-record similarity, not authenticity or trust decisions.
  • Live page structure can change; use small smoke runs before scaling.
  • The Actor is not affiliated with Vestiaire Collective.

Proxy Behavior

Apify Proxy is enabled by default through proxyConfiguration: { "useApifyProxy": true }. If you override proxyConfiguration, the Actor uses your provided Apify-compatible proxy settings. Local runs without Apify proxy credentials fall back to direct public requests and may return public request errors.

Local Development

npm install
npm test
npm run build
apify validate-schema
apify run --purge --input-file test/smoke/inputs/search-small.json