# Chewy Scraper — Prices, Autoship, Pet Food Attributes & Reviews (`blueskyscraper/chewy-scraper`) Actor

Scrape Chewy product pages and category listings: regular and Autoship prices for every variant, price per kg, stock, pet type, category path, life stage, breed size, food form, special diets, guaranteed analysis, ingredients and reviews.

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

## Pricing

from $2.80 / 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

### What does Chewy Scraper do?

Chewy Scraper collects **pet products, prices and reviews from [Chewy](https://www.chewy.com)** — the largest US online pet store. It returns **every size variant with its regular and Autoship price**, price per kg, stock, and Chewy's own product attributes: **pet type, category path, life stage, breed size, food form and special diets** — plus, on request, the **guaranteed analysis and full ingredients list**.

Built for **pet food market research, price monitoring and new-product discovery**: crawl Dog Food or Treats categories to see what is new or on deal, then track the same products every day.

- 📦 **Product pages** — one full row per product with all variants
- 🗂️ **Category listings** and 🔍 **keyword search** — price, Autoship price, rating, review count, seller claims, New and Deal flags, position on the page (organic results; sponsored placements are not part of Chewy's catalog data)
- 📚 **Whole catalog** — every product family in Chewy's dog food and treats (~14,500) in a stable newest-first order, ideal for a daily price snapshot
- 🧭 **Sitemap** — every product id and name Chewy publishes (~280,000), filtered to dog food and treats or any scope
- 🔎 **Full details for listed products** — turn listings into full product rows in one run
- 🧪 **Guaranteed analysis and ingredients** from the product page
- ⭐ **Reviews** with rating, title, text and date, **no author names**; 📅 only new ones since a date
- 🐾 **Dogs and cats never mixed**: `petType` comes from Chewy's attribute, with a filter
- 🔁 **Change tracking** against an earlier dataset; 🆕 **Only new products** returns just the products that were not in it — in Category, Whole catalog, Search and Sitemap modes

### What data can I get from Chewy?

| Field | Example |
|---|---|
| `productId`, `name`, `brand` | 34344, Wellness CORE Healthy Weight…, Wellness |
| `petType`, `categoryPath` | Dog, Dog Supplies › Dog Food › Dry Dog Food › … (on listing rows: the pet and path of the category) |
| `lifeStage`, `breedSize`, `foodForm` | Adult, All Breeds, Dry Food |
| `specialDiet` / `claims` | Weight Control, Grain-Free, High-Protein, … |
| `price`, `autoshipPrice` (USD) | 47.98, 45.58 |
| `massGrams`, `pricePerKg`, `pricePerUnit` | 5443, 8.81, 4.00 per lb |
| `variants[]` | 4 lb / 12 lb / 26 lb — SKU, GTIN, price, Autoship price, stock |
| `requestedId`, `requestedSku`, `metricsSku` | `requestedId` is the number after `/dp/` in your URL (34344); `requestedSku` is the SKU (part number) of that exact size (49163, null if Chewy no longer lists it); `metricsSku` is the variant whose price, Autoship price, mass, price per kg, size and stock fill the top-level columns — the requested size, or the first in-stock size when there is none |
| `reviewStats` | `status`: `ok`, `empty_window` (reviews exist, none since your date), `no_reviews`, `failed`, `not_requested` (reviews off), `no_review_id_on_product`, `interrupted` (run moved or stopped); `reviewsSeen` (reviews read from Chewy), `eligibleSince` (of those, inside your date window), `reviewsReturned` (review rows written — at most "Max reviews") |
| `rating`, `ratingCount`, `ratingDistribution` | 4.598, 959, 1★ 41 … 5★ 772 (no ratings yet: `rating` null with `ratingAbsentReason: no_ratings`) |
| `guaranteedAnalysis`, `ingredients` | Crude Protein 33.0% min…, Deboned Turkey, Turkey Meal… |
| `isNewOnChewy`, `isDeal`, `position`, `claims` (listings) | false, true, 5, "Enriched with omega-6…" |
| `provenance` | run id, build, parser and schema version, observedAt, and `checksum` — `sha256:` + 64 hex characters, the SHA-256 of the JSON array of the row's observed values (product rows: ID, prices, rating, rating count, stock; review rows: review ID, rating, date) — it changes when any of them changes |

### How to scrape Chewy

1. Pick **🧭 What to scrape**: Product pages, Category listing, Whole catalog, Search results or Sitemap.
2. Paste product URLs (`https://www.chewy.com/…/dp/34344`), category URLs (`https://www.chewy.com/b/dry-food-294`, `https://www.chewy.com/b/treats-335`, up to 20 per run) or keywords (`freeze dried dog food`).
3. Optional: **🔎 Full details**, **🧪 Guaranteed analysis and ingredients**, **⭐ Add reviews**, **🐾 Pet type**, **🔁 Previous dataset id**.

```json
{
  "mode": "category",
  "categoryUrls": ["https://www.chewy.com/b/dry-food-294"],
  "maxPages": 3,
  "maxItems": 100
}
```

### How much does it cost to scrape Chewy?

| Event | Price |
|---|---|
| Product from a category, catalog, search listing or sitemap | $0.002 |
| Product (all variants and attributes) | $0.004 |
| Product with guaranteed analysis and ingredients | $0.014 |
| Review | $0.000055 |
| Anti-bot browser session (once per run, only if the run returns data) | $0.04 |

Higher Apify plans pay less per row (Bronze −10%, Silver −20%, Gold and above −30%). Error and notice rows are always free. Example: 100 category products ≈ $0.24.

### Large exports (10,000+ rows)

- **💯 Max products** goes up to 30,000 rows per run, but Chewy lists **at most 10,000 products per category or catalog section** — for more, add several categories (or their sub-categories). When a category hits that ceiling you get a free notice row instead of a silent cut.
- The run stops starting new work shortly before its timeout and writes one free notice row saying what was not reached — you never get a killed, half-written run.
- Progress is saved as the run goes: if Apify moves the run to another server, it continues where it stopped, without duplicate rows or double charges.
- **🗜️ Output format → Compact** drops the data-contract blocks (metrics, provenance) and long seller texts — several times smaller datasets.
- **⚡ Parallel requests** (up to 5) speed up full product rows: product data and reviews come over plain HTTP, a browser opens only for the guaranteed analysis/ingredients and for keyword search. The whole dog food and treats catalog (~14,500 families) reads in minutes.

### Good to know

- Composition is looked up only for food, treats and supplements; toys (including chew toys) and accessories are charged as plain products, and so is a food product whose page shows no guaranteed analysis or ingredients (`compositionReason` says why).
- In listing modes each category or keyword keeps its own list: a product found in two categories appears in both, with its own position. 💯 Max products counts delivered rows across the whole run.
- Filters in a category URL (`?rh=…`) cannot be applied — Chewy's catalog API ignores them — so the whole category is returned with a free notice row; use a sub-category URL instead. Filter pages (`/f/…`) are not supported and get a free error row.
- Free notice rows also tell you when more than 20 categories or keywords were given (the rest are listed), when 🆕 Only new products found nothing new, and when the 🐾 Pet type filter skipped everything.
- Health and nutrition **claims are the seller's statements**, not proven effects.
- Prices are those shown to a logged-out US visitor; **past prices cannot be recovered** from a product page — use change tracking from your first run.
- Review history is available as deep as Chewy serves it.
- On the Apify Free plan a run returns up to 20 rows.

### FAQ

**Is it legal to scrape Chewy?** The Actor reads only public pages and stores no personal data (review authors are never stored). Check the site's terms and your local law for your use case.

**Can I track new products in a category?** Yes — run the Category mode on a schedule with **🔁 Previous dataset id**; rows with `isNew: true` are products that were not in the previous snapshot.

**Something is missing?** Open an issue on the Actor page — we answer within a day.

# Actor input Schema

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

📦 Product pages: one full row per product (all variants, regular and Autoship price, pet type, category path, life stage, breed size, food form, special diets). 🗂️ Category and 🔍 Search: listing rows with price, Autoship price, rating, seller claims, New and Deal flags, position. 📚 Whole catalog: every product family in Chewy's dog food and treats (~14,500) in a stable order. 🧭 Sitemap: every product id and name Chewy publishes (~280,000), filtered by scope — the cheap way to spot new SKUs. Turn on 🔎 Full details to get full product rows for listed products.

## `productUrls` (type: `array`):

Chewy product pages, e.g. <code>https://www.chewy.com/wellness-core-grain-free-reduced-fat/dp/34344</code>, or bare product ids (<code>34344</code>). Used by 📦 Product pages.

## `categoryUrls` (type: `array`):

Chewy category pages, e.g. <code>https://www.chewy.com/b/dry-food-294</code>, <code>https://www.chewy.com/b/treats-335</code>. Up to 20 per run. Filters in the URL (<code>?rh=…</code>) cannot be applied — the whole category is returned and a free notice row says so; use a sub-category URL to narrow it. Chewy lists at most 10,000 products per category. Used by 🗂️ Category.

## `searchQueries` (type: `array`):

Keywords as a shopper types them, e.g. <code>freeze dried dog food</code>, <code>dog food topper</code>. Up to 20 per run. Used by 🔍 Search.

## `catalogScope` (type: `string`):

📚 Whole catalog: which part of Chewy to read.

## `sitemapScope` (type: `string`):

🧭 Sitemap: which products to keep, judged by the product name.

## `sitemapKeywords` (type: `array`):

Optional: keep only names containing any of these words, e.g. <code>freeze-dried</code>, <code>topper</code>.

## `onlyNew` (type: `boolean`):

With 🔁 Previous dataset id: write only products that were not in that dataset — new SKUs since the last run. Works in Category, Whole catalog, Search and Sitemap modes.

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

Category and Search: about 36 products per page. 📚 Whole catalog always reads to the end (limited only by 💯 Max products).

## `sort` (type: `string`):

Order of category and catalog listings. Newest first is stable between runs (Chewy's default relevance order shifts, so a pass on it can skip products).

## `includeDetails` (type: `boolean`):

Category and Search: instead of a listing row, write a full product row (charged as a product) for each listed product.

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

Upper limit of product and listing rows for the whole run (reviews, errors and notices are not counted). Chewy itself lists at most 10,000 products per category, so above that add several categories.

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

How many product cards (with their reviews) are fetched at the same time. More is faster for long lists; listing pages are always read in order.

## `petType` (type: `string`):

Keep only products Chewy tags for this pet. Applies to full product rows (pet type comes from Chewy's own attribute, not from the title); skipped products do not use up 💯 Max products. Listing rows show the pet of their category and are not filtered.

## `includeVariants` (type: `boolean`):

Every size of the product with its own SKU, price, Autoship price, net weight, price per kg and stock.

## `includeComposition` (type: `boolean`):

Adds the guaranteed analysis table and the full ingredients list from the product page. Slower and charged as a product with composition.

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

After each full product row, writes its newest reviews as separate rows (author names are never stored).

## `maxReviews` (type: `integer`):

Newest first.

## `reviewsSince` (type: `string`):

Optional date (YYYY-MM-DD). Only reviews submitted on or after it; paging stops at the first older one.

## `outputFormat` (type: `string`):

Full: every row carries the data-contract blocks (metrics with units and absence reasons, provenance with run id, checksum and timestamps). Compact: the same data fields without those blocks and without long seller texts — several times smaller for exports of tens of thousands of rows.

## `previousDatasetId` (type: `string`):

Dataset id of an earlier run. Each row then gets previousPrice, priceChange, stockChanged, ratingCountDelta and isNew against that snapshot. Pick the dataset of your earlier run of this Actor (or paste its ID) — the Actor gets read-only access to that one dataset. Left empty or unreadable, the run still returns all data, just without the change fields.

## `requestDelaySecs` (type: `integer`):

Pause between pages or products. Raise it if the site starts refusing requests.

## Actor input object example

```json
{
  "mode": "products",
  "productUrls": [
    "https://www.chewy.com/wellness-core-grain-free-reduced-fat/dp/34344"
  ],
  "catalogScope": "dog_food_and_treats",
  "sitemapScope": "dog_food_and_treats",
  "onlyNew": false,
  "maxPages": 1,
  "sort": "byNewest",
  "includeDetails": false,
  "maxItems": 100,
  "maxConcurrency": 3,
  "petType": "any",
  "includeVariants": true,
  "includeComposition": false,
  "includeReviews": false,
  "maxReviews": 20,
  "outputFormat": "full",
  "requestDelaySecs": 2
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "productUrls": [
        "https://www.chewy.com/wellness-core-grain-free-reduced-fat/dp/34344"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("blueskyscraper/chewy-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 = { "productUrls": ["https://www.chewy.com/wellness-core-grain-free-reduced-fat/dp/34344"] }

# Run the Actor and wait for it to finish
run = client.actor("blueskyscraper/chewy-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 '{
  "productUrls": [
    "https://www.chewy.com/wellness-core-grain-free-reduced-fat/dp/34344"
  ]
}' |
apify call blueskyscraper/chewy-scraper --silent --output-dataset

```

## MCP server setup

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