Vinted API & Scraper
The Vinted API returns second-hand fashion listings, item and seller data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary catalog_search endpoint returns items with id, title, brand, size, price, URL, photos, condition and seller, with pagination, and you can pull an item_detail, a seller, their items and feedback, search brands, get similar items, filters and categories. It is built for resale-price intelligence, fashion apps and reselling tools that need Vinted data without a scraper. One ReefAPI key, one shared credit pool, the standard envelope.
Vinted's two prices, the condition ids and the 0-1 seller rating
Two numbers on a Vinted listing are easy to read wrong: the asking price is not what the buyer pays, and the seller rating is not a star score. Condition also arrives in two different vocabularies depending on which action you call. Measured on 2026-08-27 on vinted.fr and vinted.co.uk.
| Field or id | What it is | Measured value |
|---|---|---|
| price.amount | What the seller is asking | 40.00 EUR on item 9791322541 |
| service_fee.amount | Buyer Protection, added at checkout | 2.70 EUR on that same item |
| total_item_price.amount | price plus service_fee, what the buyer actually pays | 42.70 EUR |
| status_ids 6 / 1 | New with tags / New without tags | "Neuf avec étiquette" / "Neuf sans étiquette" on the fr site |
| status_ids 2 / 3 | Very good / Good | "Très bon état" / "Bon état" on fr, "Very good" / "Good" on co.uk |
| status_ids 4 / 7 | Satisfactory / Not fully functional | the last two ids returned by the conditions action |
| condition (catalog_search) | The localized label for the site you queried | "Très bon état" on fr, "Very good" on co.uk |
| condition (item_detail) | A schema.org value instead of the label | "UsedCondition", alongside availability "InStock" |
| seller.rating | A 0-1 reputation ratio rounded to two decimals, not a star score | 0.9 for a seller with 747 positive and 108 negative feedbacks |
| feedback[].rating | The actual 1-5 star score on one piece of feedback | 5 |
| item id | The digits in /items/<id>-slug, 10 digits today | 9791322541 |
| seller id | The digits in /member/<id>-login | 8 digits on every listing measured |
Both measured sites charged the same fee shape on the day: 0.70 plus 5 percent of the asking price. 40.00 EUR gave 2.70 and 13.50 EUR gave 1.38 on fr, and 7.42 GBP gave 1.07 on co.uk. That is Vinted's charge, not ours and not a constant we control, so read service_fee rather than recomputing it.
Real request and response JSON
Captured from the indexed primary action, catalog_search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/vinted/v1/catalog_search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"query": "nike",
"tld": "fr",
"per_page": 20
}
}{
"ok": true,
"meta": {
"api": "vinted",
"endpoint": "catalog_search",
"mode": "live",
"latency_ms": 2038.8,
"record_count": 20,
"bytes": 285318,
"cache_hit": false,
"completeness_pct": 100,
"stop_reason": "cap_reached",
"tld": "fr",
"total_entries": 960,
"window_cap": 960,
"pagination": {
"page": 1,
"has_more": true
}
},
"data": {
"items": [
{
"id": 9423313905,
"title": "Nike zwart cropped T-shirt logo Plus Size 2X EU 50/52",
"url": "https://www.vinted.fr/items/[redacted-phone]-nike-zwart-cropped-t-shirt-logo-plus-size-2x-eu-5052",
"price": {
"amount": 15,
"currency": "EUR"
},
"total_item_price": {
"amount": 16.45,
"currency": "EUR"
},
"service_fee": {
"amount": 1.45,
"currency": "EUR"
},
"brand": "Nike",
"size": "5XL / 50 / 22",
"condition": "Très bon état",
"is_visible": true,
"favourite_count": 0,
"view_count": 0,
"promoted": false,
"uploaded_ts": 1784317650,
"photos": [
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
},
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
},
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
}
],
"seller": {
"id": 28651912,
"login": "[redacted]",
"business": false,
"profile_url": "[redacted]"
}
},
{
"id": 9274294548,
"title": "Pull Nike sans capuche",
"url": "https://www.vinted.fr/items/[redacted-phone]-pull-nike-sans-capuche",
"price": {
"amount": 10,
"currency": "EUR"
},
"total_item_price": {
"amount": 11.2,
"currency": "EUR"
},
"service_fee": {
"amount": 1.2,
"currency": "EUR"
},
"brand": "Nike",
"size": "M / 38 / 10",
"condition": "Très bon état",
"is_visible": true,
"favourite_count": 0,
"view_count": 0,
"promoted": false,
"uploaded_ts": 1782662212,
"photos": [
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
},
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
},
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
}
],
"seller": {
"id": 17200761,
"login": "[redacted]",
"business": false,
"profile_url": "[redacted]"
}
},
{
"id": 9430052246,
"title": "Nike Air Sport Dry Fit Leggings mit Mesh XS",
"url": "https://www.vinted.fr/items/[redacted-phone]-nike-air-sport-dry-fit-leggings-mit-mesh-xs",
"price": {
"amount": 15,
"currency": "EUR"
},
"total_item_price": {
"amount": 16.45,
"currency": "EUR"
},
"service_fee": {
"amount": 1.45,
"currency": "EUR"
},
"brand": "Nike",
"size": "XS / 34 / 6",
"condition": "Très bon état",
"is_visible": true,
"favourite_count": 0,
"view_count": 0,
"promoted": false,
"uploaded_ts": 1784395199,
"photos": [
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
},
{
"url": "[trimmed-depth]",
"full_size_url": "[trimmed-depth]",
"dominant_color": "[trimmed-depth]",
"is_main": "[trimmed-depth]",
"width": "[trimmed-depth]",
"height": "[trimmed-depth]",
"uploaded_ts": "[trimmed-depth]"
}
],
"seller": {
"id": 3169529605,
"login": "[redacted]",
"business": false,
"profile_url": "[redacted]"
}
}
],
"pagination": {
"current_page": 1,
"total_pages": 48,
"total_entries": 960,
"per_page": 20,
"time": 1784395244
},
"query": "nike",
"filters": {},
"tld": "fr"
}
}What the Vinted API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| catalog_search | keyword + filter search (brand/size/condition/category/color/material/price) | Pricing teams call catalog_search to get keyword + filter search (brand/size/condition/category/color/material/price). | query, search_text, filters, brand_ids, size_ids, ... |
| item_detail | Full Vinted item detail — title, price, photos, description, size, color, condition, material, category and a seller summary. | Marketplace operators call item_detail to get full Vinted item detail. | id, item_id, url, path, tld |
| seller | seller profile (login/rating/item_count/feedback breakdown) — PII redactable | Catalog enrichment teams call seller to get seller profile (login/rating/item_count/feedback breakdown). | id, user_id, seller_id, tld |
| seller_items | a seller's wardrobe items | Retail analysts call seller_items to get a seller's wardrobe items. | id, user_id, seller_id, page, per_page, ... |
| seller_feedback | feedback left for a seller (text/rating/reviewer) | Pricing teams call seller_feedback to get feedback left for a seller (text/rating/reviewer). | id, user_id, seller_id, page, per_page, ... |
| brand_search | resolve a brand name -> brand_id (+ item/favourite counts) | Marketplace operators call brand_search to resolve a brand name -> brand_id (+ item/favourite counts). | query, search_text, page, per_page, tld |
| autocomplete | search typeahead — partial query -> ranked Vinted search suggestions (localized per site) | Catalog enrichment teams call autocomplete to search typeahead. | query, search_text, q, tld |
| similar | items similar to a given item (items/{id}/more) | Retail analysts call similar to get items similar to a given item (items/{id}/more). | id, item_id, content_source, tld |
| catalog_filters | dynamic facets (size/brand/status/color/price/material + option ids) for a query/category | Pricing teams call catalog_filters to get dynamic facets (size/brand/status/color/price/material + option ids) for a query/category. | query, search_text, catalog_ids, tld |
| categories | Full Vinted category tree — id, title, code, URL and child categories for the selected country site. | Marketplace operators call categories to get full Vinted category tree. | tld |
| colors | color enum (id/title/hex/code) | Catalog enrichment teams call colors to get color enum (id/title/hex/code). | tld |
| conditions | item-condition enum (status id/title) | Retail analysts call conditions to get item-condition enum (status id/title). | tld |
| countries | country enum (id/iso/currency) | Pricing teams call countries to get country enum (id/iso/currency). | tld |
| sizes | size groups + size ids | Marketplace operators call sizes to get size groups + size ids. | tld |
Call catalog_search from your stack
curl -X POST https://api.reefapi.com/vinted/v1/catalog_search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"nike","tld":"fr","per_page":20}'import requests
r = requests.post(
"https://api.reefapi.com/vinted/v1/catalog_search",
headers={"x-api-key": REEF_KEY},
json={
"query": "nike",
"tld": "fr",
"per_page": 20
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/vinted/v1/catalog_search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "nike",
"tld": "fr",
"per_page": 20
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.vinted.catalog_search with {"query":"nike","tld":"fr","per_page":20}.Who uses this API and why
- Resale-price tools call catalog_search to track second-hand prices for a brand and size.
- Reselling products use seller_items and seller_feedback to study a competitor's shop.
- Fashion apps use brand_search and similar to surface comparable second-hand listings.
Questions developers ask before integrating
Vinted shows two prices. Do both come through?
Yes, on catalog_search, seller_items and similar rows. price is what the seller asks, service_fee is the Buyer Protection charge and total_item_price is what the buyer pays. Item 9791322541 came back as 40.00, 2.70 and 42.70 EUR. All three are objects with their own currency field, so read amount and currency instead of assuming the site's currency.
Why does item_detail have no service fee?
Because the detail page and the catalog feed publish different things. item_detail returns a single price object with no service_fee and no total_item_price, and its url field also comes back null. If you need the fee or the buyer total for a specific item, take it from a catalog_search or seller_items row rather than from the detail call.
Why does condition say "UsedCondition" on one action and "Very good" on another?
They come from different parts of the page. catalog_search returns the label Vinted shows shoppers, localized to the site you queried. item_detail returns the schema.org vocabulary from the page markup, which collapses to values like "UsedCondition" with availability "InStock". The localized label is still available on item_detail, inside attributes[] under the key "status".
How do I filter by condition when the labels are translated?
Filter with status_ids, which are numeric and stable across sites: 6 New with tags, 1 New without tags, 2 Very good, 3 Good, 4 Satisfactory, 7 Not fully functional. Calling the conditions action on fr and on co.uk returned the same six ids in the same order, with French and English titles. Never match on the label text.
Is seller.rating a five-star score?
No, it is a 0-1 reputation ratio rounded to two decimals. Measured across five sellers: 268 positive with 1 negative gave 1.0, 595 positive with 8 negative gave 0.98, and 747 positive with 108 negative gave 0.9. The five-star numbers live on the individual feedback rows from seller_feedback, where rating is an integer 1 to 5. A seller.rating of 1.0 means near-perfect, not one star.
How deep can I page through Vinted search results?
About 960 items per filter combination. A search for 'nike hoodie' on fr reported total_entries 960 with meta.window_cap 960 and meta.stop_reason "cap_reached". per_page goes up to 96 and larger values are capped there. To go deeper, narrow with brand_ids, catalog_ids, size_ids or a price range rather than paging further.
Which country site am I actually reading?
Whichever tld you pass, and it defaults to fr rather than to an international site. tld picks both the listings and the currency: fr, de, es, it, nl, be, lt, lu, at, pt, sk and fi are EUR, co.uk is GBP, pl is PLN, cz CZK, se SEK, ro RON, hu HUF, dk DKK, and com is the international site in EUR. The same query on fr and on co.uk returns different items, not translations of the same items.
How do I tell when a listing was posted?
uploaded_ts on the item and on each photo is a Unix epoch in seconds, so 1787783412 on the item measured here was the moment the seller uploaded it. Combined with order="newest_first" that makes catalog_search usable as a live feed. Photos also carry dominant_color as a hex string, is_main, width, height and a separate full_size_url.
What is the Vinted API?
Vinted API is a ReefAPI endpoint group for second-hand fashion listings and prices. It returns live JSON through POST requests under /vinted/v1.
Is the Vinted API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Vinted calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Vinted login or account?
No login to Vinted is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Vinted data?
The page example is captured from a live catalog_search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Vinted API use?
Vinted actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Vinted from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call vinted actions with the same key, credit pool and JSON envelope used by normal REST requests.