# Ulta Beauty US Product Scraper (`dromb/ulta-beauty-us-product-scraper`) Actor

Extract comprehensive product information from Ulta Beauty US storefront including search, categories, and product details with pricing, reviews, and variants.

- **URL**: https://apify.com/dromb/ulta-beauty-us-product-scraper.md
- **Developed by:** [Dmitriy Gyrbu](https://apify.com/dromb) (community)
- **Categories:** Automation, Developer tools, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 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.

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

## Ulta Beauty US Product Scraper

The **Ulta Beauty US Product Scraper** is a powerful tool designed to extract comprehensive product information from the Ulta Beauty US storefront. It is ideal for price monitoring, market research, competitor analysis, product research, availability tracking, offers monitoring, and reviews analysis.

### 🚀 Features

- **Search Products**: Find products using keywords with pagination and sorting options.
- **Category Scraping**: Extract all products from specific category URLs.
- **Product Details**: Get deep product data including ingredients, usage instructions, variants, and embedded reviews.
- **Category Discovery**: List all available product categories from the storefront navigation.
- **Search Filters**: Discover available filter groups and sort options for any search query.
- **Store Probe**: Quickly check if the Ulta store is accessible.

### 🛠 How to Use

#### 🚀 Quick Start Examples
If you are unsure what to enter, use these values:
- **Search**: Operation `search`, Query `lipstick`
- **Category**: Operation `category`, URL `https://www.ulta.com/shop/makeup/lips/lip-liner`
- **Item**: Operation `item`, URL `https://www.ulta.com/p/macximal-silky-matte-lipstick-pimprod2043558?sku=2621440`

#### 1. Search for Products
- **Operation**: `search`
- **Query**: Enter a keyword (e.g., "lipstick", "foundation", "shampoo", "fragrance")
- **Page**: Specify the page number (starts at 1).
- **Sort**: Choose between `relevance`, `best_sellers`, `price_asc`, `price_desc`, `new_arrivals`, `top_rated`.

#### 2. Scrape a Category
- **Operation**: `category`
- **URL**: Enter a category URL (e.g., `https://www.ulta.com/shop/makeup/lips/lip-liner`)
- **Path**: Alternatively, enter a category path (e.g., `/shop/makeup/lips/lip-liner`)
- **Page**: Specify the page number.
- **Sort**: Choose a sorting option.

#### 3. Get Product Details
- **Operation**: `item`
- **URL**: Enter a full product URL (preferred)
- **Path**: Enter a product path (e.g., `/p/product-name`)
- **SKU**: Enter an exact SKU (best-effort resolution, URL/path preferred)

#### 4. Discover Categories
- **Operation**: `categories`
- This operation will return a list of all discoverable categories with their paths and URLs.

#### 5. Get Search Filters
- **Operation**: `search/filters`
- **Query**: Enter a search term to discover available filters and sort options.

#### 6. Probe Store
- **Operation**: `probe`
- Check if Ulta is accessible and retrieve the page title.

### 📊 Output Fields

The scraper provides a rich set of normalized fields:
- `sku`: Unique SKU identifier
- `product_id`: Product ID
- `name`: Full product name
- `brand`: Brand name
- `variant`: Variant label (e.g., color, size)
- `current_price`: Current price (sale price if available)
- `price`: Original list price
- `discount_price`: Discount/sale price
- `rating`: Average product rating
- `review_count`: Number of reviews
- `image` & `images`: Product imagery
- `description`: Full product description
- `usage`: Usage instructions
- `ingredients`: Full ingredients list
- `restrictions`: Product restrictions
- `variants`: Detailed list of product variants
- `badges`: Promotional badges (e.g., "Only at Ulta")
- `breadcrumbs`: Category breadcrumb trail
- `reviews`: Embedded review samples
- `in_store`: Whether available in physical stores

### 🌐 Proxy and Bot Protection

The scraper uses a robust proxy strategy to avoid blocks:
- **Auto**: Automatically selects the best proxy (recommended for ordinary retail)
- **Apify**: Uses Apify's standard proxy pool
- **Direct**: No proxy (use with caution)
- **Custom**: Custom proxy configuration

It employs TLS fingerprinting via `curl-cffi` to mimic real browser requests and implements retry logic for blocked responses.

### ⚖️ Disclaimer

This scraper is an unofficial tool and is not affiliated with, authorized, or endorsed by Ulta Beauty. Please use it responsibly and in accordance with the site's terms of service.

### 🏷 Categories

`ECOMMERCE`, `AUTOMATION`, `DEVELOPER_TOOLS`

### ⚠️ Known Limitations

- **SKU-only lookup**: SKU resolution is best-effort only. Ulta does not expose a stable public SKU-only resolver. Use full product URL or path when possible for the `item` operation.
- **Landing categories**: Top-level category pages (e.g., `/shop/makeup`) may behave as navigation landings rather than direct product listings. These return `kind=landing_category` with `subcategories` instead of product items.
- **Rate limiting**: Free/trial users are limited to 20 requests per day to prevent abuse.

### 📝 Operation Guide

#### Required Fields per Operation

| Operation | Required Fields | Optional Fields |
|-----------|-----------------|-----------------|
| `search` | `query` | `page`, `sort` |
| `category` | `url` or `path` | `page`, `sort` |
| `item` | `url`, `path`, or `sku` | - |
| `categories` | None | - |
| `search/filters` | `query` | - |
| `probe` | None | - |

#### Sort Options

- `relevance`: Default relevance sorting
- `best_sellers`: Best selling products
- `price_asc`: Price low to high
- `price_desc`: Price high to low
- `new_arrivals`: Newest products
- `top_rated`: Highest rated products

# Actor input Schema

## `operation` (type: `string`):

The scraping operation to perform.
## `query` (type: `string`):

Keyword to search for products (required for 'search' and 'search/filters' operations). Example: lipstick, foundation, shampoo.
## `url` (type: `string`):

Product URL or Category URL (required for 'item' or 'category' operations).
## `path` (type: `string`):

Product path like /p/product-name or category path like /shop/makeup/lips (optional for 'item' and 'category' operations).
## `sku` (type: `string`):

Exact Ulta SKU (optional for 'item' operation, best-effort resolution). Example: 2648550.
## `page` (type: `integer`):

Page number for pagination (1-based).
## `sort` (type: `string`):

Sorting option for search and category operations. Common values: relevance, best_sellers, price_asc, price_desc, new_arrivals, top_rated.
## `proxy` (type: `string`):

Proxy strategy to use. Auto is recommended for ordinary retail sites.
## `custom_proxy_url` (type: `string`):

Custom proxy URL (required when proxy is set to 'custom').

## Actor input object example

```json
{
  "operation": "search",
  "page": 1,
  "sort": "relevance",
  "proxy": "auto"
}
````

# Actor output Schema

## `sku` (type: `string`):

Unique SKU identifier

## `product_id` (type: `string`):

Product ID

## `name` (type: `string`):

Product name

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

Brand name

## `variant` (type: `string`):

Variant label

## `current_price` (type: `string`):

Current price (sale price if available, otherwise list price)

## `price` (type: `string`):

List price (original price)

## `discount_price` (type: `string`):

Discount/sale price if applicable

## `discount` (type: `string`):

Discount text

## `currency` (type: `string`):

Currency code

## `price_label` (type: `string`):

Price label text

## `rating` (type: `string`):

Average product rating

## `review_count` (type: `string`):

Number of reviews

## `review_label` (type: `string`):

Review accessibility label

## `image` (type: `string`):

Primary product image URL

## `source_url` (type: `string`):

Product page URL

## `badge` (type: `string`):

Primary badge

## `badges` (type: `string`):

List of badges

## `additional_offers_text` (type: `string`):

Additional offers text

## `sponsored` (type: `string`):

Whether the item is sponsored

## `is_limited_stock` (type: `string`):

Whether the item has limited stock

## `product_type` (type: `string`):

Product type

## `product_category` (type: `string`):

Product category path

## `categories` (type: `string`):

List of category levels

## `description` (type: `string`):

Product description

## `usage` (type: `string`):

Usage instructions

## `ingredients` (type: `string`):

Full ingredients list

## `restrictions` (type: `string`):

Product restrictions

## `prop65_warning` (type: `string`):

California Prop 65 warning

## `questions_count` (type: `string`):

Number of Q\&A questions

## `variant_type` (type: `string`):

Variant type (e.g., Color, Size)

## `variant_dimension_label` (type: `string`):

Variant dimension label

## `variant_dimension_value` (type: `string`):

Variant dimension value

## `variants` (type: `string`):

List of product variants

## `in_store` (type: `string`):

Whether available in store

## `seller_id` (type: `string`):

Seller ID

## `display_state` (type: `string`):

Display state

## `breadcrumbs` (type: `string`):

Breadcrumb trail

## `reviews` (type: `string`):

List of reviews

## `images` (type: `string`):

List of product images

## `status` (type: `string`):

Response status

## `source` (type: `string`):

Data source identifier

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("dromb/ulta-beauty-us-product-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("dromb/ulta-beauty-us-product-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 '{}' |
apify call dromb/ulta-beauty-us-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dromb/ulta-beauty-us-product-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ulta Beauty US Product Scraper",
        "description": "Extract comprehensive product information from Ulta Beauty US storefront including search, categories, and product details with pricing, reviews, and variants.",
        "version": "0.1",
        "x-build-id": "8CG6NV9ERbPQQGaVM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dromb~ulta-beauty-us-product-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dromb-ulta-beauty-us-product-scraper",
                "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/dromb~ulta-beauty-us-product-scraper/runs": {
            "post": {
                "operationId": "runs-sync-dromb-ulta-beauty-us-product-scraper",
                "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/dromb~ulta-beauty-us-product-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-dromb-ulta-beauty-us-product-scraper",
                "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": [
                    "operation"
                ],
                "properties": {
                    "operation": {
                        "title": "Operation",
                        "enum": [
                            "search",
                            "category",
                            "item",
                            "categories",
                            "search/filters",
                            "probe"
                        ],
                        "type": "string",
                        "description": "The scraping operation to perform.",
                        "default": "search"
                    },
                    "query": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Keyword to search for products (required for 'search' and 'search/filters' operations). Example: lipstick, foundation, shampoo."
                    },
                    "url": {
                        "title": "URL",
                        "type": "string",
                        "description": "Product URL or Category URL (required for 'item' or 'category' operations)."
                    },
                    "path": {
                        "title": "Path",
                        "type": "string",
                        "description": "Product path like /p/product-name or category path like /shop/makeup/lips (optional for 'item' and 'category' operations)."
                    },
                    "sku": {
                        "title": "SKU",
                        "type": "string",
                        "description": "Exact Ulta SKU (optional for 'item' operation, best-effort resolution). Example: 2648550."
                    },
                    "page": {
                        "title": "Page",
                        "type": "integer",
                        "description": "Page number for pagination (1-based).",
                        "default": 1
                    },
                    "sort": {
                        "title": "Sort Order",
                        "enum": [
                            "relevance",
                            "best_sellers",
                            "price_asc",
                            "price_desc",
                            "new_arrivals",
                            "top_rated"
                        ],
                        "type": "string",
                        "description": "Sorting option for search and category operations. Common values: relevance, best_sellers, price_asc, price_desc, new_arrivals, top_rated.",
                        "default": "relevance"
                    },
                    "proxy": {
                        "title": "Proxy Configuration",
                        "enum": [
                            "auto",
                            "apify",
                            "direct",
                            "custom"
                        ],
                        "type": "string",
                        "description": "Proxy strategy to use. Auto is recommended for ordinary retail sites.",
                        "default": "auto"
                    },
                    "custom_proxy_url": {
                        "title": "Custom Proxy URL",
                        "type": "string",
                        "description": "Custom proxy URL (required when proxy is set to 'custom')."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
