# Wayfair Scraper · Products, Prices, Stock & Ratings (`memo23/wayfair-scraper`) Actor

Scrape Wayfair products from wayfair.com, .ca, .co.uk and .ie. Paste a keyword, category, brand, SKU or listing/product URL. Each row is SKU, title, brand, price, discount %, stock, variant count, rating and image. Optional PDP specs, dimensions and materials. Pure HTTP, no browser.

- **URL**: https://apify.com/memo23/wayfair-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce
- **Stats:** 1 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 product results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Wayfair Scraper

Scrape **Wayfair** product listings from the US, Canada, UK and Ireland storefronts. Keyword search, category browse, brand, SKU or any listing/product URL. Each row is one product: SKU, title, brand, price, was-price, discount percent, stock, variant count, rating, image and URL. Turn on `fetchDetails` for specs, dimensions, materials and the product description. Pure HTTP, no browser.

### Why use this scraper

- **Listing cards are complete** — title, brand, sale price, was-price, discount %, variant count, stock, rating, reviews, image and URL come from the search/category page. No per-product crawl unless you ask for it.
- **Four storefronts** — wayfair.com, wayfair.ca, wayfair.co.uk, wayfair.ie.
- **Keyword, category, brand, SKU or URL** — paste what you have; the actor builds the rest.
- **Stock from the listing payload** — `IN_STOCK` / `LOW_STOCK` / `OUT_OF_STOCK` / `BACKORDERED` plus the original inventory sentence (e.g. “615 Left in Stock”).
- **Sale math and variants** — `savings` and `discountPercent` from price vs was-price; `variantCount` from “3 Colors” / “5 Colors, 2 Sizes”.
- **Optional product-page enrichment** — specs table, parsed dimensions, materials, About This Product, feature bullets, delivery, manufacturer URL. One extra request per product, billed only on a hit.
- **Pure HTTP** — Chrome TLS impersonation, no Playwright.

### Use cases

| Who | What they do with the rows |
|---|---|
| Price monitors | Track sale vs was-price across sofas, rugs, lighting |
| Retail / marketplace teams | Build a Wayfair product feed without an official API |
| Brands | Watch how their SKUs are priced and badged on Wayfair |
| Data teams | Category-level assortment, ratings and promo flags |

### Supported inputs

| Input | Example |
|---|---|
| Keyword search | `sofa`, `office chair`, `area rug` |
| Search URL | `https://www.wayfair.com/keyword.php?keyword=sofa` |
| Category URL | `https://www.wayfair.com/furniture/sb0/sofas-c413892.html` |
| Category filter | Furniture, Outdoor, Rugs, Lighting, … |
| Brand | `Latitude Run`, `Wade Logan` |
| SKU | `W100694092`, `CXVA1530` |
| Product URL | `https://www.wayfair.com/furniture/pdp/…-w100694092.html` |

**Not supported:** login-only lists, Wayfair Business / B2B portals, Wayfair.de (shut down).

### Proxy requirement

Wayfair runs PerimeterX. Datacenter IPs and a plain TLS fingerprint get **429 Access denied**. This actor impersonates Chrome 131; **residential proxy is recommended** on Apify. A home IP often works for small local runs.

### How it works

1. Build start URLs from `startUrls`, or from keyword / category / brand / SKU.
2. Fetch each listing page (paginated with `curpage=N`, ~48 products per page).
3. Parse the server-rendered `ListingCard` grid — one row per product.
4. Optionally fetch the product page for specs, dimensions, materials, description, feature bullets and delivery.
5. Apply price / rating / in-stock filters.
6. Push one dataset row per product.

### Input parameters

| Field | Type | Description |
|---|---|---|
| `startUrls` | string\[] | Search, category, brand or product URLs. Wins over the filters below. |
| `searchQuery` | string | Keyword when no URL is given. |
| `country` | enum | `com` / `ca` / `co.uk` / `ie` |
| `category` | enum | Top-level browse (Furniture, Outdoor, …) |
| `brand` | string | Brand name for a brand-scoped search |
| `skus` | string\[] | Wayfair SKUs |
| `sortBy` | enum | Relevance, price, rating, newest, best seller |
| `priceMin` / `priceMax` | number | Drop products outside this price range |
| `ratingMin` | number | Drop products rated below this (unrated are kept) |
| `inStockOnly` | boolean | Keep in-stock / low-stock only |
| `fetchDetails` | boolean | Fetch each product page (extra request + `additional-data` event) |
| `maxItems` | integer | Hard cap on rows |
| `maxPages` | integer | Max listing pages per start URL |
| `proxy` | proxy | Residential recommended |

### Output overview

One row per product. Listing fields (`price`, `previousPrice`, `discountPercent`, `variantCount`, `stockStatus` when the page embeds inventory) are always filled when Wayfair shows them. `specifications`, `dimensions`, `materials`, `description`, `featureBullets` and `brandUrl` fill in when `fetchDetails` is on. Nested arrays stay as arrays; turn `flatten` off only if you want nested JSON as-is (flatten is on by default).

### Output sample

```json
{
  "sku": "W117455547",
  "title": "L-Shaped Sofa With Reversible Chaise, Convertible Couch With Washable Covers, Compact Living Room Furniture For Apartments & Small Spaces",
  "brand": "Latitude Run",
  "productUrl": "https://www.wayfair.com/furniture/pdp/latitude-run-l-shaped-sofa-with-reversible-chaise-convertible-couch-with-washable-covers-compact-living-room-furniture-for-apartments-small-spaces-w117455547.html",
  "price": 329.99,
  "previousPrice": 749.99,
  "savings": 420,
  "discountPercent": 56,
  "currency": "USD",
  "stockStatus": "IN_STOCK",
  "isPurchasable": true,
  "variantCount": 3,
  "rating": 3.4,
  "reviewCount": 17,
  "promoFlag": "Sale",
  "imageUrl": "https://assets.wfcdn.com/im/95483184/resize-h200-w200%5Ecompr-r85/4887/488728918/L-Shaped+Sofa+With+Reversible+Chaise%2C+Convertible+Couch+With+Washable+Covers%2C+Compact+Living+Room+Furniture+For+Apartments+%26+Small+Spaces.jpg",
  "breadcrumbs": ["Furniture", "Living Room Furniture", "Sofas"],
  "category": "Furniture",
  "subCategory": "Sofas",
  "country": "com",
  "siteName": "Wayfair",
  "recordType": "product",
  "sourceUrl": "https://www.wayfair.com/keyword.php?keyword=sofa",
  "detailFetched": false
}
```

### Key output fields

| Field | Description |
|---|---|
| `sku` | Wayfair SKU (`W100694092`, `CXVA1530`) |
| `title` / `brand` | Product name and manufacturer |
| `price` / `previousPrice` / `savings` / `discountPercent` | Current price, was-price, dollars off, percent off |
| `rating` / `reviewCount` | Stars (0–5) and review count |
| `stockStatus` / `isPurchasable` / `inventoryMessage` | Stock enum, shoppable flag, Wayfair's own sentence |
| `variantCount` | Option combinations from the card (“5 Colors, 2 Sizes” → 10) |
| `promoFlag` | Sale, Warehouse Clearout, … |
| `imageUrl` / `productUrl` | Primary image + canonical PDP |
| `breadcrumbs` | Category path from the listing page |
| `specifications` / `dimensions` / `materials` / `description` | Spec table, parsed H×W×D + weight, material list, About This Product — `fetchDetails` |
| `featureBullets` / `brandUrl` / `estimatedDeliveryMessage` | Also filled when `fetchDetails` is on |

### FAQ

**Do I need a Wayfair account?** No. Public listing and product pages only.

**Why is `stockStatus` null?** The listing payload usually carries `shortInventoryStatusMessage` next to the SKU; we map that. A few cards have no inventory blob — those stay null unless you turn on `fetchDetails`. Free-delivery text is not treated as stock.

**US only?** No. Set `country` or paste a `.ca` / `.co.uk` / `.ie` URL.

**429 Access denied?** Use a residential proxy. Datacenter IPs are refused.

**How many products per page?** About 48. `maxPages` caps how far pagination goes.

### Support

Open an issue on the actor's Issues tab if a field is missing or a URL shape fails.

### Additional services

Need richer rows? Turn on **Fetch full product details** for the spec table (overall dimensions, materials, weight), the parsed `dimensions` object, `materials`, About This Product, feature bullets, delivery and the manufacturer page. That path bills the `additional-data` event only when extra fields are actually found.

### Explore more scrapers

See the publisher profile for other catalog and directory scrapers (Etsy, Home Depot, Houzz, Amazon and more).

### 🤖 For AI Agents & LLM Apps

Compact reference for agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/wayfair-scraper`).

**Purpose:** Turn a Wayfair keyword, category, brand, SKU or URL into one product row each — SKU, title, brand, price, rating, image, URL — over HTTP.

**Minimal input:**

```json
{
  "searchQuery": "sofa",
  "country": "com",
  "maxItems": 30
}
```

Or paste URLs:

```json
{
  "startUrls": ["https://www.wayfair.com/furniture/sb0/sofas-c413892.html"],
  "maxItems": 30
}
```

**Output:** one row per product — `sku`, `title`, `brand`, `price`, `previousPrice`, `savings`, `discountPercent`, `currency`, `stockStatus`, `variantCount`, `rating`, `reviewCount`, `promoFlag`, `imageUrl`, `productUrl`, `breadcrumbs`, `country`, `scrapedAt`. `fetchDetails` adds `specifications`, `dimensions`, `materials`, `description`, `featureBullets`, `brandUrl`, `estimatedDeliveryMessage`.

**Behaviors an agent should know:**

- Always set `maxItems`. Each listing page is ~48 products and paginates with `curpage=N`.
- `startUrls` wins over keyword/category/brand/SKU.
- Residential proxy is the safe default on Apify. Datacenter IPs often get 429.
- `fetchDetails` (off) is one extra request per product and charges `additional-data` only on a hit.
- Pay-per-event billing — see the Pricing tab.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Wayfair LLC or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available product pages — no authenticated endpoints or content behind a Wayfair login. Users are responsible for ensuring their use complies with Wayfair's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.

***

### SEO Keywords

Wayfair scraper, scrape Wayfair, Wayfair API, Apify Wayfair, Wayfair product scraper, Wayfair price scraper, furniture price data, Wayfair.ca scraper, Wayfair.co.uk scraper, home goods product feed, Wayfair SKU lookup, Wayfair category scrape, Wayfair stock status, Wayfair ratings scraper, crawlerbros Wayfair alternative

# Actor input Schema

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

Search, category, brand or product URLs on wayfair.com / .ca / .co.uk / .ie. Each listing URL is paginated until Maximum items is reached. When this is set, keyword/category/brand/SKU below are ignored.

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

Used only when Wayfair URLs is empty. Examples: sofa, office chair, area rug.

## `country` (type: `string`):

Regional storefront used when building a search/category/brand URL. Ignored when you paste a full URL — the domain on the URL wins.

## `category` (type: `string`):

Top-level Wayfair category browse. Used only when Wayfair URLs is empty.

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

Brand / manufacturer name (e.g. Latitude Run, Wade Logan). Used only when Wayfair URLs is empty.

## `skus` (type: `array`):

Wayfair SKUs such as W100694092 or CXVA1530. Each is resolved via Wayfair search. Used only when Wayfair URLs is empty.

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

Sort order applied to keyword/category/brand listing URLs.

## `priceMin` (type: `integer`):

Drop products priced below this amount (in the storefront currency).

## `priceMax` (type: `integer`):

Drop products priced above this amount (in the storefront currency).

## `ratingMin` (type: `number`):

Drop products with a rating below this value (0–5). Products with no rating are kept.

## `inStockOnly` (type: `boolean`):

Keep only products Wayfair marks as in stock or low stock. Products with no stock evidence are kept.

## `fetchDetails` (type: `boolean`):

For each listing card, fetch the product page for specs, dimensions, materials, description, feature bullets, delivery estimate, manufacturer URL and a sharper stock read. Adds one HTTP request per product and bills the additional-data event when extra fields are found.

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

Hard cap on product rows written to the dataset.

## `maxPages` (type: `integer`):

Maximum paginated listing pages (curpage=N) to crawl per start URL. About 48 products per page.

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

Wayfair runs PerimeterX and blocks many datacenter IPs. Residential proxy is recommended. Leave blank to use the actor default.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.wayfair.com/keyword.php?keyword=sofa"
  ],
  "searchQuery": "sofa",
  "country": "com",
  "brand": "Latitude Run",
  "sortBy": "relevance",
  "inStockOnly": false,
  "fetchDetails": false,
  "maxItems": 10,
  "maxPages": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One row per product: SKU, title, brand, price, discount, stock, variant count, specs, image and URL.

# 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 = {
    "startUrls": [
        "https://www.wayfair.com/keyword.php?keyword=sofa"
    ],
    "searchQuery": "sofa",
    "maxItems": 10,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/wayfair-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 = {
    "startUrls": ["https://www.wayfair.com/keyword.php?keyword=sofa"],
    "searchQuery": "sofa",
    "maxItems": 10,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/wayfair-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 '{
  "startUrls": [
    "https://www.wayfair.com/keyword.php?keyword=sofa"
  ],
  "searchQuery": "sofa",
  "maxItems": 10,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call memo23/wayfair-scraper --silent --output-dataset

```

## MCP server setup

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