# Ulta Beauty Store Locator Scraper - All US Locations (`datacach/ulta-store-locator-scraper`) Actor

Extracts all Ulta Beauty US store locator URLs and coordinates from the official sitemap. Fast, no browser needed. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/datacach/ulta-store-locator-scraper.md
- **Developed by:** [DataCach](https://apify.com/datacach) (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.50 / 1,000 links

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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 Store Locator Scraper - All US Locations

Extract every **Ulta Beauty store URL** in the United States — fast, no browser required, ready for **JSON, CSV, or Excel** export.

### What is Ulta Beauty Store Locator Scraper?

Ulta Beauty Store Locator Scraper is an [Apify Actor](https://apify.com) that **collects the page URL of every Ulta Beauty store in the US** (~1,500 locations) directly from Ulta's official store directory data. It runs as a lightweight HTTP-based scraper — **no headless browser needed** — so a full run of all US store links finishes in seconds. No search terms, ZIP codes, or coordinates are required: click **Start** and get the complete Ulta store list.

It pairs naturally with a follow-up **Ulta Beauty Store Metadata** Actor that takes these URLs and enriches them with full address, phone number, geolocation, and store hours.

### What can Ulta Beauty Store Locator Scraper do?

- 🏬 **Extract all ~1,500 Ulta Beauty US store page URLs** in a single run
- ⚡ **No browser required** — pure HTTP scraping means fast, low-cost runs
- 📄 **Export data** instantly as **JSON, CSV, Excel, HTML**, or via the Apify API
- ⏱️ Every item is stamped with an **extraction timestamp** (`extraction_datetime`, `extraction_date`) so you always know how fresh your data is
- 📌 **Paginate across runs** with `startIndex` and skip URLs you already have with `excludeUrls` — avoid re-collecting (and re-paying for) links you've already saved under pay-per-result pricing
- 🔢 Cap output size with `maxResults` for smaller, cheaper test runs
- ☁️ Runs on the **Apify platform** — schedule recurring runs, trigger via **API**, connect to **Zapier / Make** integrations, monitor run history, and use **Apify Proxy** for reliability at scale

### What data does Ulta Beauty Store Locator Scraper extract?

| Field | Description | Example |
|---|---|---|
| `url` | Ulta Beauty store page URL | `https://www.ulta.com/stores/abilene-tx-409` |
| `coordinate` | Internal source label for the link (informational) | `static source` |
| `extraction_datetime` | UTC timestamp when the link was extracted (ISO 8601) | `2026-07-21T14:30:00.123456+00:00` |
| `extraction_date` | Extraction date in `mm-dd-yyyy` format | `07-21-2026` |

### How do I scrape Ulta Beauty store locations?

1. Open the Actor's **Input** tab (no configuration is required for a full run).
2. Optionally set **Max results** to limit how many store links are collected, or leave it at `0` to collect all ~1,500 US stores.
3. Optionally use **Start index** and **Exclude URLs** if you're paginating across multiple runs and want to skip links you already collected.
4. Click **Start**.
5. When the run finishes, open the **Output** tab (or the **Dataset** in the Apify Console) and export your results as JSON, CSV, Excel, or HTML — or pull them programmatically via the **Apify API**.

<!-- TODO: embed a short demo video or GIF of a run here, e.g. https://www.youtube.com/watch?v=XXXXXXXXXXX -->

### Input

The Actor needs **no input to run** — just click Start to collect all US Ulta Beauty store links. Optional fields let you control scope and avoid duplicate collection:

- **Max results** (`maxResults`) — the maximum number of unique store links to save. `0` (default) collects every store (~1,500 links).
- **Start index** (`startIndex`) — skip this many store links from the start of the list before saving any. Useful for resuming a paginated collection across runs.
- **Exclude URLs (already collected)** (`excludeUrls`) — a list of store URLs you already have; these are never saved again, regardless of position.

<!-- TODO: add a screenshot of the Input tab / input schema form here -->

Note: free-plan runs are automatically capped to a small sample of store links, with `startIndex` and `excludeUrls` limited accordingly. Upgrade your Apify plan to remove these limits.

### Output example

```json
{
  "url": "https://www.ulta.com/stores/abilene-tx-409",
  "coordinate": "static source",
  "extraction_datetime": "2026-07-21T14:30:00.123456+00:00",
  "extraction_date": "07-21-2026"
}
````

Every run produces one dataset item per store URL. You can download the dataset in various formats such as **JSON, HTML, CSV, or Excel**, or fetch it programmatically through the Apify API for automation and integrations.

### Use cases

- 📍 **Build a complete Ulta Beauty store directory** for market research, competitor mapping, or retail analytics.
- 🔗 **Feed store URLs into a downstream scraper** (like the companion [Ulta Beauty Store Details Scraper](https://apify.com/datacach/ulta-beauty-store-details-scraper)) to enrich each location with address, phone, hours, and geolocation.
- 🗺️ **Power a store locator widget or map** on an internal dashboard or web app with up-to-date Ulta store links.
- 📊 **Track new store openings** by running the Actor on a schedule and diffing results against previous extraction dates.
- 🤖 **Automate retail data pipelines** by connecting this Actor's dataset to Zapier, Make, or a custom API integration.

### Ulta Beauty-related Actors

| Actor | What it does |
|---|---|
| [Ulta Beauty Store Details Scraper](https://apify.com/datacach/ulta-beauty-store-details-scraper) | Takes store URLs and extracts full address, phone, hours, and geolocation |

### FAQ

#### Is it legal to scrape Ulta Beauty store locations?

This Actor only collects **publicly available store URLs** that Ulta Beauty already exposes for anyone (and search engines) to access — no login, no private data, and no personal information is collected. That said, scraping any website may be subject to that site's Terms of Service, so review Ulta's terms and consult legal counsel if you plan to use the data commercially. See the Apify blog's [guide on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for more background.

#### How many Ulta Beauty stores does this Actor return?

A full run (with `maxResults` set to `0`) returns the page URL of every US Ulta Beauty store — roughly 1,500 locations at the time of writing. The exact count fluctuates slightly as Ulta opens or closes stores.

#### Does this Actor use a browser?

No. It fetches store data over plain HTTP without launching a browser, which keeps runs fast and compute-efficient.

#### Can I access this data through an API?

Yes. Every Apify Actor run and its resulting dataset are available through the [Apify API](https://docs.apify.com/api/v2), so you can trigger runs and retrieve store links programmatically, or connect the Actor to **Zapier**, **Make**, or your own backend.

#### Can I schedule this Actor to run automatically?

Yes. Use the Apify platform's built-in **Scheduler** to run this Actor daily, weekly, or on any custom cron schedule, and monitor results from the Apify Console or via webhooks.

#### Why do I see fewer results than expected?

If Ulta's servers temporarily block automated requests, the run stops with a clear status message instead of returning partial or inaccurate data. Simply re-run the Actor — this is uncommon and usually resolves on retry.

### Support

Found a bug or have a feature request? Open an issue on the Actor's **Issues** tab in Apify Console. Need a custom version of this scraper — more fields, other regions, or a fully custom retail data pipeline? Reach out through the Actor's contact page in the Apify Store for a tailored solution.

# Actor input Schema

## `maxResults` (type: `integer`):

The maximum number of unique store links to save from the sitemap. Set to <b>0</b> to collect every store (~1,500 links). Combined with <b>Start index</b>, the saved range is \[startIndex, startIndex + maxResults). Free plan runs are capped at 10 links.

## `startIndex` (type: `integer`):

Skip this many store links from the <b>start</b> of the sitemap before saving any. Use this to paginate across runs — for example, if you already saved the first 500 links, set this to <b>500</b> to resume from link 501 without re-paying for links you already have. The sitemap is read in a stable document order, so the same index always points to the same store between runs. Note: the Actor still walks the sitemap up to this point internally, so a large value changes which links are saved but does not speed up the run. Forced to 0 on the free plan.

## `excludeUrls` (type: `array`):

Store link URLs you already have from a previous run. Any URL listed here is never saved again, no matter where it falls in the sitemap order. Unlike <b>Start index</b>, this works regardless of position — ideal when you keep a running list of collected stores and only want the new ones. Applied after <b>Start index</b>. Example: <code>https://www.ulta.com/stores/abilene-tx-409</code>. Free plan runs may list at most 1 URL here.

## Actor input object example

```json
{
  "maxResults": 0,
  "startIndex": 500,
  "excludeUrls": [
    "https://www.ulta.com/stores/abilene-tx-409"
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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 = {
    "startIndex": 500,
    "excludeUrls": [
        "https://www.ulta.com/stores/abilene-tx-409"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datacach/ulta-store-locator-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 = {
    "startIndex": 500,
    "excludeUrls": ["https://www.ulta.com/stores/abilene-tx-409"],
}

# Run the Actor and wait for it to finish
run = client.actor("datacach/ulta-store-locator-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 '{
  "startIndex": 500,
  "excludeUrls": [
    "https://www.ulta.com/stores/abilene-tx-409"
  ]
}' |
apify call datacach/ulta-store-locator-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ulta Beauty Store Locator Scraper - All US Locations",
        "description": "Extracts all Ulta Beauty US store locator URLs and coordinates from the official sitemap. Fast, no browser needed. Export to JSON, CSV, or Excel.",
        "version": "0.0",
        "x-build-id": "Pyc5lUJG8qXVSHQ3j"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/datacach~ulta-store-locator-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-datacach-ulta-store-locator-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/datacach~ulta-store-locator-scraper/runs": {
            "post": {
                "operationId": "runs-sync-datacach-ulta-store-locator-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/datacach~ulta-store-locator-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-datacach-ulta-store-locator-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": {
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 0,
                        "type": "integer",
                        "description": "The maximum number of unique store links to save from the sitemap. Set to <b>0</b> to collect every store (~1,500 links). Combined with <b>Start index</b>, the saved range is [startIndex, startIndex + maxResults). Free plan runs are capped at 10 links.",
                        "default": 0
                    },
                    "startIndex": {
                        "title": "Start index",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Skip this many store links from the <b>start</b> of the sitemap before saving any. Use this to paginate across runs — for example, if you already saved the first 500 links, set this to <b>500</b> to resume from link 501 without re-paying for links you already have. The sitemap is read in a stable document order, so the same index always points to the same store between runs. Note: the Actor still walks the sitemap up to this point internally, so a large value changes which links are saved but does not speed up the run. Forced to 0 on the free plan.",
                        "default": 0
                    },
                    "excludeUrls": {
                        "title": "Exclude URLs (already collected)",
                        "type": "array",
                        "description": "Store link URLs you already have from a previous run. Any URL listed here is never saved again, no matter where it falls in the sitemap order. Unlike <b>Start index</b>, this works regardless of position — ideal when you keep a running list of collected stores and only want the new ones. Applied after <b>Start index</b>. Example: <code>https://www.ulta.com/stores/abilene-tx-409</code>. Free plan runs may list at most 1 URL here.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
