# Sephora Catalog Price & Rating Finder (`dataspryva/sephora-catalog-price-and-rating-finder`) Actor

Search Sephora's product catalog by keyword, bestsellers, or new arrivals, filtered by rating, brand, and price, with merchandising flags, review counts, and images for every matching product.

- **URL**: https://apify.com/dataspryva/sephora-catalog-price-and-rating-finder.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Sephora Catalog Price & Rating Finder

Sephora's beauty catalog changes constantly: new launches, rotating sale prices, shade and size variants, and thousands of reviews arriving every week. This actor turns that catalog into structured records for price tracking, assortment analysis, ingredient research and review intelligence. Search by keyword, browse categories or brands, or paste product URLs, then optionally add full product details, variants, stock, images, review samples, rating histograms and Q\&A. Works in the United States and Canada (English and French), with no login, cookie or proxy setup.

### What this actor does

- **Nine modes:** `search`, `category`, `brand`, `product`, `bestsellers`, `newArrivals`, `sale`, `reviews` and `questions`
- **Three storefronts:** US (USD), Canada English (CAD) and Canada French (CAD), with French product text for Quebec
- **Rich product detail:** descriptions, how-to-use, ingredients, highlights, brand copy, category path, variants/SKUs, stock, sale prices and full-size image links
- **Review intelligence:** review text, ratings, titles, verified/incentivized/staff badges, helpful votes, photos, reviewer demographics, rating histograms and GTIN/UPC/EAN identifiers
- **Q\&A export:** questions with their answers, authors, dates, brand-answer and best-answer flags
- **Server-side filters and six sort orders:** brand, category, rating, price, new, sale, advanced facet refinements, and relevance / best selling / top rated / price / newest ordering
- **Empty fields are omitted** from each record instead of being returned as null

### Output per product

- `productId`, `brandName`, `brandId`, `displayName`, `productName`, `skuId` — product identity
- `market`, `country`, `locale`, `currency` — storefront context
- `rating`, `reviews`, `lovesCount` — rating and engagement
- `price`, `priceMin`, `priceMax`, `priceText` — current price, or price range for multi-variant products
- `listPrice`, `listPriceMin`, `listPriceMax`, `salePrice`, `salePriceMin`, `salePriceMax`, `savingsAmount`, `savingsPercent` — original and discounted pricing
- `isNew`, `isBestseller`, `isSephoraExclusive`, `isLimitedEdition`, `isLimitedTimeOffer`, `isOnlineOnly`, `isOnSale`, `sponsored` — merchandising flags
- `inStock`, `outOfStockSkus`, `isReturnable`, `maxPurchaseQuantity` — stock and purchase limits
- `size`, `shade`, `variationType`, `variantsCount`, `variants[]` — size/shade matrix with per-variant price, sale price, stock, image and product URL
- `description`, `shortDescription`, `howToUse`, `ingredients`, `highlights[]` — product content
- `categoryPath[]`, `categoryId`, `categoryUrl`, `brandDescription`, `brandUrl`, `seoTitle`, `seoDescription` — taxonomy and brand context
- `images[]` with `url` (rehosted when available) and `originalUrl`; `imageOriginal`, `altImage`, `altImageOriginal`, `imageAltText`
- `reviewStats` with `ratingHistogram[]`, `averageRating`, `totalReviews`, recommendation counts, photo/video counts, review dates and vote totals
- `reviewSamples[]` — review samples with demographics and badges
- `questions[]`, `questionCount` — Q\&A embedded in product rows
- `gtins[]`, `upcs[]`, `eans[]` — product identifiers when available
- `sourceType`, `searchTerm`, `rank`, `page`, `searchUrl`, `categorySlug`, `brandSlug`, `sourceUrl`, `canonicalUrl` — where the record came from
- `pickupEligible`, `pickupNearbyEligible`, `sameDayEligible`, `nextDayEligible`, `shipToHomeEligible` — fulfillment flags
- `productUrl`, `recordType`, `scrapedAt`

### Output: per review (mode = `reviews`)

`reviewId`, `productId`, `productName`, `brandName`, `productUrl`, `market`, `country`, `locale`, `currency`, `rating`, `title`, `text`, `author`, `submittedAt`, `isRecommended`, `isVerifiedPurchase`, `isIncentivized`, `isStaff`, `helpfulVotes`, `notHelpfulVotes`, `photos[]`, `contentLocale`, `reviewer` (`skinType`, `skinTone`, `eyeColor`, `hairColor`, `ageRange`, `skinConcerns`), `recordType`, `scrapedAt`.

### Output: per question (mode = `questions`)

`questionId`, `productId`, `productName`, `brandName`, `productUrl`, `question`, `author`, `submittedAt`, `answersCount`, `answers[]` (`text`, `author`, `submittedAt`, `isBrandAnswer`, `isBestAnswer`, `helpfulVotes`), `market`, `country`, `locale`, `currency`, `recordType`, `scrapedAt`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search`, `category`, `brand`, `product`, `bestsellers`, `newArrivals`, `sale`, `reviews`, `questions` |
| `searchQueries` | array | `[]` | Keywords for `search` (1–100) |
| `categories` | array | `[]` | Category slugs, `cat...` IDs or URLs (`category`, browse modes; search filter) |
| `brands` | array | `[]` | Brand names, slugs or URLs (`brand`; optional filter in listing modes) |
| `productUrls` | array | `[]` | Product URLs or `P...` IDs (`product`, `reviews`, `questions`) |
| `market` | string | `us` | `us`, `ca-en`, `ca-fr` |
| `sortBy` | string | `relevance` | `relevance`, `bestSelling`, `topRated`, `priceLowToHigh`, `priceHighToLow`, `newArrivals` |
| `minRating` | integer | – | Minimum average rating (1–5) |
| `priceMin` / `priceMax` | integer | – | Current-price bounds in the selected market's currency |
| `includeNewOnly` | boolean | `false` | Only products flagged new |
| `includeBestsellersOnly` | boolean | `false` | Only products flagged as bestsellers in listing modes |
| `saleOnly` | boolean | `false` | Only discounted products |
| `refinements` | array | `[]` | Facet values such as `filters[skinType]=drySk` (maximum 20) |
| `includeDetails` | boolean | `false` | Fetch full detail, variants and stock for listing results |
| `includeImages` | boolean | `true` | Rehost product images for public access |
| `maxImagesPerProduct` | integer | `3` | Image cap per product (1–20) |
| `includeReviews` | boolean | `false` | Add review samples to product rows |
| `maxReviewsPerProduct` | integer | `20` | Review cap per product (1–1000) |
| `reviewsSort` | string | `mostHelpful` | `mostHelpful`, `newest`, `oldest`, `highestRating`, `lowestRating` |
| `includeReviewStats` | boolean | `false` | Add histograms, dates, recommendation counts and identifiers |
| `includeQuestions` | boolean | `false` | Add Q\&A to product rows |
| `maxQuestionsPerProduct` | integer | `10` | Question cap per product (1–200) |
| `maxItems` | integer | `50` | Overall record cap (1–10000) |
| `maxItemsPerQuery` | integer | `0` | Per-keyword/category/brand/URL cap; `0` means unlimited |
| `onlyNewProducts` | boolean | `false` | Skip product IDs already seen under `stateKey` |
| `stateKey` | string | `default` | Name of the saved product-ID state |
| `resetState` | boolean | `false` | Clear saved product IDs before the run |
| `proxyConfiguration` | object | off | Optional; the catalog and review data work without a proxy |

#### Example: US search with variants, reviews and stock

```json
{
  "mode": "search",
  "searchQueries": ["moisturizer", "serum"],
  "market": "us",
  "sortBy": "topRated",
  "minRating": 4,
  "priceMin": 15,
  "priceMax": 80,
  "includeDetails": true,
  "includeReviewStats": true,
  "maxItems": 20
}
```

#### Example: Canada French product with a selected size

```json
{
  "mode": "product",
  "productUrls": [
    "https://www.sephora.com/ca/fr/product/the-ordinary-hyaluronic-acid-2-b5-hydrating-serum-P427419?skuId=2735140"
  ],
  "includeImages": true,
  "includeReviews": true,
  "maxReviewsPerProduct": 5
}
```

#### Example: category browse with sale and rating filters

```json
{
  "mode": "category",
  "categories": ["skincare"],
  "market": "us",
  "saleOnly": true,
  "minRating": 4,
  "sortBy": "priceLowToHigh",
  "includeDetails": true,
  "maxItems": 100
}
```

#### Example: brand review and Q\&A export

```json
{
  "mode": "reviews",
  "productUrls": ["P427419", "P511921"],
  "reviewsSort": "newest",
  "maxReviewsPerProduct": 50,
  "maxItems": 100
}
```

```json
{
  "mode": "questions",
  "productUrls": ["P427419"],
  "maxQuestionsPerProduct": 25,
  "maxItems": 25
}
```

### Use cases

- **Price and promotion tracking** — snapshot current and sale prices, discounts and stock for a watchlist
- **Assortment analysis** — compare brand and category catalogs, shade ranges and size options
- **Ingredient and INCI research** — export ingredients and highlights for formulation or clean-beauty screening
- **Review intelligence** — analyze ratings, review text, photos and reviewer demographics by product or brand
- **Launch monitoring** — use `newArrivals` with `onlyNewProducts` to capture only newly listed products
- **Q\&A and customer-care research** — collect questions with answers, including brand and best answers

### FAQ

**Is this affiliated with Sephora?**
No. This is an independent third-party actor that reads publicly accessible Sephora catalog and review data. It is not operated by or affiliated with Sephora.

**Do I need an account, cookies or an API key?**
No. The actor uses public catalog and review data and works without login or credentials.

**Do I need to configure a proxy?**
No. Direct requests work for the catalog and review endpoints. A proxy input is available only if you want to route traffic yourself.

**Why are some products missing ingredients, highlights or size?**
Those fields are product-specific. When Sephora does not publish them for a product, the field is omitted rather than filled with a placeholder.

**Why do some products show a price range and others a single price?**
Multi-size or multi-shade products can have different prices. `priceMin` and `priceMax` show the current range; `price` is the default variant's current price. `listPrice*` and `salePrice*` keep the original and discounted values separate.

**Why are review demographics missing on some reviews?**
Reviewers choose whether to share skin type, tone, eye color, hair color, age range and concerns. Fields are included only when the reviewer provided them.

**Why isn't mainland France supported?**
The US and Canada storefronts (English and French) are supported. Mainland France is not reachable reliably from the actor's network path, so it is not offered as a market.

**Why aren't product videos included?**
Sephora's video media links are not publicly reachable without a browser session. Product images, descriptions, ingredients and variants are included instead.

**Why does a product page show a different price than the dataset?**
Prices and promotions change frequently, and the dataset reflects the moment of the run. Prices also differ by market and currency; use the `market` field to compare like with like.

**How many records can I get?**
`maxItems` caps the run at up to 10,000 records. Search returns up to 60 products per page, while category and brand browsing return up to 200 per page. Very large result sets are split across categories, brands and filters, and duplicates are removed by product, review or question ID.

# Actor input Schema

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

What to fetch: keyword search, category or brand browse, product URLs, bestsellers, new arrivals, sale, reviews or questions.

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

Keywords to search (mode=search). Enter one or more terms, e.g. `moisturizer`, `vitamin c serum`.

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

Category slugs, `cat...` IDs or Sephora category URLs (mode=category, bestsellers, newArrivals, sale; also a filter in search). Empty browse modes use the six top-level categories.

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

Brand names, slugs or Sephora brand URLs (mode=brand; also an optional filter in other listing modes). Example: `Rare Beauty` or `/brand/rare-beauty-by-selena-gomez`.

## `productUrls` (type: `array`):

Sephora product URLs or `P...` IDs (mode=product, reviews, questions). A `?skuId=` in the URL selects that variant.

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

Storefront and currency: United States (USD), Canada English (CAD) or Canada French (CAD).

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

Result ordering for listing modes. Bestsellers and sale default to best selling; new arrivals default to newest.

## `minRating` (type: `integer`):

Only include products rated at or above this value (1-5).

## `priceMin` (type: `integer`):

Only include products whose current price is at or above this amount, in the selected market's currency.

## `priceMax` (type: `integer`):

Only include products whose current price is at or below this amount, in the selected market's currency.

## `includeNewOnly` (type: `boolean`):

Only include products Sephora flags as new.

## `includeBestsellersOnly` (type: `boolean`):

Only include products flagged as bestsellers in listing modes. Not available in product-URL mode.

## `saleOnly` (type: `boolean`):

Only include products currently discounted by Sephora.

## `refinements` (type: `array`):

Optional Sephora facet values, e.g. `filters[skinType]=drySk` or `filters[ingredientPreferences]=crueltyFree`. Up to 20.

## `includeDetails` (type: `boolean`):

Fetch descriptions, ingredients, highlights, variants, stock, category path and brand information for every product in listing modes. Product-URL mode always includes details.

## `includeImages` (type: `boolean`):

Copy product images into the run's key-value store so the image links stay publicly accessible.

## `maxImagesPerProduct` (type: `integer`):

Maximum number of product images to keep and rehost for each product.

## `includeReviews` (type: `boolean`):

Add recent or most-helpful review samples to product records, and fetch review samples in reviews mode.

## `maxReviewsPerProduct` (type: `integer`):

Maximum review rows or samples per product.

## `reviewsSort` (type: `string`):

Ordering for review rows and review samples.

## `includeReviewStats` (type: `boolean`):

Add the rating histogram, recommendation counts, review dates and GTIN/UPC/EAN identifiers.

## `includeQuestions` (type: `boolean`):

Add questions with their answers to product records, and fetch question rows in questions mode.

## `maxQuestionsPerProduct` (type: `integer`):

Maximum question rows or embedded questions per product.

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

Hard cap on all records emitted by the run.

## `maxItemsPerQuery` (type: `integer`):

Cap records per keyword, category, brand or product URL. 0 means no per-source cap.

## `onlyNewProducts` (type: `boolean`):

Skip product IDs that were already returned under the same state key in earlier runs.

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

Name for the saved product-ID state used by 'Only new products'.

## `resetState` (type: `boolean`):

Forget previously seen product IDs for this state key before the run.

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

Optional. Sephora's public catalog and review endpoints work without a proxy.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "moisturizer"
  ],
  "categories": [],
  "brands": [],
  "productUrls": [],
  "market": "us",
  "sortBy": "relevance",
  "includeNewOnly": false,
  "includeBestsellersOnly": false,
  "saleOnly": false,
  "refinements": [],
  "includeDetails": false,
  "includeImages": true,
  "maxImagesPerProduct": 3,
  "includeReviews": false,
  "maxReviewsPerProduct": 20,
  "reviewsSort": "mostHelpful",
  "includeReviewStats": false,
  "includeQuestions": false,
  "maxQuestionsPerProduct": 10,
  "maxItems": 1,
  "maxItemsPerQuery": 0,
  "onlyNewProducts": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (type: `string`):

Dataset containing Sephora products, reviews and questions, distinguished by recordType.

# 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",
    "searchQueries": [
        "moisturizer"
    ],
    "categories": [],
    "brands": [],
    "productUrls": [],
    "market": "us",
    "sortBy": "relevance",
    "includeNewOnly": false,
    "includeBestsellersOnly": false,
    "saleOnly": false,
    "refinements": [],
    "includeDetails": false,
    "includeImages": false,
    "maxImagesPerProduct": 3,
    "includeReviews": false,
    "maxReviewsPerProduct": 20,
    "reviewsSort": "mostHelpful",
    "includeReviewStats": false,
    "includeQuestions": false,
    "maxQuestionsPerProduct": 10,
    "maxItems": 1,
    "maxItemsPerQuery": 0,
    "onlyNewProducts": false,
    "stateKey": "default",
    "resetState": false,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/sephora-catalog-price-and-rating-finder").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",
    "searchQueries": ["moisturizer"],
    "categories": [],
    "brands": [],
    "productUrls": [],
    "market": "us",
    "sortBy": "relevance",
    "includeNewOnly": False,
    "includeBestsellersOnly": False,
    "saleOnly": False,
    "refinements": [],
    "includeDetails": False,
    "includeImages": False,
    "maxImagesPerProduct": 3,
    "includeReviews": False,
    "maxReviewsPerProduct": 20,
    "reviewsSort": "mostHelpful",
    "includeReviewStats": False,
    "includeQuestions": False,
    "maxQuestionsPerProduct": 10,
    "maxItems": 1,
    "maxItemsPerQuery": 0,
    "onlyNewProducts": False,
    "stateKey": "default",
    "resetState": False,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/sephora-catalog-price-and-rating-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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",
  "searchQueries": [
    "moisturizer"
  ],
  "categories": [],
  "brands": [],
  "productUrls": [],
  "market": "us",
  "sortBy": "relevance",
  "includeNewOnly": false,
  "includeBestsellersOnly": false,
  "saleOnly": false,
  "refinements": [],
  "includeDetails": false,
  "includeImages": false,
  "maxImagesPerProduct": 3,
  "includeReviews": false,
  "maxReviewsPerProduct": 20,
  "reviewsSort": "mostHelpful",
  "includeReviewStats": false,
  "includeQuestions": false,
  "maxQuestionsPerProduct": 10,
  "maxItems": 1,
  "maxItemsPerQuery": 0,
  "onlyNewProducts": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dataspryva/sephora-catalog-price-and-rating-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/sephora-catalog-price-and-rating-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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