# 24S Scraper $1💰 Luxury Fashion Products + Prices (`abotapi/24s-com-scraper`) Actor

Scrape 24S luxury fashion for women and men. Get brand, name, price and discount, currency, per-size stock, colors, image gallery, description, composition and made-in. Search by category with brand, color, size, price and sale filters, or paste any 24S category or product URL.

- **URL**: https://apify.com/abotapi/24s-com-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product 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

## 24S Scraper

Scrape the full 24S luxury fashion catalog and product details for women and men. Search by category with brand, color, size, price, and sale filters, or paste any 24S category or product link. Every record carries the brand, name, price and discount, currency, the complete size list with per-size stock, color variants, the image gallery, and (optionally) the full description, composition, made-in, and product code.

### Why this scraper

- 90+ data points per product, including per-size stock and color variants most catalog scrapers miss
- Two ways to collect: search by category with filters, or paste category and product URLs
- Brand, color, size, price-range, minimum-discount, and sort filters
- Was-price, savings amount, discount %, and a "specials only" toggle on every result
- Optional product-detail enrichment: description, bullet points, composition, made-in country, product code, and full image gallery
- Works across 24S markets (en-gb, en-us, en-au, fr-fr, and more), with the connection country matched to the market automatically
- Clean image URLs ready to download, and a direct product URL on every record

### Data you get

> Sample shape, values are illustrative placeholders, not from a live listing.

| Field | Example |
|---|---|
| id | `BRDXXX0XBCK` |
| brand | `Sample Brand` |
| name | `Leather ankle boots` |
| price | `790.0` |
| discountPrice | `553.0` |
| currentPrice | `553.0` |
| discountPercentage | `30` |
| currency | `EUR` |
| color | `Black` |
| inStock | `true` |
| onSale | `true` |
| title | `Sample Brand Leather ankle boots` |
| isOnSpecial | `true` |
| wasPrice | `790.0` |
| savingsAmount | `237.0` |
| discountPercent | `30` |
| promoEventName | `tbm_sales` |
| discountStartDate | `2026-01-15T09:00:00+00:00` |
| discountEndDate | `2026-02-15T00:00:00+00:00` |
| sizes | `[{"label":"FR 38","sku":"BRDXXX0XBCK...","inStock":true}]` |
| otherColors | `[{"label":"Beige","shortSku":"BRDXXX0XBEI","image":"https://www.24s.com/static/images/unsafe/fit-in/1024x1280/00000000000000000000000000000000"}]` |
| images | `["https://www.24s.com/static/images/unsafe/fit-in/1024x1280/00000000000000000000000000000000"]` |
| imagesCount | `8` |
| description | `Full product description appears here when fetchDetails is on.` |
| bulletPoints | `["Round toe","Logo detail","Leather sole"]` |
| composition | `Calf leather` |
| madeIn | `IT` |
| productCode | `BRDXXX0XBCKO0AAA00` |
| year | `2024` |
| productSlug | `leather-ankle-boots-sample-brand` |
| url | `https://www.24s.com/en-gb/leather-ankle-boots-sample-brand_BRDXXX0XBCK` |
| locale | `en-gb` |

### How to use

Search a category, basic:

```json
{
  "mode": "search",
  "locale": "en-gb",
  "categories": ["women/shoes"],
  "maxItems": 50
}
```

Search with filters:

```json
{
  "mode": "search",
  "locale": "en-gb",
  "categories": ["women/shoes", "women/bags"],
  "brands": ["CHLOE", "LOEWE"],
  "colors": ["Black"],
  "minPrice": 300,
  "maxPrice": 1500,
  "sortBy": "price_asc",
  "fetchDetails": true,
  "maxItems": 100
}
```

Only discounted items:

```json
{
  "mode": "search",
  "locale": "en-gb",
  "categories": ["women/ready-to-wear"],
  "discounts": ["30"],
  "maxItems": 60
}
```

Only current specials:

```json
{
  "mode": "search",
  "locale": "en-gb",
  "categories": ["women/shoes"],
  "specialsOnly": true,
  "maxItems": 60
}
```

Paste URLs (categories and products mixed):

```json
{
  "mode": "url",
  "urls": [
    "https://www.24s.com/en-gb/women/shoes",
    "https://www.24s.com/en-gb/men/bags",
    "https://www.24s.com/en-gb/leather-ankle-boots-sample-brand_BRDXXX0XBCK"
  ],
  "maxItems": 200
}
```

### Specials, was-price & discount

24S has **no separate sale / private-sale / outlet category or collection** — `/sale`, `/private-sale`,
`/soldes`, `/outlet` and similar paths all return 404 on the site's own data route (verified live). Its
only specials surface is the discount-percentage bucket facet already used by the `discounts` filter
above. `specialsOnly` is a convenience toggle over that same facet: since a single bucket is not
cumulative (e.g. `discounts=20` misses items discounted 30% or more — verified live), turning it on
checks every bucket (`20/30/40/50`) at once, unless you already picked specific buckets yourself.

Every result also carries `isOnSpecial`, `wasPrice`, `savingsAmount`, `discountPercent`, `promoEventName`,
`discountStartDate`, and `discountEndDate` — all read straight from the same catalog data 24S already
returns for that product (no extra request), and all `null`/`false` on full-price items. `wasPrice` and
`discountPercent` restate `price`/`discountPercentage` under the field names used across this line of
scrapers; the pre-existing `price`, `discountPrice`, `currentPrice`, `discountPercentage`, `onSale` fields
are unchanged.

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | `search` | `search` (category + filters) or `url` (paste links) |
| locale | string | `en-gb` | Market as lang-country, e.g. en-gb, en-us, en-au, fr-fr |
| categories | array | `["women/shoes"]` | Category paths, universe/category\[/subcategory] (search mode) |
| brands | array | empty | Exact brand names, e.g. `CHLOE`, `LOEWE` |
| colors | array | empty | Color names, e.g. `Black`, `Beige` |
| sizes | array | empty | Sizes in 24S notation, e.g. `FR 38` |
| minPrice | integer | empty | Minimum price in the locale's currency (whole units) |
| maxPrice | integer | empty | Maximum price in the locale's currency (whole units) |
| discounts | array | empty | Minimum discount buckets: 20, 30, 40, 50 |
| specialsOnly | boolean | `false` | Show only items currently on sale (checks every discount bucket) |
| sortBy | string | `relevance` | `relevance`, `price_asc`, `price_desc`, `newest` |
| urls | array | empty | Category or product URLs (url mode) |
| fetchDetails | boolean | `false` | Add full detail page fields to every product |
| maxItems | integer | `20` | Max products across all categories/URLs; 0 for unlimited |
| maxPages | integer | empty | Optional page cap per category (72 products per page); empty means no page limit, the run stops at Max products |
| resumeFromRunId | string | empty | Continue ONE interrupted run/dataset without re-collecting or re-charging its products |
| incrementalMode | boolean | `false` | Recurring monitoring of the same search: later runs return only NEW/UPDATED/REAPPEARED products |
| stateKey | string | empty | Optional name for an incremental-mode monitoring campaign; auto-derived from locale/categories/URLs/filters when empty |
| emitUnchanged | boolean | `false` | Incremental mode only: also return (and bill for) products unchanged since the last run |
| emitExpired | boolean | `false` | Incremental mode only: also return (and bill for) products no longer found, once a run fully scans the tracked search |
| proxy | object | Residential | Connection settings; the country follows the locale |

### Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the `mcpConnectors` field. Each connector receives a condensed, human-readable summary per product (title plus key fields), while the complete record always stays in the Apify dataset. For Notion, set `notionParentPageUrl` to the page the item pages should be created under. Supported connectors: Notion, Linear, Airtable, and Apify. Leave the field empty to skip; it never changes the dataset output.

### Output example

> Sample shape, values are illustrative placeholders, not from a live listing.

```json
{
  "id": "BRDXXX0XBCK",
  "brand": "Sample Brand",
  "name": "Leather ankle boots",
  "title": "Sample Brand Leather ankle boots",
  "color": "Black",
  "price": 790.0,
  "discountPrice": 553.0,
  "currentPrice": 553.0,
  "discountPercentage": 30,
  "currency": "EUR",
  "onSale": true,
  "isOnSpecial": true,
  "wasPrice": 790.0,
  "savingsAmount": 237.0,
  "discountPercent": 30,
  "promoEventName": "tbm_sales",
  "discountStartDate": "2026-01-15T09:00:00+00:00",
  "discountEndDate": "2026-02-15T00:00:00+00:00",
  "inStock": true,
  "stockLevel": 1,
  "sizes": [
    { "label": "FR 38", "sku": "BRDXXX0XBCKO0AAA00", "inStock": true },
    { "label": "FR 39", "sku": "BRDXXX0XBCKO1AAA00", "inStock": false }
  ],
  "otherColors": [
    { "label": "Beige", "shortSku": "BRDXXX0XBEI", "image": "https://www.24s.com/static/images/unsafe/fit-in/1024x1280/00000000000000000000000000000000" }
  ],
  "images": [
    "https://www.24s.com/static/images/unsafe/fit-in/1024x1280/00000000000000000000000000000000"
  ],
  "imagesCount": 8,
  "description": "Full product description appears here when fetchDetails is on.",
  "bulletPoints": ["Round toe", "Logo detail", "Leather sole"],
  "composition": "Calf leather",
  "madeIn": "IT",
  "productCode": "BRDXXX0XBCKO0AAA00",
  "year": 2024,
  "productSlug": "leather-ankle-boots-sample-brand",
  "url": "https://www.24s.com/en-gb/leather-ankle-boots-sample-brand_BRDXXX0XBCK",
  "locale": "en-gb",
  "detailFetched": true
}
```

### Plan requirement

This actor runs on any Apify plan, including the free tier.

# Actor input Schema

## `mode` (type: `string`):

How to find products to scrape. 'search' builds catalog pages from categories + filters; 'url' scrapes category or product page links you paste.

## `locale` (type: `string`):

24S market in the form lang-country, e.g. en-gb, en-us, en-au, en-hk, en-sg, fr-fr, de-de, it-it, es-es. The proxy exit country is matched to this automatically. Category names must be in the locale's language (en-\* uses women/men, shoes, bags, ready-to-wear).

## `categories` (type: `array`):

Category paths to scrape (search mode). Format universe/category\[/subcategory], e.g. 'women/shoes', 'men/bags', 'women/ready-to-wear', 'women/shoes/sandals'.

## `brands` (type: `array`):

Filter by brand. Use the exact brand name as shown on 24S, e.g. 'CHLOE', 'LOEWE', 'BOTTEGA VENETA', 'LOUIS VUITTON', 'CELINE'. Leave empty for all brands.

## `colors` (type: `array`):

Filter by color, e.g. 'Black', 'Beige', 'Brown', 'Blue'. Leave empty for all colors.

## `sizes` (type: `array`):

Filter by size in 24S 'FR NN' notation, e.g. 'FR 38' (shoes) or 'FR 36' (clothing). Leave empty for all sizes.

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

Minimum price in the locale's currency (whole units). Leave empty for no minimum.

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

Maximum price in the locale's currency (whole units). Leave empty for no maximum.

## `discounts` (type: `array`):

Show only discounted items at or above these discount buckets. Valid values: 20, 30, 40, 50. Leave empty to include full-price items.

## `specialsOnly` (type: `boolean`):

Show only items currently on sale. 24S has no separate sale/outlet category or collection (verified: does not exist as a page); this checks every discount bucket at once. Ignored if you already picked specific buckets above.

## `sortBy` (type: `string`):

Result ordering (search mode).

## `urls` (type: `array`):

24S category or product page URLs to scrape (url mode). Category URLs paginate forward; product URLs are fetched as single detail records. Filter fields are ignored in this mode (use the filters already in the pasted URL).

## `fetchDetails` (type: `boolean`):

Add the full product-detail fields to every result: long description, bullet points, composition, made-in, product code and the complete image gallery. Adds one request per product.

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

Maximum number of products to scrape across all categories/URLs. Set 0 for unlimited.

## `maxPages` (type: `integer`):

Optional safety cap on pages walked per category/URL (72 products per page). Leave empty for no page limit; the run stops at Max products.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large crawl of products without returning or charging for products already collected there. Use this after an interrupted run, or when continuing a product catalogue pull in another run. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately for each locale/category/URL and filter/detail-mode setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the locale/category/URL and filter settings — different searches then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max products capped it or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.

## `proxy` (type: `object`):

24S serves each market only to connections from that country. Residential proxy pinned to the locale's country is recommended and selected by default; the exit country follows the locale automatically.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "locale": "en-gb",
  "categories": [
    "women/shoes"
  ],
  "specialsOnly": false,
  "sortBy": "relevance",
  "urls": [
    "https://www.24s.com/en-gb/women/shoes"
  ],
  "fetchDetails": false,
  "maxItems": 20,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "categories": [
        "women/shoes"
    ],
    "urls": [
        "https://www.24s.com/en-gb/women/shoes"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/24s-com-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 = {
    "mode": "search",
    "categories": ["women/shoes"],
    "urls": ["https://www.24s.com/en-gb/women/shoes"],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/24s-com-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 '{
  "mode": "search",
  "categories": [
    "women/shoes"
  ],
  "urls": [
    "https://www.24s.com/en-gb/women/shoes"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call abotapi/24s-com-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/l5dZQog97tkuswtWw/builds/EbAxi5SkTj4GdBQqx/openapi.json
