# Yoox Scraper — Outlet Prices With Supplier RRP (`studio-amba/yoox-scraper`) Actor

Scrape yoox.com, YNAP's luxury outlet. Every product comes back with the supplier-stated RRP, its source and its date, next to the current outlet price and the markdown between them. Plus brand, sizes, stock, category, colour and images.

- **URL**: https://apify.com/studio-amba/yoox-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Yoox Scraper

Get Yoox's outlet catalogue with the **supplier-stated RRP** on every single product, so you can tell a real discount from a marketing one.

Yoox is YNAP's off-season luxury outlet. This actor reads its product catalogue and returns the current outlet price, the recommended retail price the *supplier* stated, the date that RRP was stated, and the markdown between the two. Plus brand, size ladder, availability, category, colour, materials and images.

### The field nobody else publishes

This is the whole reason to point a scraper at Yoox rather than at another luxury site.

| Retailer | What the "was" price actually means |
|---|---|
| Farfetch | Farfetch's own previous price |
| Mytheresa | Mytheresa's own previous price |
| Net-a-Porter | Net-a-Porter's own previous price |
| **Yoox** | **The RRP the supplier stated, with a source and a date** |

Every other luxury retailer shows you what *they* used to charge. That number moves with their own promo calendar and tells you very little about what the piece is worth. Yoox publishes `retailPrice` with `retailPriceSource: "Supplier"` and `retailPriceDate`, plus a `retailPriceTrusted` flag. That is the brand's number, not the shop's.

For price comparison, resale valuation, arbitrage screening or brand-level pricing research, that makes Yoox the reference point rather than the footnote.

Because of that, this actor never gives you a markdown price on its own. `currentPrice` and `retailPrice` always travel together in the output, so nothing downstream can mistake an outlet discount for a market price.

### Why use this actor?

- **Resale and arbitrage** — screen for pieces trading far below their stated RRP, with the RRP itself as the anchor.
- **Competitive pricing** — see what a brand's own RRP is versus what the outlet channel actually clears at.
- **Market research** — measure real markdown depth per brand, category and season across a 150,000-product catalogue.
- **Product feeds** — brand, category, colour, composition, size ladder, availability and gallery images in one record.

### How to scrape Yoox data

1. Open the actor on Apify and pick a market (Belgium, Luxembourg or the Netherlands).
2. Type a search query, or leave it empty to browse the entire catalogue for that market.
3. Optionally narrow with brand, gender, department, price range or minimum markdown against RRP.
4. Set **Max items** and run it.
5. Export the dataset as JSON, CSV, Excel or read it straight from the Apify API.

No login, no cookies, no proxy, no browser. Yoox's catalogue is served by a public search index, so a run is close to instant: 3,000 products come back in about 3 seconds.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Single keyword search, e.g. `gucci bag`. Empty browses the whole catalogue. |
| `searchQueries` | Array | No | Several searches in one run. Takes precedence over `searchQuery`. Results are de-duplicated. |
| `market` | String | No | `BE`, `LU` or `NL`. Default `BE`. |
| `maxItems` | Integer | No | Max products across all queries. Default 100. |
| `brand` | String | No | Plain-language brand name, e.g. `prada`. Resolved against Yoox's own brand list. |
| `gender` | String | No | `any`, `Women` or `Men`. Default `any`. |
| `department` | String | No | Yoox department code for a finer category cut, e.g. `ShoesWomen`. |
| `minPrice` | Integer | No | Minimum current outlet price in EUR. |
| `maxPrice` | Integer | No | Maximum current outlet price in EUR. |
| `minDiscountPercent` | Integer | No | Only items marked down at least this much against RRP. |
| `onlyPurchasable` | Boolean | No | Skip items that cannot be bought. Default `true`. |
| `algoliaAppId` | String | No | Override, only needed if Yoox changes its public search application. |
| `algoliaApiKey` | String | No | Override, only needed if Yoox rotates its public search key. |
| `proxyConfiguration` | Object | No | Ignored on purpose. See "Why there is no proxy" below. |

### Output

| Field | Type | Example |
|-------|------|---------|
| `name` | String | `"GUCCI Mules & Clogs"` |
| `brand` | String | `"GUCCI"` |
| `currentPrice` | Number | `873` |
| `retailPrice` | Number | `1490` |
| `retailPriceSource` | String | `"Supplier"` |
| `retailPriceDate` | String | `"2025-09-03"` |
| `retailPriceTrusted` | Boolean | `true` |
| `markdownPercentage` | Number | `41.41` |
| `fullPrice` | Number | `1028` |
| `currency` | String | `"EUR"` |
| `sizes` | Array | `["36.5","37","37.5","38"]` |
| `sizeSystem` | String | `"Footwear"` |
| `inStock` | Boolean | `true` |
| `category` | String | `"Mules & Clogs"` |
| `categoryGroup` | String | `"FOOTWEAR"` |
| `gender` | String | `"Woman"` |
| `colour` | String | `"Black"` |
| `colourHex` | String | `"#000000"` |
| `material` | String | `"Leather"` |
| `composition` | String | `"Leather"` |
| `description` | String | `"mules, glossed-leather, plain colour, ..."` |
| `imageUrl` | String | Primary gallery shot |
| `imageUrls` | Array | All gallery shots |
| `url` | String | Yoox product page for the selected market |
| `yooxCode` | String | `"32047896TE"` |
| `modelId` | String | `"32047896"` |
| `preowned` | Boolean | `false` |
| `seasonality` | String | `"Mid-season"` |
| `departments` | Array | `["Women","ShoesWomen", ...]` |
| `market` | String | `"BE"` |
| `scrapedAt` | String | ISO 8601 timestamp |

`price` and `originalPrice` are also present as aliases of `currentPrice` and `retailPrice`, so the dataset drops straight into tooling built for a standard product feed.

### Example output

```json
{
    "name": "GUCCI Mules & Clogs",
    "brand": "GUCCI",
    "price": 873,
    "currency": "EUR",
    "url": "https://www.yoox.com/be/32047896TE/item",
    "scrapedAt": "2026-07-29T08:21:14.708Z",
    "currentPrice": 873,
    "retailPrice": 1490,
    "originalPrice": 1490,
    "retailPriceSource": "Supplier",
    "retailPriceDate": "2025-09-03",
    "retailPriceTrusted": true,
    "markdownPercentage": 41.41,
    "discount": "-41%",
    "fullPrice": 1028,
    "markdownPercentageFromFullPrice": 15.08,
    "sizes": ["36.5", "37", "37.5", "38", "38.5", "39", "40", "41"],
    "sizeSystem": "Footwear",
    "inStock": true,
    "category": "Mules & Clogs",
    "categoryGroup": "FOOTWEAR",
    "categories": ["FOOTWEAR", "Mules & Clogs"],
    "gender": "Woman",
    "colour": "Black",
    "colourHex": "#000000",
    "material": "Leather",
    "composition": "Leather",
    "description": "mules, glossed-leather, plain colour, brand logo, buckle fastening, pointed toe, wedge, leather sole, leather lining",
    "imageUrl": "https://cdn.yoox.biz/32/32047896te_11_f.jpg",
    "imageUrls": [
        "https://cdn.yoox.biz/32/32047896te_11_f.jpg",
        "https://cdn.yoox.biz/32/32047896te_11_d.jpg",
        "https://cdn.yoox.biz/32/32047896te_11_e.jpg",
        "https://cdn.yoox.biz/32/32047896te_11_r.jpg"
    ],
    "yooxCode": "32047896TE",
    "modelId": "32047896",
    "preowned": false,
    "seasonality": "Mid-season",
    "market": "BE",
    "searchQuery": "gucci"
}
```

### Read this before matching Yoox against another retailer

`yooxCode` (and `modelId`) look exactly like a manufacturer style code and are not one. They are YNAP-assigned identifiers. The per-size GTINs Yoox shows on its product pages have the same problem: they all start `04996`, which is a YNAP prefix rather than the brand's.

So neither is usable as a cross-retailer join key. They are stable and useful *inside* Yoox, and nowhere else. To match a Yoox item against Farfetch, Net-a-Porter or a brand's own site, join on brand plus normalised model plus colour, or use Farfetch's `brandStyleId` or Net-a-Porter's `mfPartNumber` as the spine and attach Yoox to it.

This gets misunderstood often enough that it is worth stating plainly: do not build a product-matching scheme on `yooxCode`.

### Why there is no proxy

The `proxyConfiguration` input exists for Apify Store compatibility and is deliberately ignored.

Yoox's website sits behind Akamai, but its product catalogue is served by a public search index on a different host that has no bot protection in front of it. Direct requests work, and they work better than proxied ones: Belgian residential exits get HTTP 403 from Yoox where a direct connection succeeds, because those IP ranges are already badly scored.

Turning on a residential proxy here would make the actor slower, more expensive and less reliable. So it does not use one.

### Markets

Belgium, Luxembourg, the Netherlands, France and Germany. Assortment and ranking differ per market, so these are five genuinely different catalogues rather than five views of one. The French catalogue is roughly three times the size of the Belgian one.

All five price in EUR.

Great Britain, Austria, Switzerland and Poland are reachable and may be added later. They are left out for now because their product-URL path segment has not been confirmed, and a guessed segment would produce dead links.

### Depth: this actor is index-only

Every product comes from Yoox's own catalogue search index. There is one request per page of up to 1,000 products and no per-product page fetch, which is why a run costs almost nothing and finishes in seconds.

That also sets the ceiling on what it can return. Fields the catalogue index carries — price, retail price, sizes in stock, colour, composition, images, category — are complete. Fields that only exist on the product page, such as per-size GTINs, are not available at any depth here. There is no crawl mode that would fetch them.

### Limitations

- **Outlet prices, by definition.** Everything on Yoox is off-season stock. `currentPrice` is an outlet price. Always read it next to `retailPrice`.
- **No free-text product title.** Yoox does not publish one. `name` is composed from brand plus micro-category, which is what its own product cards show.
- **Sizes are availability, not a full ladder.** The catalogue lists only sizes that can currently be bought, so every entry in `sizes` is in stock and an empty array means sold out. Sizes that were never stocked do not appear.
- **No per-size GTINs.** Those live on the product page rather than in the catalogue, and as explained above they are YNAP-assigned anyway.
- **20,000 results per query.** The catalogue caps how deep any single query can page. Narrow with brand, department or a price range to get past it.
- **The search key can rotate.** Yoox's public search key is stable but not permanent. If a run fails with HTTP 401 or 403, the log tells you exactly where to read the new one, and you pass it as `algoliaApiKey`.

### Cost

A run costs almost nothing to execute: 3,000 products come back in about 3 seconds, using three requests and no proxy traffic. You pay the per-result price, not a compute or proxy bill.

### Related scrapers

- [Net-a-Porter Scraper](https://apify.com/studio-amba/net-a-porter-scraper) -- Same YNAP group, full-price luxury
- [Mytheresa Scraper](https://apify.com/studio-amba/mytheresa-scraper) -- German luxury retailer, designer fashion
- [Vinted Scraper](https://apify.com/studio-amba/vinted-scraper) -- European second-hand fashion marketplace
- [Otto Scraper](https://apify.com/studio-amba/otto-scraper) -- Large German general retailer
- [Bol Scraper](https://apify.com/studio-amba/bol-scraper) -- Benelux marketplace

### Legal

This actor reads publicly available catalogue data. It does not log in, does not bypass any access control, and does not collect personal data. You are responsible for how you use the output, including compliance with Yoox's terms and with applicable copyright and database rights.

# Actor input Schema

## `searchQuery` (type: `string`):

A single keyword search, e.g. 'gucci bag', 'alexander mcqueen', 'sneakers'. Leave empty to browse the whole catalogue for the selected market.

## `searchQueries` (type: `array`):

Run several keyword searches in one go. Takes precedence over the single Search query field. Results are de-duplicated on the Yoox product code.

## `market` (type: `string`):

Which Yoox market to read. Each market is a separate catalogue with its own assortment and ranking, not a currency switch. Prices are EUR in all five.

## `maxItems` (type: `integer`):

Maximum number of products to return across all queries. Yoox's index caps any single query at 20,000 retrievable results — narrow with brand, department or price filters to go beyond that.

## `brand` (type: `string`):

Filter by brand, in plain language ('gucci', 'prada', 'dolce\&gabbana'). The actor resolves it against the index's own brand list, so you don't need Yoox's internal brand codes. Ignored if no brand matches.

## `gender` (type: `string`):

Restrict to the women's or men's catalogue. Matched on the product's own gender attribute rather than Yoox's department tags, because some brands carry no department tag at all. Unisex items are returned for both.

## `department` (type: `string`):

Yoox department code for a finer category filter, e.g. 'ShoesWomen', 'ClothingMen'. Read the exact codes off the 'departments' field of any scraped item. Note that department tagging is incomplete on some brands, so a department filter can return fewer items than you expect. Use the Gender field for gender, not a department.

## `minPrice` (type: `integer`):

Only return products whose current outlet price is at least this amount.

## `maxPrice` (type: `integer`):

Only return products whose current outlet price is at most this amount.

## `minDiscountPercent` (type: `integer`):

Only return products discounted at least this much against the supplier-stated RRP (markdownPercentage). Applied after fetching, because Yoox's index does not allow numeric filtering on the markdown field.

## `onlyPurchasable` (type: `boolean`):

Skip products that are in the index but cannot currently be bought. Leave on unless you specifically want sold-out records.

## `algoliaAppId` (type: `string`):

Only needed if Yoox changes its public search application. Read props.pageProps.algolia.app from the **NEXT\_DATA** script tag on any Yoox catalogue page.

## `algoliaApiKey` (type: `string`):

Only needed if Yoox rotates its public search-only key and the run fails with HTTP 401. Read props.pageProps.algolia.key from the **NEXT\_DATA** script tag on any Yoox catalogue page.

## `proxyConfiguration` (type: `object`):

Deliberately ignored. Yoox's catalogue index is queried directly and residential exits are counter-productive here (they get 403 from Yoox and cost money for nothing), so the default is proxy off. Kept for Apify Store compatibility.

## Actor input object example

```json
{
  "searchQuery": "gucci",
  "market": "BE",
  "maxItems": 20,
  "gender": "any",
  "onlyPurchasable": true,
  "proxyConfiguration": {
    "useApifyProxy": false,
    "apifyProxyGroups": [
      "DATACENTER"
    ]
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "gucci",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false,
        "apifyProxyGroups": [
            "DATACENTER"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/yoox-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "gucci",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": False,
        "apifyProxyGroups": ["DATACENTER"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/yoox-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "gucci",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false,
    "apifyProxyGroups": [
      "DATACENTER"
    ]
  }
}' |
apify call studio-amba/yoox-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/yoox-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/N6o5t1omEyCb4Edm2/builds/GRwidZDd6XFLENmdr/openapi.json
