# Saks Fifth Avenue Scraper — luxury product prices (`xhrdev/saks-scraper`) Actor

Scrape Saks Fifth Avenue product grids past DataDome: designer, product name, price, sale price, product ID and image. Search by keyword or pass category URLs. No browser. Powered by xhr.dev.

- **URL**: https://apify.com/xhrdev/saks-scraper.md
- **Developed by:** [xhrdev](https://apify.com/xhrdev) (community)
- **Categories:** E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 products

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

**Scrape [Saks Fifth Avenue](https://www.saksfifthavenue.com) product grids past DataDome**: designer, product name, price, original price when it's on sale, product ID, product URL and image. Search by keyword or pass category URLs with the site's own filters applied.

No browser is launched. [xhr.dev](https://xhr.dev) solves the DataDome challenge as plain HTTP, so a page of around 23 products costs a few hundred milliseconds of compute. Runs on Apify, so you get API access, scheduling, integrations and monitoring with no extra setup.

### Quickstart

```json
{
  "queries": ["dress"],
  "maxPagesPerQuery": 2
}
```

### Why use Saks Fifth Avenue Scraper?

- **Luxury price monitoring.** Track what a designer's line sells for at Saks, and catch markdowns as they happen.
- **Assortment research.** See which designers Saks carries in a category, and how deep.
- **Competitive pricing.** Compare against your own catalog or other retailers on product ID and name.

### How to use it

1. Click **Try for free**.
2. Enter search keywords, or paste category URLs copied from your browser after filtering (designer, size, price, sort).
3. Set **Pages per search**. Each page holds around 23 products.
4. Leave the proxy on **Residential** (see below) and click **Start**.
5. Download results from the **Output** tab.

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `queries` | string\[] | `["dress"]` | Keywords, each run as its own search. |
| `startUrls` | array | `[]` | Category (`/c/...`) or search URLs. Product pages are refused up front. See below. |
| `maxPagesPerQuery` | integer | `1` | How deep to page each search, 1–50. |
| `maxItems` | integer | `100` | Stop once this many products have been scraped. |
| `proxyConfiguration` | object | Apify RESIDENTIAL | Keep it on Residential. See below. |
| `maxRetries` | integer | `3` | Attempts per page, 1–5. Each takes a fresh proxy session. |
| `timeoutSecs` | integer | `120` | Deadline per page, challenge and all. |
| `maxConcurrency` | integer | `4` | Pages in flight at once, 1–10. |

### Output

One dataset item per product. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Saks product ID, e.g. `0400026376195`. |
| `brand` | string | Designer. |
| `name` | string | Product name. |
| `price` | number | Current price. |
| `originalPrice` | number | Price before markdown, only when it is on sale. |
| `currency` | string | Always `USD`. |
| `url` | string | Product page URL. |
| `image` | string | Main product image. |

#### Example record

```json
{
  "id": "0400026376195",
  "brand": "Prada",
  "name": "Belted Denim Dress",
  "url": "https://www.saksfifthavenue.com/product/prada-belted-denim-dress-0400026376195.html",
  "price": 1990,
  "currency": "USD",
  "image": "https://cdn.saksfifthavenue.com/is/image/saks/0400026376195_BLUE?wid=510&hei=680&qlt=70&resMode=sharp2&op_usm=1.2,1,6,0"
}
```

#### Why there are no product-page details

The grid already carries designer, name, price and image. Saks' product pages are a JavaScript app whose data arrives as a streamed payload rather than markup, and a parser built on that would break the first time Saks reshaped the stream. This Actor reads only what it can read reliably.

### Proxies: keep it on Residential

Saks bans Apify's own address outright. DataDome answers it with an IP ban rather than a challenge, so there is nothing to solve. Through Apify Residential every page cleared when this Actor was verified, covering search, page 2 and category grids. Each attempt takes a fresh residential session.

### How much does it cost to scrape Saks Fifth Avenue?

**$3.00 per 1,000 products** (`listing-item`), charged only on rows that reach your dataset. Residential proxy traffic is billed by Apify on top. One grid page is a couple of megabytes, so expect roughly $0.50–1.00 of proxy per 1,000 products.

### Tips

- **Filter on the site, then paste the URL.** Designer, size and price filters stay in the category URL.
- **Set `maxTotalChargeUsd`** on the run for a hard spend cap.

### Limits and failure behaviour

- **100 pages per run**, hard. Split bigger jobs across runs.
- **Failures never enter the dataset.** Each run writes a `RUN_SUMMARY` record to the key-value store explaining what failed and why.
- **Pagination is never speculative.** Later pages are fetched only once page 1 confirms they exist.
- **Category URLs are read one page at a time.** To go deeper in a category, add its `?start=24&sz=24`, `?start=48&sz=24` and later URLs, or use a keyword search with `maxPagesPerQuery`.

### FAQ

**Is scraping Saks legal?** This Actor reads public product listings and no personal data. Check Saks' terms and the law where you operate before running at scale.

**Is this affiliated with Saks Fifth Avenue?** No. It is an independent tool with no connection to Saks or any bot-protection vendor.

**Something broke?** Open an issue on the **Issues** tab. For volume or a custom build, reach us through [xhr.dev](https://xhr.dev).

### Related Actors

- **[DataDome Unblocker](https://apify.com/xhrdev/datadome-unblocker)**: any URL behind DataDome, returning HTML plus clearance cookies.
- **[Yelp Scraper](https://apify.com/xhrdev/yelp-scraper)**: local business listings.
- **[Anthropologie Scraper](https://apify.com/xhrdev/anthropologie-scraper)**, **[Etsy Scraper](https://apify.com/xhrdev/etsy-scraper)**, **[Grainger Scraper](https://apify.com/xhrdev/grainger-scraper)**, **[leboncoin Scraper](https://apify.com/xhrdev/leboncoin-scraper)**.

***

Built by [xhr.dev](https://xhr.dev). Independent tool, not affiliated with Saks Fifth Avenue or any bot-protection vendor.

# Actor input Schema

## `queries` (type: `array`):

What to search Saks Fifth Avenue for. Each keyword is run as its own search, exactly as if typed into the site's search box.

## `startUrls` (type: `array`):

Saks category (/c/...) or search URLs to scrape, for when you want the site's own filters — designer, size, price, sort. Copy the URL out of your browser. Product pages are not supported; the grid carries brand, name, price and image already.

## `maxPagesPerQuery` (type: `integer`):

How deep to page through each search, roughly 23 products a page. Pages beyond the first are only fetched once the site confirms they exist.

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

Stop once this many products have been scraped, across everything in this run.

## `proxyConfiguration` (type: `object`):

Keep this on RESIDENTIAL for Saks. It bans Apify's own address outright (DataDome answers with an IP ban, not a challenge), while through Residential every page cleared when this Actor was verified.

## `maxRetries` (type: `integer`):

How many times to try a page before giving up on it. Each attempt takes a fresh proxy session, so a dead exit node or a burnt IP gets a genuinely new chance.

## `timeoutSecs` (type: `integer`):

How long one page — challenge, solve and all — may take before it counts as a failed attempt.

## `maxConcurrency` (type: `integer`):

How many pages to work on at once. The solve path is HTTP-only and cheap, so this can go higher than a browser scraper would allow, but be a considerate guest on someone else's site.

## Actor input object example

```json
{
  "queries": [
    "dress"
  ],
  "startUrls": [],
  "maxPagesPerQuery": 1,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxRetries": 3,
  "timeoutSecs": 120,
  "maxConcurrency": 4
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "queries": [
        "dress"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("xhrdev/saks-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 = { "queries": ["dress"] }

# Run the Actor and wait for it to finish
run = client.actor("xhrdev/saks-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 '{
  "queries": [
    "dress"
  ]
}' |
apify call xhrdev/saks-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xhrdev/saks-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/ddE27AQfzMaWbOmPl/builds/stadWAOe4VlIP8lCA/openapi.json
