Vinted APIvinted.nl ↗
Search Vinted.nl second-hand listings by keyword. Get titles, prices, brands, sizes, conditions, image URLs, and listing URLs in structured JSON.
What is the Vinted API?
The Vinted.nl API exposes 1 endpoint — search_listings — that returns up to 96 catalog listings per page for any free-text search phrase, sorted newest-first by default. Each result includes the listing ID, title, URL, brand, price, size and condition, and full image URLs. The response also reports total_entries and total_pages so you can paginate through the full result set programmatically.
curl -X GET 'https://api.parse.bot/scraper/3bccc3ee-9b40-477b-b113-2e2f21ce8844/search_listings?order=newest_first&search_text=nike+air+max' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace vinted-nl-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Vinted NL SDK — search second-hand listings, browse prices."""
from parse_apis.vinted_nl_api import VintedNL, SortOrder, InputFormatInvalid
client = VintedNL()
# Search for Nike Air Max listings, cheapest first, capped at 5 results.
for listing in client.listings.search("nike air max", order=SortOrder.PRICE_LOW_TO_HIGH, limit=5):
print(listing.title, listing.price.amount, listing.price.currency)
# Drill into the newest listing for a different query.
newest = client.listings.search("levi's 501", order=SortOrder.NEWEST_FIRST, limit=1).first()
if newest is not None:
print(newest.title, newest.brand, newest.size_and_condition)
print("total:", newest.total_price.amount, newest.total_price.currency)
print("seller business?", newest.seller.is_business)
print("favourites:", newest.favourite_count)
print("photos:", len(newest.photos))
# Demonstrate typed-error handling: InputFormatInvalid is raised for bad inputs.
try:
bad = client.listings.search("test", order="not_a_real_order", limit=1).first()
except InputFormatInvalid as e:
print("caught expected error:", e.message)
print("exercised: listings.search (paginated, enum sort, .first(), error handling)")
Returns one page of Vinted.nl catalog listings matching a free-text search phrase. Sorted newest-first by default, so the first page is the most recently uploaded matching listings; other sort orders are available through the order parameter. Each row is one listing with its price breakdown (item price, buyer protection service fee, and total, all in the currency the site reports), a full-size main image URL (image_url) plus the photo list with sized thumbnails, brand, a size/condition summary line as shown on the site card, and the seller id. One page per call, 96 listings per page as fixed by the site; the page parameter selects the page (omitted = first page) and total_pages / has_more describe the continuation (the site caps results at 10 pages, i.e. total_entries never exceeds 960). Note: when a phrase has few or no exact matches, the site itself pads the results with loosely related listings rather than returning an empty page, so an empty items list is not expected. Invalid order or non-positive page values are rejected with a 422.
| Param | Type | Description |
|---|---|---|
| page | integer | 1-based page number within the sorted result stream; valid pages are 1..total_pages of the response. |
| order | string | Sort order of the result stream. |
| search_textrequired | string | Free-text search phrase, e.g. a brand and model name. |
{
"type": "object",
"fields": {
"page": "page number returned",
"items": "array of listing objects: id (string), title, url (listing page), brand, size_and_condition (site card line, size and condition separated by a middle dot; size may be absent), accessibility_label (site text summarising brand, condition, size and prices), price / price_with_discount / service_fee / total_price ({amount: number, currency}; price_with_discount is null when no discount), favourite_count, is_promoted, dominant_color (hex), thumbnail_url (310x430), image_url (full-size main photo), photos (array of {url, is_main, thumbnails[{type,url,width,height}]}), seller ({id: string, is_business})",
"order": "sort order applied",
"has_more": "true when page < total_pages",
"per_page": "listings per page (site-fixed, 96)",
"search_text": "echo of the phrase searched (trimmed)",
"total_pages": "number of pages available",
"total_entries": "total matching listings the site reports for this search (capped by the site at 960)"
},
"sample": {
"data": {
"page": 1,
"items": [
{
"id": "10195498189",
"url": "https://www.vinted.nl/items/10195498189-nike-air-max-90-easyon-maat-33",
"brand": "Nike Air",
"price": {
"amount": 45,
"currency": "EUR"
},
"title": "Nike Air max 90 Easyon maat 33",
"photos": [
{
"url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/f800/19231b8a.webp?s=cddefb2b2ff3c779558dcbdd16e38e75b10b487a",
"is_main": true,
"thumbnails": [
{
"url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/70x100/19231b8a.webp?s=06f2b908dbac799399e58b11cdd0f5ecdc9e158d",
"type": "thumb70x100",
"width": 70,
"height": 100
},
{
"url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/150x210/19231b8a.webp?s=3fb5fc9ff6410a6126691abdb870e876786cdde9",
"type": "thumb150x210",
"width": 150,
"height": 210
},
{
"url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/f800/19231b8a.webp?s=cddefb2b2ff3c779558dcbdd16e38e75b10b487a",
"type": "thumb364x428",
"width": 364,
"height": 204
}
]
}
],
"seller": {
"id": "168789909",
"is_business": false
},
"image_url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/f800/19231b8a.webp?s=cddefb2b2ff3c779558dcbdd16e38e75b10b487a",
"is_promoted": false,
"service_fee": {
"amount": 2.95,
"currency": "EUR"
},
"total_price": {
"amount": 47.95,
"currency": "EUR"
},
"thumbnail_url": "https://images1.vinted.net/t/02_0191d_K59Gj1jBi6mPtUK1KgxVWiQN/310x430/19231b8a.webp?s=643ca509698a5fda192cc419e37c7901f6f60dc0",
"dominant_color": "#EADDDE",
"favourite_count": 0,
"size_and_condition": "33 · Heel goed",
"accessibility_label": "Nike Air max 90 Easyon maat 33, Merk: Nike Air, Staat: Heel goed, Maat: 33, 45.00 €, 47.95 €",
"price_with_discount": null
}
],
"order": "newest_first",
"has_more": true,
"per_page": 96,
"search_text": "nike air max",
"total_pages": 10,
"total_entries": 960
},
"status": "success"
}
}About the Vinted API
What the API returns
The search_listings endpoint accepts a search_text parameter and returns one page of matching Vinted.nl listings. Each item in the items array includes a string id, title, direct url to the listing page, brand, size_and_condition (the combined size-and-condition label shown on the site's listing card), price information, and full image URLs. The response envelope also echoes search_text, confirms the order applied, and provides page, per_page (fixed at 96 by the site), total_pages, total_entries (capped at 960 by the site), and a has_more boolean.
Pagination and sort order
Results are sorted newest-first by default, meaning page 1 contains the most recently uploaded matching listings. You can change this with the order parameter — the site supports several sort orders. Pagination is 1-based via the page integer parameter. Walk through pages while has_more is true, up to the total_pages ceiling. Because total_entries is capped at 960, broad searches will not surface listings beyond that threshold.
Coverage scope
The API targets the Dutch Vinted domain, vinted.nl. Listings reflect what is publicly visible on that locale: second-hand fashion and lifestyle items listed by individual sellers across the Netherlands. Brand, size, and condition are returned as displayed on listing cards, so format varies by seller input. Seller profile details and full item descriptions beyond the card-level fields are not part of the current response shape.
The Vinted API is a managed, monitored endpoint for vinted.nl — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when vinted.nl changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official vinted.nl API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Monitor newly listed items for a specific brand or model by polling search_listings sorted newest-first.
- Build a price-comparison tool using the price field across multiple search phrases.
- Aggregate brand-level supply data to see how many listings exist for a given brand using total_entries.
- Collect image URLs for visual cataloging or machine-learning training datasets.
- Track condition distribution of second-hand items by parsing the size_and_condition field across pages.
- Alert users when a specific search phrase produces new listings by comparing IDs between polling intervals.
- Build a resale research tool that pages through total_pages to sample asking prices for a product category.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.