# Macy's Scraper (`crawlerbros/macys-scraper`) Actor

Scrape Macy's (macys.com) - search products by keyword, browse department/category listings, or fetch full product detail (variants, prices, sizes, colors, images, ratings) by product ID. No login, cookies, or API key required.

- **URL**: https://apify.com/crawlerbros/macys-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Macy's Scraper

Scrape [Macy's](https://www.macys.com) — search products by keyword, browse a department/category listing, or fetch full product detail (variants, prices, sizes, colors, images, ratings) by product ID. No login, cookies, proxy, or API key required.

### What this actor does

- **Three modes:** `search` (keyword), `category` (department/category browse), `product` (full detail by ID)
- **Sort orders:** Featured, Price Low→High, Price High→Low, Top Rated, Best Sellers, New Arrivals
- **Filters:** min/max price, min rating, on-sale-only, brand contains, exclude sponsored/featured listings
- **Full product detail:** every color/size/SKU variant with its own price and stock status, description, category, images, aggregate rating
- **Empty fields are omitted** — every field in the output is real data, never `null` or placeholders

### Output per product (search / category mode)

- `productId` — Macy's numeric product ID
- `title`, `brand`
- `url` — canonical product page URL
- `imageUrl`
- `price`, `currency`, `originalPrice`, `discountPercent` (when on sale)
- `ratingValue`, `reviewCount`
- `badge` — promotional tag shown on the listing tile (e.g. `Clearance`, `Limited-Time Special`, `Today Only`), when present
- `promoBadge` — loyalty/rewards promo text shown on the listing tile (e.g. `$10 Star Money per $50`), when present
- `isSponsored` — `true` if this is a paid-placement tile Macy's inserts into the listing grid out of the requested sort order
- `sourceMode`, `sourceQuery` — which mode/query produced this record
- `sourceUrl` — the listing page URL this record was found on
- `recordType: "product"`, `scrapedAt`

### Output per product (product mode — full detail)

- `productId`, `title`, `brand`, `category`, `description`
- `breadcrumbs[]` — full category navigation trail (e.g. `["Women's Fashion, Shoes & Accessories", "Flats"]`), more granular than `category`
- `features[]` — bulleted product detail specs from the page (material, closure type, fit, care instructions, style number), when present
- `images[]`, `imageUrl` (first image)
- `variants[]` — each with `sku`, `color`, `size`, `price`, `inStock`
- `colors[]`, `sizes[]` — unique lists across all variants
- `minPrice`, `maxPrice`, `price` (= minPrice), `currency`
- `originalPrice`, `discountPercent` — pre-sale price and markdown %, when the product is discounted
- `inStock` — true if any variant is in stock
- `ratingValue`, `reviewCount`
- `ratingDistribution[]` — per-star review-count breakdown, each `{stars, count}` (5-star down to 1-star), when reviews exist
- `fitInsights[]` — crowd-sourced fit ratings, each `{aspect, rating}` (e.g. `{"aspect": "Runs narrow/runs wide", "rating": "Neutral"}`), when enough reviews carry fit data (mostly footwear/apparel)
- `reviews[]` — (only when `includeReviews=true`) each with `author`, `date`, `title`, `text`, `ratingValue`, `bestRating`
- `url`, `sourceUrl` — canonical product page URL
- `recordType: "productDetail"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search` / `category` / `product` |
| `searchQuery` | string | `womens dresses` | Free-text keyword (mode=search) |
| `categoryPath` | select/text | – | Department/category path (mode=category), e.g. `womens-clothing`, `mens/shoes?id=55822`, or paste any Macy's category URL |
| `productIds` | array | – | Numeric product IDs or product page URLs (mode=product) |
| `sortBy` | select | `ORIGINAL` | Sort order for `search`/`category` listings |
| `minPrice` / `maxPrice` | integer | – | Price range filter (USD) |
| `minRating` | integer | – | Minimum review rating (0–5) |
| `onSaleOnly` | boolean | `false` | Only emit discounted products |
| `excludeSponsored` | boolean | `false` | Drop paid-placement/"featured" tiles that ignore the requested sort order |
| `brand` | string | – | Case-insensitive brand substring filter |
| `includeReviews` | boolean | `false` | Include a `reviews[]` array (mode=product) |
| `maxItems` | integer | `50` | Hard cap (1–1000) |

#### Example: search for running shoes under $100, top rated

```json
{
  "mode": "search",
  "searchQuery": "running shoes",
  "sortBy": "TOP_RATED",
  "maxPrice": 100,
  "maxItems": 50
}
```

#### Example: browse men's shoes on sale

```json
{
  "mode": "category",
  "categoryPath": "mens/shoes?id=55822",
  "onSaleOnly": true,
  "maxItems": 60
}
```

#### Example: full product detail lookup

```json
{
  "mode": "product",
  "productIds": ["20663500", "https://www.macys.com/shop/product/easy-street-womens-fresh-slip-on-sneakers?ID=11081206"],
  "includeReviews": true
}
```

### Use cases

- **Price monitoring** — track sale prices and discount percentages over time
- **Assortment research** — pull a full department listing to analyze brand mix and pricing
- **Product data enrichment** — resolve a list of product IDs into full variant/SKU-level catalog data
- **Competitive intelligence** — compare pricing and availability across brands and categories
- **Size/color availability tracking** — monitor stock status per SKU for a watched product

### FAQ

**Do I need to log in or provide cookies?** No — every mode works against Macy's public, unauthenticated pages.

**What's the difference between `search` and `category` mode?** `search` runs a free-text keyword query (like the site's search bar). `category` browses a fixed department/category listing (like clicking through the site's navigation menu).

**Can I use a category URL that isn't in the dropdown?** Yes — the dropdown lists common departments for convenience, but `categoryPath` accepts any `macys.com/shop/...` category path or full URL.

**Why does `product` mode return more fields than `search`/`category`?** Listing pages only expose a summary card. Product-detail mode fetches the individual product page, which contains the full JSON-LD dataset — every color/size variant, SKU, stock status, and description.

**Are prices real-time?** Yes — every run fetches Macy's live pages; prices, discounts, and stock status reflect what's on the site at scrape time.

**What currency are prices in?** USD — Macy's is a US retailer.

**Is there a rate limit?** The actor paces its requests to Macy's public pages so it stays reliable without needing a proxy.

# Actor input Schema

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

What to fetch.

## `searchQuery` (type: `string`):

Free-text keyword search (mode=search), e.g. `womens dresses`, `running shoes`, `mens suit`.

## `categoryPath` (type: `string`):

A Macy's category/department path. Pick a common one from the dropdown-style examples below, or paste any `macys.com/shop/...` category URL / path.

## `productIds` (type: `array`):

Macy's numeric product IDs (e.g. `20663500`) or full product page URLs.

## `sortBy` (type: `string`):

Sort order for listing results.

## `minPrice` (type: `integer`):

Drop products priced below this amount.

## `maxPrice` (type: `integer`):

Drop products priced above this amount.

## `minRating` (type: `integer`):

Drop products with a review rating below this value.

## `onSaleOnly` (type: `boolean`):

Only emit products that are currently discounted from an original price.

## `excludeSponsored` (type: `boolean`):

Macy's interleaves paid-placement ("featured") tiles into search/category listings that ignore the requested sort order (e.g. a pricier sponsored item can appear mid-way through a Price: Low to High sort). Enable to drop these and keep only organically-ranked/sorted results.

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

Case-insensitive substring match against the product brand (e.g. `Nike`, `Ralph Lauren`).

## `includeReviews` (type: `boolean`):

When true, `product` mode also emits a `reviews[]` array (author, date, title, text, rating) parsed from the product page's review data. Off by default to keep records compact.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "womens dresses",
  "productIds": [],
  "sortBy": "ORIGINAL",
  "onSaleOnly": false,
  "excludeSponsored": false,
  "includeReviews": false,
  "maxItems": 50
}
```

# Actor output Schema

## `products` (type: `string`):

Dataset containing all scraped Macy's products.

# 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 = {
    "mode": "search",
    "searchQuery": "womens dresses",
    "productIds": [],
    "sortBy": "ORIGINAL",
    "onSaleOnly": false,
    "excludeSponsored": false,
    "includeReviews": false,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/macys-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 = {
    "mode": "search",
    "searchQuery": "womens dresses",
    "productIds": [],
    "sortBy": "ORIGINAL",
    "onSaleOnly": False,
    "excludeSponsored": False,
    "includeReviews": False,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/macys-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 '{
  "mode": "search",
  "searchQuery": "womens dresses",
  "productIds": [],
  "sortBy": "ORIGINAL",
  "onSaleOnly": false,
  "excludeSponsored": false,
  "includeReviews": false,
  "maxItems": 50
}' |
apify call crawlerbros/macys-scraper --silent --output-dataset

```

## MCP server setup

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