# Sephora Product Scraper (Global) (`autofacts/sephora`) Actor

Scrape Sephora products across 20 storefronts (US, Canada, 9 EU markets, 10 APAC countries) through one unified Python actor. Extract prices, variants, ratings, and catalog details via official mobile APIs with TLS fingerprint impersonation, OAuth2/guest-token auth, and per-market session isolation.

- **URL**: https://apify.com/autofacts/sephora.md
- **Developed by:** [Richard Feng](https://apify.com/autofacts) (community)
- **Categories:** Developer tools, E-commerce, Social media
- **Stats:** 353 total users, 12 monthly users, 100.0% runs succeeded, 14 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $4.50 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Sephora Product Scraper (Global)

### What does Sephora Scraper do?

**Sephora Scraper** extracts complete product data — every variant, every price, every image, every review — from **28 Sephora storefronts** across the US, Canada, 9 EU markets, 6 MENA markets, the UK, India, and 10 Asia-Pacific markets. Paste any `sephora.*` product or category URL and the actor auto-detects the market, fetches the data, and returns a normalized JSON record that's identical in shape across every region.

The same run can span multiple markets. Mix `sephora.com`, `sephora.fr`, and `sephora.nz` URLs in one `startUrls` list; the dispatcher groups them by market, runs each module concurrently with market-appropriate headers and auth, and streams everything to a single dataset tagged with a `market` field.

### Why use Sephora Scraper?

- **28 storefronts, one SKU.** One actor covers US + Canada + 9 EU + 6 MENA + UK + IN + 10 APAC. No juggling multiple scrapers.
- **Fast, structured fetches.** No browser automation, no HTML scraping. Expect seconds per product, not minutes.
- **Locale-correct pricing.** NZD for New Zealand, EUR for France, USD for US — returned by Sephora's own localization layer, not guessed.
- **Normalized schema.** Every market emits the same top-level shape: `source / brand / title / options / variants / medias / stats`. Drop-in compatible with v1.x US dataset consumers.
- **Production-tested.** Built on top of the `autofacts/sephora` US scraper that's been running continuously since 2025. EU and SEA ports were translated directly from the `sephora-eu-scraper` and `sephora-nz-scraper` standalone actors.

### How to use Sephora Scraper

1. In the **Input** tab, paste any Sephora product or category URL(s) into **Sephora start URLs** — from any country.
2. (Optional) Set **Max requests per crawl** to cap the run (applies to all markets).
3. (Optional) Override the auto-detected market with the **Market override** field if you're passing bare IDs instead of URLs.
4. Click **Start** and download the results from the **Dataset** tab (JSON, CSV, XLSX, HTML).

No API keys, no tokens, no proxy account required for EU/SEA. US runs perform best with a residential-proxy Apify plan.

### Input

| Field | Description |
|---|---|
| `startUrls` | Product or category URLs from any `sephora.*` storefront. Required. |
| `market` | Optional market override. Values: `us`, `eu-fr`, `eu-it`, `eu-de`, `eu-es`, `eu-pl`, `eu-ro`, `eu-pt`, `eu-cz`, `eu-gr`, `mena-ae`, `mena-sa`, `mena-bh`, `mena-om`, `mena-kw`, `mena-qa`, `uk`, `in`, `sea-nz`, `sea-au`, `sea-sg`, `sea-my`, `sea-th`, `sea-id`, `sea-ph`, `sea-hk`, `sea-tw`, `sea-bn`. Leave blank to auto-detect from URLs. |
| `locale` | Optional BCP 47 locale (e.g. `fr-FR`, `en-NZ`). Overrides the market's default. |
| `categoryIds` | EU-only. SFCC category IDs like `C479`. Alternative to pasting category URLs. |
| `proxy` | Proxy configuration. Residential strongly recommended; set `apifyProxyCountry` to match the target market (e.g. `FR` for `sephora.fr`, `NZ` for `sephora.nz`) — see Tips. |
| `maxConcurrency` | Concurrent requests. Default `5`. |
| `maxRequestsPerCrawl` | Global hard cap on total Crawlee requests across every active market (includes listing, search, detail). `0` = unlimited. |

### Supported markets

| Region | Market ID | Country | Locale | Currency | Hostname |
|---|---|---|---|---|---|
| Americas | `us` | United States | `en-US` | USD | sephora.com |
| Americas | `us` | Canada | `en-CA` / `fr-CA` | CAD | sephora.ca |
| EU | `eu-fr` | France | fr-FR | EUR | sephora.fr |
| EU | `eu-it` | Italy | it-IT | EUR | sephora.it |
| EU | `eu-de` | Germany | de-DE | EUR | sephora.de |
| EU | `eu-es` | Spain | es-ES | EUR | sephora.es |
| EU | `eu-pl` | Poland | pl-PL | PLN | sephora.pl |
| EU | `eu-cz` | Czech Republic | cs-CZ | CZK | sephora.cz |
| EU | `eu-gr` | Greece | el-GR | EUR | sephora.gr |
| EU | `eu-ro` | Romania | ro-RO | RON | sephora.ro |
| EU | `eu-pt` | Portugal | pt-PT | EUR | sephora.pt |
| MENA | `mena-ae` | United Arab Emirates | en-AE | AED | sephora.ae |
| MENA | `mena-sa` | Saudi Arabia | en-SA | SAR | sephora.sa |
| MENA | `mena-bh` | Bahrain | en-BH | BHD | sephora.bh |
| MENA | `mena-om` | Oman | en-OM | OMR | sephora.om |
| MENA | `mena-kw` | Kuwait | en-KW | KWD | sephora.kw |
| MENA | `mena-qa` | Qatar | en-QA | QAR | sephora.qa |
| UK | `uk` | United Kingdom | en-GB | GBP | sephora.co.uk |
| India | `in` | India | en-IN | INR | sephora.in |
| APAC | `sea-nz` | New Zealand | en-NZ | NZD | sephora.nz |
| APAC | `sea-au` | Australia | en-AU | AUD | sephora.com.au |
| APAC | `sea-sg` | Singapore | en-SG | SGD | sephora.sg |
| APAC | `sea-my` | Malaysia | en-MY | MYR | sephora.com.my |
| APAC | `sea-th` | Thailand | th-TH | THB | sephora.co.th |
| APAC | `sea-id` | Indonesia | id-ID | IDR | sephora.co.id |
| APAC | `sea-ph` | Philippines | en-PH | PHP | sephora.ph |
| APAC | `sea-hk` | Hong Kong | zh-HK | HKD | sephora.hk |
| APAC | `sea-tw` | Taiwan | zh-TW | TWD | sephora.tw |
| APAC | `sea-bn` | Brunei | en-BN | BND | sephora.bn |

### Output

Each dataset item follows the schema in `.actor/dataset_schema.json`. Example (NZ):

```json
{
    "market": "sea-nz",
    "source": {
        "id": 58792,
        "crawlUrl": null,
        "canonicalUrl": "https://www.sephora.nz/products/rare-beauty-true-to-myself-natural-matte-longwear-foundation",
        "retailer": "SEPHORA",
        "currency": "NZD"
    },
    "brand": "Rare Beauty",
    "title": "True To Myself Natural Matte Longwear Foundation",
    "description": "<p>A self-priming and self-setting foundation...</p>",
    "shortDescription": "<p>3-in-1 foundation primes, covers and sets...</p>",
    "ingredients": "Aqua/Water, Cyclopentasiloxane, Glycerin, Phenyl Trimethicone...",
    "howToUse": "<p>Shake well. Apply a small amount onto the back of your hand and use a brush or fingertips to blend onto skin.</p>",
    "currentSku": "770225",
    "categories": ["makeup/face/foundation"],
    "options": [
        { "name": "shade", "id": "66488", "values": [{"value": "1 Fair Neutral", "label": "1 Fair Neutral", "orderable": true}] }
    ],
    "variants": [
        {
            "id": "276343",
            "sku": "770225",
            "price": { "current": 77.0, "original": 77.0, "stockStatus": "IN_STOCK" },
            "options": [{"name": "shade", "value": "1 Fair Neutral"}],
            "highlights": ["NEW", "Only at Sephora"],
            "wishlisted": null
        }
    ],
    "medias": [{"url": "https://www.sephora.nz/.../foundation-shade.jpg", "type": "image"}],
    "stats": { "reviewCount": 971, "rating": 4.8, "lovesCount": null },
    "sentiments": null
}
````

Download as JSON, CSV, XLSX, or HTML from the **Dataset** tab.

### Data fields

| Field | Type | US | EU | SEA | Notes |
|---|---|---|---|---|---|
| `market` | string | ✓ | ✓ | ✓ | Market identifier stamped by dispatcher |
| `source.id` | number/string | ✓ | ✓ | ✓ | US: string `P123`; EU/SEA: numeric |
| `source.crawlUrl` | string | ✓ | — | — | US-only |
| `source.canonicalUrl` | string | ✓ | ✓ | ✓ | |
| `source.currency` | string | ✓ | ✓ | ✓ | Per-market currency |
| `description` | string (HTML) | ✓ | ✓ | ✓ | Full product description |
| `shortDescription` | string (HTML) | ✓ | ✓ | ✓ | Short description / benefits |
| `ingredients` | string | ✓ | ✓ | ✓ | Full ingredient list. Empty for non-cosmetic SKUs |
| `howToUse` | string (HTML) | ✓ | ✓ | ✓ | Usage / application instructions |
| `currentSku` | string | ✓ | ✓ | ✓ | Storefront-default SKU; matches one of `variants[].id` |
| `variants[].price.current` | number | ✓ | ✓ | ✓ | Local currency |
| `variants[].price.stockStatus` | enum | ✓ | ✓ | ✓ | `IN_STOCK` / `OUT_OF_STOCK` / `UNKNOWN` |
| `variants[].wishlisted` | boolean | — | — | ✓ | SEA-only |
| `stats.reviewCount` / `rating` | number | ✓ | ✓ | ✓ | |
| `stats.lovesCount` | number | ✓ | ✓ | — | SEA does not expose loves; see `wishlisted` instead |
| `sentiments` | object | ✓ | — | — | US-only AI review summaries |

### Tips / advanced options

- **Pin the proxy country to the target market.** A residential exit in a mismatched country (e.g. a US IP hitting `sephora.fr`) is the single largest source of 403s from Sephora's Akamai layer. Set `apifyProxyCountry` to the storefront's country: `US` / `CA` for US, `FR`/`IT`/`DE`/`ES`/`PL`/`RO` for EU (`PT` routes through `ES`, `CZ` through `PL`, `GR` through `RO`), and the matching ISO code for each APAC country (`NZ`, `AU`, `SG`, `MY`, `TH`, `ID`, `PH`, `HK`, `TW`, `BN`). Unpinned residential works but expect a noticeably lower success rate.
- **US** — set `maxConcurrency` between 2 and 5. Sephora US is aggressive about rate-limiting; higher concurrency increases 403 rates, not throughput.
- **EU** — `maxConcurrency=3` is the sweet spot. Higher concurrency triggers extra session-refresh churn with no throughput gain.
- **SEA** — `maxConcurrency=16` finishes a full-market catalog scrape in a few minutes.
- **Mixed runs** — concurrency is enforced per-market (each market gets its own semaphore), so a mixed run at concurrency=5 doesn't blast any one storefront.
- **Smoke test first** — set `maxRequestsPerCrawl=10` before your first production run in a new market.

### FAQ

**Will my existing US run configs keep working?** Yes. Pre-2.0 inputs — `startUrls`, `maxConcurrency`, `proxy`, `maxRequestsPerCrawl` — behave identically. The only output change is a new `market` key on every item, which is a soft addition (not a breaking change).

**Do I need a new API token?** No. Your existing Apify API token works unchanged.

**What's the `market` field in the output?** The dispatcher's auto-detected country/region tag. Useful for filtering when a single run scrapes multiple storefronts. Values match the table under **Supported markets**.

**Why does `stats.lovesCount` show null for NZ/AU/etc.?** Sephora SEA (the API that backs NZ/AU/SG/MY/TH/ID/PH/HK/TW/BN) doesn't expose a loves counter. Each variant has a boolean `wishlisted` field instead — use it if you need the SEA equivalent.

**How do I scrape only a specific market?** Paste only URLs from that market's hostname, OR set the `market` input field explicitly (e.g. `eu-fr`).

**Why do I see `sephora-scraper.internal/...` URLs in the Run's Request Queue tab?** Those are **internal tracking identifiers**, not the URLs the actor fetches. The actor resolves them at the moment of request and the resolved form is never written to the Console, logs, or the dataset. Your actual scrape targets the public Sephora stores you requested in `startUrls`.

**Will re-running with the same input re-scrape everything?** Yes. Each run starts with a fresh Request Queue (the default Apify queue, purged per run), so hitting Run twice will re-scrape every URL. If you need resume-on-rerun semantics for very long crawls, split the input into smaller batches.

**Why did my run abort with "circuit breaker tripped"?** Every 50 consecutive failed requests trigger an early abort — this protects you from burning compute when the target is entirely down. Check Sephora's availability, then re-run. Normal transient errors (429s, 5xxs on individual products) don't trip the breaker because they're mixed with successes.

**Legality / Terms of Service.** Scraping is a gray area that depends on jurisdiction and intended use. Review Sephora's ToS and consult counsel before running at scale. This actor is provided as-is for research, compliance, competitive monitoring, and other lawful use cases.

### Support

Issues and feature requests: open an issue on the Apify listing or email the autofacts team. For custom-scope requests (historical backfills, loyalty data, sub-brand catalogs), contact us directly.

# Actor input Schema

## `startUrls` (type: `array`):

Product or category URLs from any Sephora storefront. The market is auto-detected from the hostname (e.g. sephora.com → US, sephora.fr → EU-FR, sephora.nz → SEA-NZ).

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

Force a specific market module. Leave blank to auto-detect from startUrls hostname. Values: us, eu-fr, eu-it, eu-de, eu-es, eu-pl, eu-ro, eu-pt, eu-cz, eu-gr, mena-ae, mena-sa, mena-bh, mena-om, mena-kw, mena-qa, uk, in, sea-nz, sea-au, sea-sg, sea-my, sea-th, sea-id, sea-ph, sea-hk, sea-tw, sea-bn.

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

BCP 47 locale tag (e.g. en-US, fr-FR, en-NZ). Overrides the default locale for the detected market. Leave blank to use the market default.

## `categoryIds` (type: `array`):

EU-only. SFCC category IDs like "C479" (body oils). Alternative to pasting category URLs in startUrls.

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

Select proxies to be used by your crawler. Defaults to Apify RESIDENTIAL — datacenter IPs are blocked by Akamai on all Sephora storefronts (US, EU, SEA). Pin a country (e.g. FR for eu-fr, DE for eu-de) when scraping a single market to keep the exit geographically consistent with the storefront.

## `maxConcurrency` (type: `integer`):

Maximum concurrent requests. US: 2-5 recommended. EU: 3 recommended. SEA: 8-16 fine (API is permissive).

## `maxRequestsPerCrawl` (type: `integer`):

Hard cap on total Crawlee requests across every active market (includes listing, search, detail). 0 = unlimited. Applies uniformly to US, EU, and SEA.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.sephora.com/product/resistance-mask-for-severely-damaged-hair-P434434?skuId=2127413"
    }
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxConcurrency": 5,
  "maxRequestsPerCrawl": 0
}
```

# Actor output Schema

## `products` (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 = {
    "startUrls": [
        {
            "url": "https://www.sephora.com/product/resistance-mask-for-severely-damaged-hair-P434434?skuId=2127413"
        }
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    },
    "maxConcurrency": 5,
    "maxRequestsPerCrawl": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("autofacts/sephora").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 = {
    "startUrls": [{ "url": "https://www.sephora.com/product/resistance-mask-for-severely-damaged-hair-P434434?skuId=2127413" }],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
    "maxConcurrency": 5,
    "maxRequestsPerCrawl": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("autofacts/sephora").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 '{
  "startUrls": [
    {
      "url": "https://www.sephora.com/product/resistance-mask-for-severely-damaged-hair-P434434?skuId=2127413"
    }
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxConcurrency": 5,
  "maxRequestsPerCrawl": 0
}' |
apify call autofacts/sephora --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Sephora Product Scraper (Global)",
        "description": "Scrape Sephora products across 20 storefronts (US, Canada, 9 EU markets, 10 APAC countries) through one unified Python actor. Extract prices, variants, ratings, and catalog details via official mobile APIs with TLS fingerprint impersonation, OAuth2/guest-token auth, and per-market session isolation.",
        "version": "2.0",
        "x-build-id": "HYhcvaOVa45Ml2lxN"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/autofacts~sephora/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-autofacts-sephora",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/autofacts~sephora/runs": {
            "post": {
                "operationId": "runs-sync-autofacts-sephora",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/autofacts~sephora/run-sync": {
            "post": {
                "operationId": "run-sync-autofacts-sephora",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Sephora start URLs",
                        "type": "array",
                        "description": "Product or category URLs from any Sephora storefront. The market is auto-detected from the hostname (e.g. sephora.com → US, sephora.fr → EU-FR, sephora.nz → SEA-NZ).",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "market": {
                        "title": "Market override (optional)",
                        "type": "string",
                        "description": "Force a specific market module. Leave blank to auto-detect from startUrls hostname. Values: us, eu-fr, eu-it, eu-de, eu-es, eu-pl, eu-ro, eu-pt, eu-cz, eu-gr, mena-ae, mena-sa, mena-bh, mena-om, mena-kw, mena-qa, uk, in, sea-nz, sea-au, sea-sg, sea-my, sea-th, sea-id, sea-ph, sea-hk, sea-tw, sea-bn."
                    },
                    "locale": {
                        "title": "Locale override (optional)",
                        "type": "string",
                        "description": "BCP 47 locale tag (e.g. en-US, fr-FR, en-NZ). Overrides the default locale for the detected market. Leave blank to use the market default."
                    },
                    "categoryIds": {
                        "title": "EU category IDs (optional)",
                        "type": "array",
                        "description": "EU-only. SFCC category IDs like \"C479\" (body oils). Alternative to pasting category URLs in startUrls.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Select proxies to be used by your crawler. Defaults to Apify RESIDENTIAL — datacenter IPs are blocked by Akamai on all Sephora storefronts (US, EU, SEA). Pin a country (e.g. FR for eu-fr, DE for eu-de) when scraping a single market to keep the exit geographically consistent with the storefront.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum concurrent requests. US: 2-5 recommended. EU: 3 recommended. SEA: 8-16 fine (API is permissive).",
                        "default": 5
                    },
                    "maxRequestsPerCrawl": {
                        "title": "Max requests per crawl",
                        "minimum": 0,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Hard cap on total Crawlee requests across every active market (includes listing, search, detail). 0 = unlimited. Applies uniformly to US, EU, and SEA.",
                        "default": 0
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
