# Ulta Product Search Scraper (`stealth_mode/ulta-product-search-scraper`) Actor

Scrape Ulta.com product search results efficiently. This scraper collects 27+ data fields including SKU, pricing, ratings, brand info, and promotional details from beauty product listings — perfect for price monitoring, market research, and e-commerce analytics.

- **URL**: https://apify.com/stealth\_mode/ulta-product-search-scraper.md
- **Developed by:** [Stealth mode](https://apify.com/stealth_mode) (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 $2.00 / 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

## Ulta Product Search Scraper: Extract Beauty & Cosmetics Data

---

### What Is Ulta.com?

Ulta Beauty is one of North America's largest beauty retailers, offering over 25,000 products across makeup, skincare, fragrance, and hair care from premium and drugstore brands. The platform's search functionality allows users to filter by product type, brand, price, and more. Manually extracting product data from Ulta's search results is labor-intensive; the **Ulta Product Search Scraper** automates this process, delivering structured product intelligence for competitive analysis, price monitoring, and market research.

---

### Overview

The **Ulta Product Search Scraper** extracts comprehensive product data from Ulta's search result pages, capturing 27+ fields per product. It is ideal for:

- **Price intelligence teams** tracking competitor pricing and discounts
- **Market researchers** analyzing beauty product trends and availability
- **E-commerce aggregators** building product databases
- **Brand managers** monitoring shelf presence and promotional activity

The scraper combines flexibility with reliability: configurable item limits per URL, graceful error handling, and support for paginated search results enable large-scale, uninterrupted data collection.

---

### Input Format

The scraper accepts a JSON configuration with the following parameters:

```json
{
  "urls": [
    "https://www.ulta.com/search?search=lips&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 200
}
````

| Parameter | Type | Description |
|---|---|---|
| `urls` | Array | Ulta product search URLs to scrape. Paste complete URLs including search query and pagination (e.g., `?search=lips&page=2`). Supports multiple URLs per run. |
| `ignore_url_failures` | Boolean | If `true`, the scraper continues running even if some URLs fail. Recommended for bulk operations to prevent interruptions. |
| `max_items_per_url` | Integer | Maximum number of products to collect per URL (e.g., `200`). Ulta typically displays 20–50 items per page; set this to control data volume. |

> **Pro tip:** Use specific search queries (e.g., "foundation," "mascara") to target product categories. Adjust pagination in the URL (`&page=2`, `&page=3`) to scrape across multiple result pages.

***

### Output Format

**Sample output**

```json
{
  "sku_id": "2594033",
  "product_id": "pimprod2032003",
  "bookmarked": false,
  "image": {
    "image_url": "https://media.ultainc.com/i/ulta/2594033",
    "name": "2594033",
    "is_captions_enabled": false,
    "closed_caption_url": null,
    "video_url": null,
    "video_profiles": null,
    "meta_data": {
      "media_type": "img",
      "is_captions_enabled": false,
      "image_template": "None",
      "width": null,
      "height": null,
      "aspect_ratio": null,
      "is_image": true
    }
  },
  "alt_image": null,
  "bookmark_accessibility": null,
  "add_to_bag_accessibility": null,
  "badge": "",
  "sponsored": false,
  "brand_name": "Tarte",
  "product_name": "Maracuja Juicy Lip Plumping Gloss",
  "price_label": "",
  "rating": 4.2,
  "review_count": 1201,
  "list_price": "$27.00",
  "sale_price": null,
  "discount": null,
  "promo_text": null,
  "additional_offers_text": null,
  "review_accessibility_label": "4.2 out of 5 stars ; 1201 reviews",
  "variant_label": "8 colors",
  "kit_price": null,
  "format_on_load_beacon": null,
  "format_on_view_beacon": null,
  "sponsored_badge_label": null,
  "is_limited_stock": false,
  "product_card_tags": null,
  "badge_tags": null,
  "from_url": "https://www.ulta.com/search?search=lips&page=2"
}
```

Each product record includes 27 data fields covering identity, pricing, reviews, availability, and marketing metadata:

#### Product Identification

| Field | Meaning |
|---|---|
| `SKU ID` | Stock Keeping Unit — unique identifier for inventory tracking |
| `Product ID` | Ulta's internal product database identifier |
| `Product Name` | Full product title as displayed in search results |
| `Brand Name` | Manufacturer or brand name (e.g., "MAC," "Fenty Beauty") |

#### Pricing & Discounts

| Field | Meaning |
|---|---|
| `List Price` | Original manufacturer suggested retail price (MSRP) |
| `Sale Price` | Current selling price on Ulta.com |
| `Price Label` | Formatted price display (e.g., "$15.00") |
| `Discount` | Calculated discount percentage or absolute amount |
| `Kit Price` | Price if the product is part of a bundled set |
| `Promo Text` | Text describing active promotions (e.g., "Buy 2, Get 1 Free") |
| `Additional Offers Text` | Extra incentives like loyalty rewards or seasonal deals |

#### Ratings & Reviews

| Field | Meaning |
|---|---|
| `Rating` | Average customer star rating (1–5 scale) |
| `Review Count` | Total number of customer reviews |
| `Review Accessibility Label` | Descriptive text for screen readers (accessibility metadata) |

#### Visual & Content

| Field | Meaning |
|---|---|
| `Image` | URL to the product thumbnail image |
| `Alt Image` | Alternative image URL (e.g., product from a different angle) |
| `Variant Label` | Description of product options (e.g., "Shade: Rose Gold," "Size: 0.5 oz") |

#### Availability & Stock Status

| Field | Meaning |
|---|---|
| `Is Limited Stock` | Boolean flag indicating if inventory is running low |
| `Product Card Tags` | Category tags (e.g., "Cruelty-Free," "Vegan," "Natural") |
| `Badge Tags` | Special designations (e.g., "New," "Best Seller," "Editor's Pick") |
| `Badge` | Visual badge displayed on the product card |

#### User Interaction & Bookmarking

| Field | Meaning |
|---|---|
| `Bookmarked` | Whether the product is saved to the user's favorites/wishlist |
| `Bookmark Accessibility` | Descriptive text for screen readers (bookmark button) |
| `Add To Bag Accessibility` | Accessibility label for the "Add to Cart" button |

#### Sponsored & Marketing Data

| Field | Meaning |
|---|---|
| `Sponsored` | Boolean flag if the product listing is paid/sponsored |
| `Sponsored Badge Label` | Text label identifying sponsored products |
| `Format On Load Beacon` | Tracking pixel or beacon fired when page loads |
| `Format On View Beacon` | Analytics beacon triggered when product enters viewport |

***

### How to Use

1. **Find search URLs** — Visit Ulta.com and perform a product search (e.g., "lips," "foundation"). Navigate through pages if needed.
2. **Copy the search URL** — Copy the complete URL from your browser, including the search parameter and page number. Example: `https://www.ulta.com/search?search=lips&page=2`
3. **Paste into configuration** — Add the URL(s) to the `urls` array. You can scrape multiple search queries in a single run.
4. **Set max items** — Configure `max_items_per_url` based on your needs (typical range: 20–200 products per URL).
5. **Enable error handling** — Set `ignore_url_failures: true` for large-scale runs to avoid interruptions.
6. **Run the scraper** — Execute and monitor progress in the run log.
7. **Export data** — Download results as JSON, CSV, or Excel.

**Common tips:**

- Ulta search URLs support filtering by category, price range, and rating. Adjust the search query to narrow scope.
- The `&page=` parameter controls pagination; increment it manually in URLs for multi-page scraping.
- Limited stock status updates frequently; run the scraper periodically for fresh inventory data.

***

### Use Cases & Business Value

**Price Monitoring:** Track Ulta's prices against competitor offerings (Sephora, Amazon) in real-time.

**Product Intelligence:** Monitor which products are trending (high review counts, new badges) and plan inventory decisions.

**Market Research:** Analyze brand presence, discount patterns, and product availability across categories (makeup, skincare, fragrance).

**Assortment Planning:** Identify best-sellers and top-rated products to guide purchasing and merchandising.

**SEO & Content:** Gather product data for building independent review sites, comparison tools, or beauty recommendation engines.

The scraper delivers clean, structured data that integrates seamlessly into analytics platforms, spreadsheets, and databases — eliminating weeks of manual data entry.

***

### Conclusion

The **Ulta Product Search Scraper** is a powerful tool for anyone needing reliable, large-scale beauty product data. Whether you're monitoring prices, tracking trends, or building product databases, this scraper extracts 27+ fields of actionable intelligence from Ulta search results. Get started today and unlock insights into the competitive beauty retail landscape.

# Actor input Schema

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

Add the URLs of the product search list urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.

## `ignore_url_failures` (type: `boolean`):

If true, the scraper will continue running even if some URLs fail to be scraped.

## `max_items_per_url` (type: `integer`):

The maximum number of items to scrape per URL.

## Actor input object example

```json
{
  "urls": [
    "https://www.ulta.com/search?search=lips&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20
}
```

# 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 = {
    "urls": [
        "https://www.ulta.com/search?search=lips&page=2"
    ],
    "ignore_url_failures": true,
    "max_items_per_url": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("stealth_mode/ulta-product-search-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 = {
    "urls": ["https://www.ulta.com/search?search=lips&page=2"],
    "ignore_url_failures": True,
    "max_items_per_url": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("stealth_mode/ulta-product-search-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 '{
  "urls": [
    "https://www.ulta.com/search?search=lips&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20
}' |
apify call stealth_mode/ulta-product-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ulta Product Search Scraper",
        "description": "Scrape Ulta.com product search results efficiently. This scraper collects 27+ data fields including SKU, pricing, ratings, brand info, and promotional details from beauty product listings — perfect for price monitoring, market research, and e-commerce analytics.",
        "version": "0.0",
        "x-build-id": "0EtnvgYeGhcPENqkg"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stealth_mode~ulta-product-search-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stealth_mode-ulta-product-search-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/stealth_mode~ulta-product-search-scraper/runs": {
            "post": {
                "operationId": "runs-sync-stealth_mode-ulta-product-search-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/stealth_mode~ulta-product-search-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-stealth_mode-ulta-product-search-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",
                "properties": {
                    "urls": {
                        "title": "URLs of the product search list urls to scrape",
                        "type": "array",
                        "description": "Add the URLs of the product search list urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "ignore_url_failures": {
                        "title": "Continue running even if some URLs fail to be scraped",
                        "type": "boolean",
                        "description": "If true, the scraper will continue running even if some URLs fail to be scraped."
                    },
                    "max_items_per_url": {
                        "title": "Max items per URL",
                        "type": "integer",
                        "description": "The maximum number of items to scrape per URL."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
