Sephora Scraper at a glance
Sephora Scraper is a ready-to-run Apify actor from abotapi for collecting ecommerce data. Its documented output includes market, brand, title, change type (incremental mode) and sku, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $1.80 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Ecommerce, Automation, Developer Tools
- Pricing
- $1.80 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 36 options
From $1/1K. Scrape Sephora products across 21+ storefronts (US, AU, NZ, SG, MY, ID, TH, PH, MX, DE, RO, SE, GR, DK) with a unified schema. Extract brand, title, ingredients, claims, full SKU and shade variants, ratings histogram, top reviews, Q&A, and rich media.
What Sephora Scraper can do
- 14 regional storefronts, one input form. United States, Australia, New Zealand, Singapore, Malaysia, Indonesia, Thailand, Philippines, Mexico, Germany, Romania, Sweden, Greece and Denmark, all normalized to the same output shape.
- Three ways to find products. Search by keyword, browse by category slug, or paste any Sephora product, category, brand or search URL and let the scraper detect the storefront.
- Full product detail on demand. Switch on the product detail fetch for ingredients, how-to-use text, claims and, on the US and Southeast Asia storefronts, the complete variant matrix (every shade, size, SKU and UPC). Leave it off for a search-results-only run so you only pay for the fields you actually use.
- Ratings and voice of the customer. Pull the rating histogram, top reviews (with skin type and skin tone tags where available) and top questions and answers, each capped by you.
- Built-in discount tracking. Every record carries isOnSpecial, wasPrice, savingsAmount and savingsPercent, always present, never guessed. A non-discounted product gets an explicit false/null rather than a missing field.
- Resilient long walks. Forward-paginated result walks checkpoint themselves and resume automatically after a platform restart, and a delta-resume option skips everything a previous run already collected.
Choose what to collect
These inputs let you configure Sephora Scraper - Products, SKUs, Reviews & 21+ Stores. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Search mode = pick storefront + queries. URL mode = paste Sephora product, category, brand, or search URLs. Result filters (price, rating, brand, new arrivals, exclusives) work in both modes. |
storefrontstring | Which Sephora regional site to scrape. |
marketstring | Alias for the storefront in the style of other Sephora scrapers: us, eu-de, eu-ro, eu-gr, mena-ae, mena-sa, mena-qa, mena-kw, sea-au, sea-nz, sea-sg, sea-my, sea-id, sea-th, sea-ph. An explicit market wins over the default Storefront (us); if a non-default Storefront is also set, the Storefront wins and the run logs a warning. Markets without a verified storefront (uk, in, sea-hk, sea-tw, sea-bn, eu-cz, mena-bh, mena-om) are NOT supported: the run logs a warning and falls back to the Storefront value. |
localestring | Accepted for compatibility with other Sephora scrapers (e.g. en-AU). The storefront decides the locale; a mismatch logs a warning. |
categoryIdsarray | Alias that is merged into Categories (slugs or paths). |
newProductsPageLimitinteger | With Only new arrivals on, caps the result pages walked per query (same as Max pages). |
maxRequestsPerCrawlinteger | Caps the result pages walked per query (same as Max pages). |
Show 29 more inputs
| Input | What it controls |
|---|---|
queriesarray | Keywords to search the storefront (e.g. 'foundation', 'rare beauty', 'lipstick'). Each query runs as a separate search. |
categoriesarray | Category slugs from the navigation tree (e.g. 'shop/foundation-makeup', 'shop/skincare', 'shop/fragrance'). Optional, leave empty if you only want keyword search. |
sortBystring | How to order the search results. |
specialsOnlyboolean | Scrape Sephora's 'Sale' collection instead of your queries/categories. Covers the SEA storefronts only (AU/NZ/SG/MY/ID/TH/PH); ignored elsewhere. The Sale collection does not combine with keywords or categories, so when this is on, 'Search queries' and 'Category slugs' are ignored and the full Sale collection is scraped instead. |
urlsarray | One or more full Sephora URLs (product, category, brand, or search). The scraper auto-detects the storefront from the host. Left untouched, one example per URL shape is scraped. startUrls is accepted as an alias. |
brandsarray | Brand slugs to filter results (e.g. 'rare-beauty', 'fenty-beauty', 'charlotte-tilbury'). Multiple allowed. |
priceMininteger | Minimum product price in the storefront's currency. |
priceMaxinteger | Maximum product price in the storefront's currency. |
ratingMininteger | Only return products with average rating at or above this value. Use 0 (no filter), 3, 4, or 5. |
newOnlyboolean | Return only products marked as new arrivals on the storefront. |
onlyNewProductsboolean | Alias of 'New arrivals only'. Either one switches the filter on. |
exclusiveOnlyboolean | Return only products marked 'Only at Sephora'. |
fetchDetailsboolean | Fetch the product detail page for full content. Required for ingredients, howToUse, full variant list, claims, awards, ratings histogram. SERP-only mode is faster and cheaper. |
fetchReviewsboolean | Pull the top N reviews per product (sorted by helpfulness). Adds one extra fetch per product. |
maxReviewsPerProductinteger | Cap the number of reviews per product (1-100). Ignored unless 'Fetch top reviews' is on. |
fetchQnaboolean | Pull questions and answers per product (sorted by recency). Adds one extra fetch per product. |
maxQnaPerProductinteger | Cap the number of Q&A entries per product (1-50). Ignored unless 'Fetch top Q&A' is on. |
maxPagesinteger | Optional bound on result pages walked per query/category/URL. Leave empty to walk every result page; the walk stops when the storefront returns no next page, a repeat page is detected, or 'Max products total' is hit. |
maxProductsinteger | Total cap across all queries/URLs. Set to 0 for the hard maximum of 100000 (also bounded by maxPages and the storefront's own result count). |
resumeFromCheckpointboolean | Resume a previous run from the last saved checkpoint. |
resumeFromRunIdstring | Optional: paste a previous run ID (or dataset ID) from this actor. Products already collected there are skipped, so this run only returns new ones. Leave empty for a normal run. For recurring daily/weekly monitoring of the same search or URLs, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or recurring monitoring of the same search/category/URLs. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. UPDATED means a compared field changed: price, was price, specials, stock, variants, title, brand, categories, images, descriptions and every other product field. Review and rating counters (rating, reviewCount, stats ratings/loves/question counts, ratingHistogram, topReviews, topQuestions, sentiments) and scrapedAt are kept in the output but never trigger UPDATED; add more with "Ignore fields when detecting changes". Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately per search/category/URL and filter 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 run ID above. |
stateKeystring | 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 storefront/search/category/URL and filter settings -- different setups then never mix state with each other. |
emitUnchangedboolean | 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. |
emitExpiredboolean | 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/category/URLs -- 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. |
ignoreFieldsForChangesarray | Optional. Field names to exclude from UPDATED change detection, in addition to the built-in handling (review and rating counters never trigger a false UPDATED). Use a top-level name such as "badges", or a dotted path for a nested key such as "stats.lovesCount". Ignored fields stay in the output; they are only left out of the comparison and of changedFields. |
mcpConnectorsarray | 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). |
notionParentPageUrlstring | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
marketMarket (text)brandBrand (text)titleTitle (text)changeTypeChange type (incremental mode) (text)currentSkuSKU (text)categoriesCategories (array)pricePrice (object)isOnSpecialOn special (boolean)wasPriceWas price (number)savingsAmountSavings (number)statsStats (object)sourceSource (object)Show 16 more fields
changedFieldsChanged fields (incremental mode) (array)firstSeenAtFirst seen (incremental mode) (date)lastSeenAtLast seen (incremental mode) (date)optionsOptions (object)variantsVariants (object)ratingHistogramHistogram (object)secondaryRatingsSecondary (object)sentimentsTags (object)topReviewsTop reviews (object)descriptionDescription (text)ingredientsIngredients (text)howToUseHow to use (text)claimsClaims (array)mediasMedia (array)subtitleSubtitle (text)topQuestionsQuestion (object)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"market": "sea-nz",
"source": {
"id": 500000001,
"crawlUrl": "https://www.sephora.nz/products/sample-foundation",
"canonicalUrl": "https://www.sephora.nz/products/sample-foundation",
"retailer": "SEPHORA",
"currency": "NZD",
"locale": "en-NZ"
},
"brand": "Sample Brand",
"title": "Sample Foundation",
"subtitle": "30ml",
"description": "<p>A self-priming foundation, primes, covers and sets...</p>",
"shortDescription": "<p>3-in-1 foundation primes, covers and sets...</p>",
"ingredients": "Aqua, Cyclopentasiloxane, Glycerin...",
"howToUse": "Shake well. Apply a small amount onto the back of your hand and use a brush or fingertips to blend onto skin.",
"claims": [
"Cruelty free",
"Paraben free",
"Vegan"
],
"currentSku": "0000000",
"price": {
"current": 18,
"original": 36,
"currency": "NZD",
"stockStatus": "IN_STOCK",
"available": true,
"inventory": 13
},
"categories": [
"Makeup",
"Face",
"Foundation"
],
"options": [
{
"name": "shade",
"id": "0",
"values": [
{
"value": "1 Fair Neutral",
"label": "1 Fair Neutral",
"id": "0"
}
]
}
],
"variants": [
{
"id": "0",
"sku": "0000000",
"gtin": "000000000000",
"name": "1 Fair Neutral",
"shade": "1 Fair Neutral",
"size": "30ml",
"price": {
"current": 18,
"original": 36,
"currency": "NZD",
"stockStatus": "IN_STOCK",
"available": true,
"inventory": 13
},
"highlights": [
"NEW",
"Only at Sephora"
],
"swatchUrl": "https://image.example.com/swatches/icon_swatch_0000.png",
"imageUrl": "https://image.example.com/products/sample.jpg"
}
],
"medias": [
{
"url": "https://image.example.com/products/sample-zoom.jpg",
"type": "image",
"role": "hero"
}
],
"stats": {
"reviewCount": 971,
"rating": 4.8,
"recommendedCount": 800,
"totalPhotoCount": 100
},
"ratingHistogram": [
{
"RatingValue": 5,
"Count": 700
},
{
"RatingValue": 4,
"Count": 200
},
{
"RatingValue": 3,
"Count": 50
},
{
"RatingValue": 2,
"Count": 15
},
{
"RatingValue": 1,
"Count": 6
}
],
"topReviews": [
{
"id": "0",
"rating": 5,
"title": "Best foundation I have ever tried",
"body": "Sample review text appears here...",
"publishedAt": "2026-01-01T00:00:00.000Z",
"skinType": "combination",
"skinTone": "fair"
}
],
"highlights": [
"NEW",
"Only at Sephora"
],
"isOnSpecial": true,
"wasPrice": 36,
"savingsAmount": 18,
"savingsPercent": 50,
"soldOut": false,
"frontend": "sea",
"scrapedAt": "2026-01-01T00:00:00.000Z"
}Ways to use this data
- Retail price and assortment monitoring: track price, stock status and the Sale collection across storefronts and currencies.
- Beauty affiliate and comparison sites: pull brand, description, ingredients and claims to build product pages without manual entry.
- Review and sentiment research: collect top reviews with skin type and skin tone context, plus the ratings histogram, for a brand's own SKUs or its competitors.
- Variant and shade planning: build a full shade, size and SKU matrix per product for merchandising or QA.
- Recurring monitoring: schedule the actor and use Incremental mode to see only new, changed or discontinued products since the last run.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Sephora Scraper return?
The documented output for Sephora Scraper includes market, brand, title, change type (incremental mode), sku, categories, price and on special. Availability of each field depends on the source page and the selected mode.
How much does Sephora Scraper cost?
It costs $1.80 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed products on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated products by default, and unchanged ones are suppressed and not billed. A product that disappears is only reported (as EXPIRED) once you turn on Emit expired products and a run scans the full tracked scope without being capped by Max products or run with Resume. A product that comes back after being marked EXPIRED is then reported as REAPPEARED on the run where it reappears. Without Emit expired products turned on at some point, you will only ever see NEW, UPDATED and UNCHANGED.
Why did my run return no reviews or Q&A even though I turned them on?
Fetch top reviews and Fetch top Q&A currently return data on the Southeast Asia storefronts (Australia, New Zealand, Singapore, Malaysia, Indonesia, Thailand, Philippines). The US storefront's review feed is not verified in this release and usually returns an empty list. Other storefronts return an empty list for these fields even with the switches on, since their review platform is not wired up yet. In search mode, both switches also require Fetch product details to be on; otherwise they are silently ignored.
Why did my run fail instead of returning an empty dataset?
An unresolvable input, such as an empty search with no queries or categories, leaves the run SUCCEEDED with zero rows and a status message explaining why, so a first-time typo never gets billed for nothing. The run fails outright only for a genuine setup problem: a Resume from run ID that cannot be resolved to a run or dataset your account can read, or Incremental mode combined with a Resume from run ID when that search already has saved incremental state. If the site refuses every request, run it again in a few minutes.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each record into Notion, Linear or Airtable.
