# Sur La Table Kitchenware Scraper (`crawlerbros/sur-la-table-scraper`) Actor

Scrape Sur La Table (surlatable.com) kitchenware. Browse 60+ departments or search, filter by brand/material/color/size/price/rating/discount, and get pricing, sale discounts, images, videos, variants, ratings, promotions, and full product-detail lookups by ID.

- **URL**: https://apify.com/crawlerbros/sur-la-table-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, E-commerce, Agents
- **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/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

## Sur La Table Kitchenware Scraper

Scrape **Sur La Table** (surlatable.com) — the specialty kitchenware and cookware retailer. Browse any of 65+ departments and subcategories (cookware, bakeware, knives, small appliances, dining & bar, kitchen tools, coffee & tea, outdoor, and more), run a keyword search, or look up specific products by ID. Get real-time pricing (including sale/markdown discounts), brand, images, color/material/size variants, ratings, and full product-detail fields. No login, no cookies, no proxy required.

### What this actor does

- **Three modes:** `byCategory`, `search`, `byProductId`
- **65+ browsable categories** covering every department — Cookware, Bakeware, Knives, Small Appliances, Dining & Bar, Kitchen Tools, Kitchen & Decor, Food, Outdoor, Coffee & Tea
- **Filters:** brand, material, color, size, price range, minimum rating, minimum discount % — brand/material/color/price/discount are applied server-side by the retailer's own search; rating and size are additionally guaranteed by the actor itself (the site's own `rating` and `size` refinement parameters don't reliably narrow results server-side, so both are enforced against each product's actual data before it's returned)
- **Sort:** price, name, discount, rating, review count (applied after fetching, since the site's own sort parameter is not honored server-side)
- **Automatic subcategory expansion** — when a category holds more products than fit in one fetch, the actor automatically walks into its subcategories to keep collecting toward `maxItems`, deduplicating by product ID
- **Empty fields are omitted**

### Output per product

#### List mode (`byCategory` / `search`)

- `productId`, `masterProductId`
- `name`, `brand`
- `productUrl`, `sourceUrl`, `imageUrl`
- `price`, `regularPrice`, `currency`, `discountPercent`, `onSale`
- `badge` — promotional badge shown on the site (e.g. `Only at SLT`)
- `rating`, `reviewCount`
- `description`
- `material`, `color`, `size` — of the default/shown variant
- `variantCount`, `variants[]` — up to 20 color/material/size variants, each with its own price and image
- `categoryId`, `categoryPath[]` — full department > subcategory breadcrumb
- `recordType: "product"`, `scrapedAt`

#### Detail mode (`byProductId`) — everything above, plus

- `shortDescription`, `features[]`, `specifications[]`, `careInstructions[]`, `whatsInBox[]`, `warranty`
- `manufacturerName`, `upc`, `model`, `vendorStyleId`
- `dimensions` — `height`, `width`, `length`, `weight`
- `inStock`, `availabilityStatus`, `stockLevel`
- `images[]` — full gallery (up to 30 images)
- `videoUrls[]` — brand/product demo videos, when available
- `colorOptions[]` — all currently orderable colors
- `saleFinal` — whether the sale price is final-sale (non-returnable)
- `savingsAmount` — dollar amount saved off the regular price (alongside `discountPercent`)
- `promotions[]` — active promotional callouts shown on the product page (e.g. `ENDS SOON`)
- `giftWrapAvailable`, `giftWrapPrice` — gift-wrap option and its price, when offered
- `onlineOnly` — true if the item is sold online only (not available in-store)
- `inStorePickupAvailable` — true if the item can be picked up in a physical store
- `shippingMethods[]` — fulfillment methods available for this item (e.g. `Standard Shipping`, `Same-Day Delivery`, `In-Store Pickup`)
- `containsPfa` — whether the product contains PFAS ("forever chemical") coatings, as disclosed by the retailer
- `questionCount`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `byCategory` | `byCategory` / `search` / `byProductId` |
| `category` | string | `cookware/stovetop` | Department/subcategory to browse (mode=byCategory) |
| `searchQuery` | string | `dutch oven` | Free-text keyword query (mode=search) |
| `productIds` | array | – | Product IDs or product URLs to look up (mode=byProductId) |
| `brand` | string | – | Exact brand name, e.g. `Le Creuset`, `All-Clad`, `OXO` |
| `material` | string | – | Material facet value, e.g. `Stainless Steel`, `Cast Iron` |
| `color` | string | – | Color facet value, e.g. `Black`, `Red` |
| `size` | string | – | Size facet value, e.g. `2-3 qt.`, `10"-11"`, `Set of 3`, or an exact single size like `12 qt.`. Range-bucket values are matched against each product's own recorded size(s), so only genuinely in-range products are returned. |
| `priceMin` | int | – | Minimum current/sale price (USD) |
| `priceMax` | int | – | Maximum current/sale price (USD) |
| `minRating` | int | – | Minimum customer star rating (1-5) |
| `minDiscountPercent` | int | – | Minimum discount off the regular price, e.g. `20` for 20%+ off |
| `sortBy` | string | `relevance` | `relevance` / `priceAsc` / `priceDesc` / `nameAsc` / `nameDesc` / `discountDesc` / `ratingDesc` / `reviewCountDesc` |
| `maxItems` | int | `20` | Hard cap on emitted records (1–2000) |

#### Example: browse a category with filters

```json
{
  "mode": "byCategory",
  "category": "cookware/stovetop",
  "brand": "Le Creuset",
  "material": "Cast Iron",
  "sortBy": "priceAsc",
  "maxItems": 50
}
```

#### Example: keyword search with a price range

```json
{
  "mode": "search",
  "searchQuery": "chef knife",
  "priceMin": 20,
  "priceMax": 150,
  "maxItems": 30
}
```

#### Example: highly-rated deals in a category

```json
{
  "mode": "byCategory",
  "category": "cookware/stovetop",
  "minRating": 4,
  "minDiscountPercent": 20,
  "sortBy": "discountDesc",
  "maxItems": 30
}
```

#### Example: full detail lookup by product ID

```json
{
  "mode": "byProductId",
  "productIds": ["10165173", "9141854"]
}
```

#### Example: large-volume category pull (auto-expands into subcategories)

```json
{
  "mode": "byCategory",
  "category": "bakeware",
  "maxItems": 800
}
```

### Use cases

- **Price monitoring** — track sale/markdown pricing across cookware and kitchenware brands
- **Catalog enrichment** — pull structured product data (images, variants, specs) for a marketplace or comparison site
- **Competitive intelligence** — monitor a competitor's assortment, discounting, and new arrivals by department
- **Affiliate content** — build gift guides or buying guides with live pricing and images
- **Market research** — analyze brand and material distribution within a category (e.g. how many Le Creuset vs. Staub Dutch ovens are stocked)

### FAQ

**Is this affiliated with Sur La Table?** No. This is an independent, third-party actor that reads the same publicly served product pages a browser sees — no login, cookies, or API key involved.

**Why does `byCategory` sometimes return more products than the category page shows in the browser?** Sur La Table's storefront paginates a single fetch to a maximum of ~200 products. When a category holds more, the actor automatically walks into its subcategories (using the same facet breadcrumb the site itself exposes) to keep collecting toward your `maxItems`, deduplicating by product ID. It's a genuine feature, not a bug — it's how you get full department-level pulls (e.g. all ~1000+ Cookware products) in one run.

**Why is `sortBy` applied by the actor instead of the retailer?** The retailer's own `sort` query parameter is accepted but silently ignored by their backend for these page types. To guarantee correct ordering, the actor fetches the batch and sorts it locally before emitting records.

**What currency are prices in?** USD — Sur La Table only sells in US dollars.

**Some products show a `variants` list — what is that?** Products with multiple colors, materials, or sizes (e.g. a Dutch oven available in 12 colors) list each purchasable variant separately, with its own price and image, alongside the default variant's fields at the top level of the record.

**How do I get full specs, dimensions, and stock level?** Use `mode=byProductId` with the product ID (or the full product URL) — these fields require an individual product-page fetch and aren't included in category/search listings for performance reasons.

**How does `minRating` differ from `minDiscountPercent`?** `minDiscountPercent` is applied by the retailer's own search before results are returned, so it also narrows the fetch itself. `minRating` is applied by the actor against each product's published rating, since the retailer's own rating facet doesn't reliably narrow results for a single "N stars and up" query.

**What does `containsPfa` mean?** Some cookware carries a Prop 65-style disclosure about PFAS ("forever chemical") content in its coating. This field mirrors that disclosure when the retailer publishes it, so buyers of nonstick cookware can filter or flag accordingly.

**How fresh is the data?** Real-time — every run fetches live pages directly from surlatable.com.

# Actor input Schema

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

What to fetch.

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

Department or subcategory to browse.

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

Free-text keyword search, e.g. `chef knife`, `dutch oven`, `espresso machine`.

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

Sur La Table product IDs (e.g. `10165173`) or full product URLs. Each returns a full detail record.

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

Exact brand name as shown on the site, e.g. `Le Creuset`, `All-Clad`, `Staub`, `Zwilling J.A. Henckels`, `OXO`, `Cuisinart`, `KitchenAid`. Leave empty for all brands.

## `material` (type: `string`):

Material facet value, e.g. `Stainless Steel`, `Cast Iron`, `Nonstick`, `Ceramic`, `Aluminum`. Leave empty for all materials.

## `color` (type: `string`):

Color facet value, e.g. `Black`, `Silver`, `Red`, `Blue`, `White`. Leave empty for all colors.

## `size` (type: `string`):

Size facet value as shown on the site, e.g. `2-3 qt.`, `6-7 qt.`, `10"-11"`, `Set of 3`. Leave empty for all sizes.

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

Drop products priced below this (current/sale price).

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

Drop products priced above this (current/sale price).

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

Only keep products rated at least this many stars (based on the site's own customer review average). Leave empty for no rating filter.

## `minDiscountPercent` (type: `integer`):

Only keep products discounted by at least this percentage off the regular price, e.g. `20` for 20% off or more. Leave empty for no discount filter.

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

How to order the returned products (applied after fetching).

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

Hard cap on emitted product records (mode=byCategory/search). A single category/search page tops out around 200 products per fetch; wide categories with subcategories are auto-expanded to reach higher totals.

## Actor input object example

```json
{
  "mode": "byCategory",
  "category": "cookware/stovetop",
  "searchQuery": "dutch oven",
  "productIds": [],
  "sortBy": "relevance",
  "maxItems": 20
}
```

# Actor output Schema

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

Dataset containing all scraped Sur La Table 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": "byCategory",
    "category": "cookware/stovetop",
    "searchQuery": "dutch oven",
    "productIds": [],
    "sortBy": "relevance",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/sur-la-table-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": "byCategory",
    "category": "cookware/stovetop",
    "searchQuery": "dutch oven",
    "productIds": [],
    "sortBy": "relevance",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/sur-la-table-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": "byCategory",
  "category": "cookware/stovetop",
  "searchQuery": "dutch oven",
  "productIds": [],
  "sortBy": "relevance",
  "maxItems": 20
}' |
apify call crawlerbros/sur-la-table-scraper --silent --output-dataset

```

## MCP server setup

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