# Shopify Product Scraper | $0.40/1K (`monkey.d.scraping/shopify-catalog-monitor`) Actor

Export Shopify catalogs with all variants, prices, SKUs and images for $0.40/1K + $0.001/run. Cheapest in our 1,000-product benchmark vs Lofomachines, Autofacts and Tidytools (18 Oct 2026). Public feeds only; snapshot comparison included.

- **URL**: https://apify.com/monkey.d.scraping/shopify-catalog-monitor.md
- **Developed by:** [Monkey D. Scraping](https://apify.com/monkey.d.scraping) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 shopify products

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?

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

## Shopify Product Scraper | $0.40/1K

Export public Shopify product catalogs for **$0.40 per 1,000 products + $0.001 per run** at default memory. Every product includes all returned variants, SKUs, prices, availability, images and discount data. Built for affordable competitor catalog exports and product research, with optional price and availability comparison between snapshots. No Shopify API key or login required.

### Cheapest: what we compared

**Cheapest in our three-Actor benchmark for a 1,000-product catalog export**, checked 18 October 2026. Our total is **$0.401**, including one start event. Compared with current base product pricing across the published tiers:

| Actor | Total for 1,000 products |
| --- | ---: |
| This Actor | **$0.401** |
| [Lofomachines](https://apify.com/lofomachines/shopify-competitor-product-intelligence) | $1.49005–$3.00005 |
| [Autofacts](https://apify.com/autofacts/shopify/pricing) | $0.80005–$1.20005 |
| [Tidytools](https://apify.com/tidytools/shopify-store-products-scraper) | $0.80–$1.00 |

This is a dated price comparison for base catalog extraction, not a claim to be the cheapest Actor everywhere or to match every competitor feature. Optional competitor services are excluded; start fees assume up to 1 GB. Tidytools can cost less for one or two products and charges nothing for unchanged comparisons. Our start fee applies even when no products or changes are returned. See Coverage and failure handling for supported stores and limits.

### Ready-to-run example

| Task | What you get | Sample price |
| --- | --- | --- |
| [Export Shopify Product Catalog to CSV](https://apify.com/monkey.d.scraping/shopify-catalog-monitor/examples/export-shopify-product-catalog-to-csv) | Up to 20 Kith products with prices, availability and source links. Replace the store domain to try another compatible public feed. | Up to **$0.009** at the saved 512 MB setting, including startup and run platform usage. |

Open the task, keep the small sample or change the store, then start it. Select **Products** and export CSV or Excel for one row per product. Download JSON for the complete returned variants, including SKUs and per-variant prices. This sample is capped at 20 products; it does not claim to export the full catalog. The saved run budget is $0.01.

### Start with one store

```json
{"stores":["https://kith.com"],"maxProducts":20,"mode":"extract"}
```

1. Enter one or more HTTPS store home URLs or domains.
2. Choose the maximum products per store (1–1,000; default 20).
3. Run and inspect **Results overview**, or select **Products** for catalog details. Export JSON, CSV or Excel from Apify.
4. Read **Coverage and errors** to see which stores worked and whether a product limit was reached.

All public variants are included in each product row. `minPrice` and `maxPrice` are prices in the reported currency, not minor units. `available` is a public storefront flag, not an inventory quantity.

### Compare prices and restocks

Every successful collection saves a comparison snapshot. To compare later, open **Input for the next comparison** and copy its JSON into the next run's input. It sets `mode: "compare"` and selects the prior snapshot storage with read-only access. You can also use the **Previous snapshot storage** picker in **Comparison baseline**.

The default **Results overview** shows either products or changes. Open the **Price and availability changes** view for `price_changed`, `availability_changed` and `variant_first_seen` events. Events include the variant/product IDs, product and variant titles, SKU, currency and observed time. Price/availability changes include the old and new values. First-seen does not mean newly launched.

The first comparison without a previous snapshot initializes it and emits no artificial changes. An unchanged comparison returns **zero dataset rows**, with results recorded in SUMMARY. Keep the prior storage available. Reusing the same baseline can repeat events; this is not exactly-once delivery. Each run creates a separate snapshot; concurrent runs do not overwrite the selected baseline.

### Product output

| Fields | Meaning |
| --- | --- |
| store, productId, title, url | Product identity and original storefront URL |
| vendor, productType, tags | Merchant-provided classification |
| minPrice, maxPrice, currency | Current variant price range and currency from cart.js |
| available, availableVariantCount, variantCount | Public availability and variant counts |
| onSale, maxDiscountPercent | Comparison against public compare-at prices |
| imageUrl, imageUrls | Public product images |
| variants | Every returned variant with SKU, options, price, compare-at price and availability |
| publishedAt, updatedAt, scrapedAt | Source timestamps when available and observation time |

#### Real product output excerpt

Reduced product row observed in an owner verification run on 18 October 2026. Prices and availability describe that observation and may change. Other fields, including the full variants array, are omitted here.

```json
{
  "recordType": "product",
  "store": "kith.com",
  "productId": "8286859198592",
  "title": "Kith Treats Pumpkin Harvest Pocket Tee - Sandrift",
  "url": "https://kith.com/products/khta030086-104",
  "currency": "USD",
  "minPrice": 75,
  "maxPrice": 75,
  "available": true,
  "variantCount": 6,
  "availableVariantCount": 6,
  "scrapedAt": "2026-10-18T12:08:33.478Z"
}
```

All six variants belonged to one product row and one product billing unit. The observed USD 75 price is not a current offer. `available` is a public storefront flag, not stock quantity. Use the JSON export for per-variant details and SUMMARY to check catalog completeness.

### Coverage and failure handling

The store must expose a public `products.json` feed. Protected or unavailable feeds are reported explicitly; a 404 does not prove the site is not Shopify. Collection/product URLs, IPv6-only stores, redirects, exact warehouse stock, reviews and full article/page scraping are not supported. For redirects, enter the final canonical store home URL.

Maximum ten stores per run, 1,000 products per store. Pagination uses 100-product pages with a bounded collection deadline. `catalogComplete` is true only when a shorter feed page is observed; a limit reached is not a full catalog. Public feed changes during collection can still affect coverage. No claims of universal coverage or exact sales/inventory estimates.

Partial failures preserve the store's prior comparison state without generating misleading changes. Missing products or variants are **never reported as removed**, because a capped/reordered feed cannot prove removal. Missing currency also preserves prior comparison state. A currency change starts a new baseline only after a complete collection. If the new-currency collection is capped or incomplete, the prior baseline is preserved and no changes are emitted for that store; SUMMARY shows `preserved_currency_change_incomplete`. Increase the product limit within supported bounds and verify completeness before retrying. Repeated capped runs will not advance this baseline. Currency is the anonymous storefront cart currency; multi-market pricing has not been exhaustively verified.

SUMMARY reports per-store status, errors, product counts and completeness. Valid empty feeds can finish successfully with no products. All stores failing causes a failed run with diagnostics. Comparison snapshots are bounded at 50,000 variants per store and 16 MB overall; exceeding a limit is an explicit error, not silent truncation.

### Common questions

**Why did I get no change rows?** The baseline may be new or the observed prices and availability may be unchanged. Check SUMMARY before treating it as failure.

**Can I monitor stock quantity?** No. This Actor tracks public available/unavailable flags, including restocks, not warehouse units.

**Can I schedule it?** Apify can schedule Actors, but this version requires the previous snapshot reference to advance between runs. A fixed scheduled input repeatedly compares against the same baseline. No automatic schedule is created.

**Does it scrape every Shopify store?** No. It supports accessible public product feeds and reports incompatible stores explicitly.

**What does it cost?** $0.40 per 1,000 products plus $0.001 per run at the default memory (up to 1 GB). Platform usage during the run is included. Higher run memory multiplies the platform start event; post-run dataset/storage operations follow Apify platform pricing.

In Extract mode, one saved product costs one product event, with all variants included. In Compare mode, one changed or first-seen product costs one event, even if several variants or fields changed. Unchanged products and initial comparison baselines have no product charge. The start fee still applies to unchanged, empty or failed runs. This is not universally the cheapest option, particularly for empty runs.

Examples at default memory: 20 extracted products cost $0.009; 1,000 cost $0.401. A comparison with no changes costs $0.001. Two variant changes on the same product cost $0.0014 total. Set Max cost per run in Apify to cap spending.

Product groups are saved before charging. If output storage or charge acknowledgment is uncertain, processing stops and no new comparison state is committed. Resurrecting/rebooting a run that has started output processing is rejected to avoid duplicate product charges; start a new run instead. Budget-limited comparisons retain old values for products whose changes were not confirmed delivered/charged. Inspect BILLING and SUMMARY; partial charging can leave some saved rows uncharged.

Use cases: competitor catalog exports, variant price monitoring, public availability/restock tracking, discount checks and assortment research. The input schema and output links are available through the Apify API for workflows and AI clients. Do not interpret source fields as AI-generated business conclusions.

### More data tools

Explore [Monkey D. Scraping Actors](https://apify.com/monkey.d.scraping) for other data collection workflows.

# Actor input Schema

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

Extract a catalog and save a baseline, or compare with a previous snapshot. First comparison without a snapshot initializes without changes.

## `stores` (type: `array`):

Public HTTPS Shopify store home URLs or domains. Example: https://kith.com. Public products.json feed required; redirects and collection/product paths are not supported.

## `maxProducts` (type: `integer`):

Maximum products per store, including all public variants. Up to 1,000; a limit reached does not mean a complete catalog.

## `previousStoreId` (type: `string`):

Select the storage from a previous extraction or comparison. Read-only. SUMMARY and NEXT_INPUT provide the settings for the next run.

## Actor input object example

```json
{
  "mode": "extract",
  "stores": [
    "kith.com"
  ],
  "maxProducts": 20
}
```

# Actor output Schema

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

Product rows in Extract mode, change events in Compare mode. An unchanged comparison has zero rows.

## `summary` (type: `string`):

Per-store coverage, errors and next snapshot reference.

## `nextInput` (type: `string`):

Copy this JSON into the Actor input to compare against this run.

## `snapshot` (type: `string`):

Preserve this storage to use it as the next baseline.

## `billing` (type: `string`):

Saved products, charged products, budget status and failures. Product units include all variants.

# 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 = {
    "stores": [
        "kith.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("monkey.d.scraping/shopify-catalog-monitor").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 = { "stores": ["kith.com"] }

# Run the Actor and wait for it to finish
run = client.actor("monkey.d.scraping/shopify-catalog-monitor").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 '{
  "stores": [
    "kith.com"
  ]
}' |
apify call monkey.d.scraping/shopify-catalog-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,monkey.d.scraping/shopify-catalog-monitor"
        }
    }
}
```

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/Aa2jeB99yKcwA9blM/builds/kk9qd6rcaDaPz1dCu/openapi.json
