# Ulta Scraper (`redomic/ulta-scraper`) Actor

Scrape Ulta Beauty products by search or category with prices, ratings, reviews, and availability. Monitor price and stock changes over time. $1.40 per 1,000 products.

- **URL**: https://apify.com/redomic/ulta-scraper.md
- **Developed by:** [Redomic](https://apify.com/redomic) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.12 / 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/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

## Ulta Scraper - Ulta Beauty products, prices, ratings, and availability

Ulta Scraper collects Ulta Beauty product data from a search term or category page. Each row is one product with id, sku, brand, title, priceAmount, priceCurrency, list and sale prices, rating, reviewCount, availability, badge, promo text, imageUrl, and url. Use it to track prices, monitor stock and assortment changes, or build product and market research datasets.

In monitor mode it compares each run with the previous run for the same input and reports only new, changed, and removed products.

### Who uses it

- Beauty brands and ecommerce managers tracking competitor prices, promotions, ratings, and assortment on Ulta.
- Retail and pricing analysts building recurring price and stock monitoring feeds for Ulta Beauty categories.
- Catalog and research teams collecting product metadata, review counts, and availability for analysis.

### What you get

5 real rows captured from Ulta Beauty on 2026-11-16 (category: foundation):

| id | brand | title | priceAmount | rating | reviewCount | availability | url |
|---|---|---|---:|---:|---:|---|---|
| pimprod2057355 | Estée Lauder | Double Wear Stay-in-Place Longwear Matte Foundation | 52.00 | 4.2 | 10297 |  | https://www.ulta.com/p/double-wear-stay-in-place-longwear-matte-foundation-pimprod2057355?sku=2651970 |
| pimprod2051406 | MAC | Studio Fix Powder Plus Foundation | 39.00 | 3.8 | 3525 |  | https://www.ulta.com/p/studio-fix-powder-plus-foundation-pimprod2051406?sku=2635749 |
| pimprod2049570 | Lancôme | Teint Idole Ultra Wear 24H Full Coverage Foundation | 53.00 | 4.3 | 7390 |  | https://www.ulta.com/p/teint-idole-ultra-wear-24h-full-coverage-foundation-pimprod2049570?sku=2632372 |
| xlsimpprod5770257 | IT Cosmetics | CC+ Cream with SPF 50+ | 39.00 | 4.3 | 22056 |  | https://www.ulta.com/p/cc-cream-with-spf-50-xlsimpprod5770257?sku=2264064 |
| pimprod2058179 | NARS | Light Reflecting Advanced Skincare Foundation | 52.00 | 4.4 | 3011 |  | https://www.ulta.com/p/light-reflecting-advanced-skincare-foundation-pimprod2058179?sku=2649511 |

Discovery rows also include sku, priceCurrency, listPriceAmount, salePriceAmount, badge, promoText, imageUrl, variantLabel, sourceType, and scrapedAt. Product detail rows can include description, gtin12, color, breadcrumbs, categoryPath, imageUrls, ingredients, attributes, and sampleReviews when available on the product page.

### Modes

| Mode | What it does | Output |
|---|---|---|
| `discovery` | Collects products from a search term or category path/URL. | One row per product found on the page. |
| `detail` | Fetches a single product page. | One row with full product details parsed from the page. |
| `monitor` | Runs discovery and compares with the previous run for the same input. | Rows with `changeType` set to `new`, `changed`, or `removed`, plus a STATUS summary. |

### Price

This Actor charges $1.40 per 1,000 products, with no start fee. In `discovery` and `detail` modes each returned product is charged as a result. In `monitor` mode only new or changed products are charged; unchanged and removed items are free. For example, collecting 500 products in discovery mode costs $0.70.

### How to run it

- Search for products: set `query` to `mascara` with `mode` = `discovery`. Ulta shows search results only in the browser, so a product type or brand opens the category or brand page Ulta's own menu links (`mascara` reads `/shop/makeup/eyes/mascara`).
- Collect a category: set `query` to `/shop/makeup/face/foundation` with `mode` = `discovery`.
- Track changes: set `query` to `/shop/skin-care/moisturizers/face-moisturizer` with `mode` = `monitor` and schedule the run.

### Input

| Field | Default | What it does |
|---|---|---|
| `query` | `mascara` | Product type or brand (opens the matching Ulta category or brand page), category path (for example `/shop/makeup/face/foundation`), brand page (`/brand/tarte`), or full Ulta product or category URL. |
| `mode` | `discovery` | `discovery` to list products, `detail` to fetch one product page, `monitor` to report new/changed/removed products since the previous run. |
| `maxItems` | `50` | Maximum number of products to return. |
| `proxy` | Apify Proxy enabled | Proxy settings. Use a residential proxy if Ulta blocks requests from your run environment. |

### Output fields

- `id`: Ulta product identifier (for example `pimprod2057355`).
- `sku`: SKU shown on the card or product page.
- `brand`: Product brand.
- `title`: Product name.
- `variantLabel`: Variant label from the listing card when present.
- `priceAmount`, `priceCurrency`: Current price as a number and ISO 4217 currency code.
- `listPriceAmount`, `salePriceAmount`: List and sale prices when available.
- `rating`, `reviewCount`: Average rating and number of reviews.
- `availability`: Availability value when known (for example `InStock` or `LimitedAvailability`).
- `badge`, `promoText`: Badge and promotion text from the listing.
- `imageUrl`, `imageUrls`: Product image URL(s).
- `url`: Canonical product URL.
- `description`, `gtin12`, `color`: Detail fields from the product page.
- `breadcrumbs`, `categoryPath`: Category breadcrumb values.
- `ingredients`, `attributes`: Ingredients and other product attributes from detail pages.
- `sampleReviews`: Sample reviews included on the product page.
- `changeType`: In monitor mode, `new`, `changed`, or `removed`.
- `sourceType`, `scrapedAt`: Source and capture timestamp.

Run status and summary are stored in the key-value store record `STATUS`.

### FAQ

**Can I get data from the Ulta API?**\
This Actor reads public product information from Ulta web pages. It does not use a private or authenticated API.

**Does it return contact or personal data?**\
No. It returns product catalog data such as titles, prices, ratings, availability, and public product page content.

**Why are some fields empty?**\
Not every page exposes every field. Search and category pages provide listing-level data; product detail pages provide richer fields such as description, ingredients, and sample reviews when present.

**Can I monitor price or stock changes?**\
Yes. Use `mode` = `monitor` with the same `query` on a schedule. Each run stores state in a named key-value store and returns only new, changed, or removed products.

**Is scraping allowed?**\
Only collect data you have the right to use and follow applicable laws and Ulta's terms. Use reasonable request rates and avoid collecting personal data.

### Datos de productos de Ulta

Este Actor extrae datos públicos de productos de Ulta Beauty (precios, valoraciones, disponibilidad e información del producto) desde páginas de búsqueda o categorías. Puede ejecutarse en modo descubrimiento, detalle o monitor para detectar cambios.

### Use it from AI agents (MCP) and Python

**AI agents.** Add this Actor as a tool in Claude, Cursor, VS Code or any MCP client through the Apify MCP server. The agent reads the input schema, so a plain request is enough.

```json
{
  "mcpServers": {
    "ulta-scraper": {
      "url": "https://mcp.apify.com?tools=redomic/ulta-scraper",
      "headers": {
        "Authorization": "Bearer <YOUR_APIFY_TOKEN>"
      }
    }
  }
}
```

**Python.** `pip install apify-client`, then:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("redomic/ulta-scraper").call(run_input={"query": "mascara", "mode": "discovery"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### More from us

- [Allabolag Scraper - Swedish Company Data](https://apify.com/redomic/allabolag-company-scraper): Scrape allabolag.se for Swedish company financials, industry, status and board role titles by search, org number or URL
- [Ashby Jobs Scraper with Salaries](https://apify.com/redomic/ashby-jobs-monitor): Ashby jobs scraper for any startup careers board (OpenAI, Ramp, Notion and thousands more), with salary ranges as numbers: min, max, currency, period, plus equity and bonus flags
- [ATS Jobs Search: Greenhouse, Lever & Ashby Jobs API](https://apify.com/redomic/ats-jobs-search): Search 300,000+ open jobs from 11,000+ companies on Greenhouse, Lever and Ashby in one run
- [Blocket Scraper: Car Monitor](https://apify.com/redomic/blocket-se-scraper): Blocket scraper: each run returns up to 2,500 Blocket Bil and Torget listings as flat rows with price, make, model, year, mileage, VIN, inspections and seller
- [Closed Jobs Tracker: Filled Roles & Time-to-Fill](https://apify.com/redomic/closed-jobs-tracker): Search closed jobs from 11,000+ companies with closedOn, daysOpen and time-to-fill signals
- [Google Jobs Scraper - Job Postings API](https://apify.com/redomic/google-jobs): Google Jobs and job postings scraper: get job title, company, location, posted date, salary, full description and every apply link for any search
- [Google Trends API: Trending Now & Interest Over Time](https://apify.com/redomic/google-trends): Trending-now searches and new-trends alerts/monitoring per country with the news behind them, plus interest over time, interest by region, and related and rising queries for any keyword
- [GovDeals Scraper](https://apify.com/redomic/govdeals-scraper): Search and monitor GovDeals government surplus auctions
- [Greenhouse Jobs Monitor & Scraper](https://apify.com/redomic/greenhouse-jobs-monitor): Monitor Greenhouse jobs from any company careers board (Airbnb, Stripe, Discord and thousands more)
- [Job Postings Dataset: 320k+ Open Jobs, Updated Daily](https://apify.com/redomic/job-postings-dataset): 320,000+ open jobs from 10,000+ company career sites (Greenhouse, Lever, Ashby), updated daily with first-seen and closed dates
- [Lever Jobs Scraper with Salaries](https://apify.com/redomic/lever-jobs-monitor): Lever jobs scraper for any company's careers page (Palantir, Spotify, Zoox, Shield AI and thousands more): flat rows with title, team, location, workplace, commitment, apply link, salary as numbers and the full description merged
- [Marktplaats.nl Scraper](https://apify.com/redomic/marktplaats-nl): Scrape Marktplaats.nl listings into clean rows: title, price in EUR, condition, seller, location, images
- [Otodom Scraper: Poland Property Listings & Price Monitor](https://apify.com/redomic/otodom-scraper): Scrape Otodom.pl property listings in Poland
- [Otomoto.pl Scraper](https://apify.com/redomic/otomoto-scraper): Scrape Otomoto.pl Polish car listings: one run returns used-car rows with price, make, model, year, mileage, fuel, gearbox, seller and URL
- [Personio Jobs Scraper](https://apify.com/redomic/personio-jobs): Scrape open jobs from Personio company career pages (jobs.personio.de/.com XML feeds)
- [Salary Data API: Pay Ranges by Job Title & Level](https://apify.com/redomic/salary-data): Get salary benchmarks (p10-p90, annualised, with n) and pay ranges from 150,000+ employer-posted jobs across 11,000+ companies, updated daily
- [SIRET Company Scraper](https://apify.com/redomic/siret-company-scraper): Search French companies by name, SIREN or SIRET
- [SUUMO Scraper - Japan Property Listings](https://apify.com/redomic/suumo-scraper): Scrape SUUMO Japan property listings from search URLs for rentals and sales
- [Talabat Scraper — Menus, Prices & Delivery Fees](https://apify.com/redomic/talabat-scraper): Talabat menus, prices and delivery fees as flat rows in 8 MENA markets
- [Workday Jobs Scraper](https://apify.com/redomic/workday-jobs): Search and monitor public Workday (myworkdayjobs.com) job postings

# Actor input Schema

## `query` (type: `string`):

A product type or brand (e.g. "mascara", "dry shampoo"), which opens the matching Ulta category or brand page; or a category path (e.g. "/shop/makeup/face/foundation"), a brand page (e.g. "/brand/tarte"), or a full Ulta product or category URL.

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

discovery: list products from a search or category. detail: fetch full details for product URLs/IDs. monitor: report only new, changed, and removed products since the previous run for the same input.

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

Maximum number of products to return.

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

Proxy settings. Use a residential proxy if Ulta blocks datacenter requests.

## Actor input object example

```json
{
  "query": "mascara",
  "mode": "discovery",
  "maxItems": 50,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Product rows from the default dataset.

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

Per-input status rows and a summary record.

# 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 = {
    "query": "mascara",
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("redomic/ulta-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 = {
    "query": "mascara",
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("redomic/ulta-scraper").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 '{
  "query": "mascara",
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call redomic/ulta-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,redomic/ulta-scraper"
        }
    }
}
```

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/QesyHquAFicVRypNQ/builds/AeqsuSOoWKJ9Tv9kk/openapi.json
