# Shopify Store Scraper ⚡ Live Prices, Sales & Stock (`malek_oweis/shopify-store-product-price-scraper`) Actor

Read a Shopify store's whole live catalog in seconds, straight from its own feed — always current, never a stale cache. Every product: price + variant range, sale price, stock, vendor, type, tags, images. Plus sale detection, out-of-stock and missing-SKU flags and a per-store price summary.

- **URL**: https://apify.com/malek\_oweis/shopify-store-product-price-scraper.md
- **Developed by:** [Malek Oweis](https://apify.com/malek_oweis) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 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

## Shopify Store Scraper ⚡ Live Prices, Sales & Stock

Point this at any **Shopify store** and get its **entire live catalog** back in seconds — price, sale price, stock, variants, images, tags — read straight from the store's own product feed, so it's always current, never a stale cache. No login, no private data.

Where a plain scraper stops at raw fields, this one adds the analysis a price/catalog monitor actually needs: **sale detection**, **out-of-stock** and **missing-SKU** flags, variant price ranges, and a **per-store price summary** (avg / min / max, on-sale count, out-of-stock count).

### What you get per product

| Field | Meaning |
|---|---|
| `priceMin` / `priceMax` | Price range across all variants |
| `compareAtMax` | Highest "compare at" (was) price — set when on sale |
| `onSale` | `true` when any variant's compare-at price is above its price |
| `inStock` | `true` when at least one variant is available |
| `vendor`, `productType` | Brand / category as set in Shopify |
| `tags`, `tagCount` | Storefront tags |
| `variantCount`, `imageCount` | Catalog completeness signals |
| `descriptionLength` | Product description length (HTML stripped) |
| `skuCoverage` | Fraction of variants that have a SKU set |
| `createdAt`, `updatedAt`, `publishedAt` | Timestamps — diff between runs to catch changes |
| `flags` | Quality issues found (see below) |
| `url` | Direct link to the product page |

### Flags

- `OUT_OF_STOCK` — no variant available
- `ON_SALE` — compare-at price above current price
- `NO_IMAGES` / `SINGLE_IMAGE` — thin product media
- `NO_DESCRIPTION` — empty description
- `NO_TAGS` — no storefront tags
- `MISSING_SKU` — one or more variants have no SKU
- `NO_PRICE` — no parseable price on any variant

### Input

```json
{
  "storeUrls": ["https://www.allbirds.com", "taylorstitch.com"],
  "maxProductsPerStore": 1000,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

- `storeUrls` — bare domain, full URL, or any page on the store (only the domain is used).
- `maxProductsPerStore` — `0` for no limit (up to 50,000).
- `proxyConfiguration` — most stores need no proxy. Turn one on only if a store returns HTTP 403 or non-JSON (some sit behind Cloudflare/Akamai).

### Output

One dataset row per product, plus a `STORE_SUMMARY` key-value record per store with
`productsScraped`, `onSaleCount`, `outOfStockCount`, `avgPrice`, `minPrice`, `maxPrice`.

#### Example row

```json
{
  "store": "taylorstitch.com",
  "title": "The Tiller Half Zip in Rinsed Indigo Slub",
  "url": "https://www.taylorstitch.com/products/tiller-half-zip-in-rinsed-indigo-slub-2607",
  "vendor": "Taylor Stitch",
  "productType": "Knits",
  "tags": ["knits", "half-zip", "indigo"],
  "tagCount": 31,
  "variantCount": 6,
  "priceMin": 138.0,
  "priceMax": 138.0,
  "compareAtMax": null,
  "onSale": false,
  "inStock": true,
  "imageCount": 9,
  "descriptionLength": 812,
  "skuCoverage": 1.0,
  "createdAt": "2026-01-14T09:02:11-08:00",
  "updatedAt": "2026-09-03T11:40:55-07:00",
  "publishedAt": "2026-01-15T06:00:00-08:00",
  "flags": []
}
```

### Use cases

- **Competitor price monitoring** — schedule daily, diff `priceMin` between runs
- **Sale detection** — alert when `onSaleCount` jumps for a competitor
- **New-product alerts** — watch for new `handle`s / recent `publishedAt`
- **Catalog QA** — audit your own store for missing images, descriptions, SKUs
- **Market research** — pull an entire niche's pricing into a spreadsheet

### FAQ

**Does it need a proxy?**
No, for most stores. Shopify serves `/products.json` publicly. Only stores behind
Cloudflare / Akamai need a proxy — set `proxyConfiguration` to `{ "useApifyProxy": true }`
if a store returns HTTP 403 or non-JSON.

**How fast is it?**
Very. It reads a paginated JSON feed (250 products per request), no headless browser.
A full 1,000-product catalog typically finishes in a few seconds.

**How current is the data?**
It is the store's own live feed — the same data the storefront renders. There is no
cache layer; every run reflects the catalog at run time.

**Is this allowed?**
It reads only the public `/products.json` endpoint Shopify exposes on every store by
default, i.e. public data any visitor can see. It never logs in and never touches
customer, order or checkout data. Respect each store's terms and your local laws.

**A store returned nothing / was skipped.**
The owner disabled the public product feed, or the store isn't Shopify. The run logs a
warning and moves on to the next store.

**Can I get only new or changed products?**
Run it on a schedule and diff `priceMin` / `updatedAt` / the set of `handle`s between
runs — new `handle`s are new products, changed `priceMin` is a price move.

### Notes

Reads only the **public** `/products.json` endpoint that Shopify exposes on every
storefront by default. No login, no private data.

# Actor input Schema

## `storeUrls` (type: `array`):

One or more Shopify storefronts. A bare domain (mystore.com), a full URL (https://mystore.com), or any page on the store all work — only the domain is used.

## `maxProductsPerStore` (type: `integer`):

Stop after this many products per store. Set 0 for no limit (up to 50,000).

## `proxyConfiguration` (type: `object`):

Most Shopify stores serve their product feed without a proxy — leave this off. Turn a proxy on only if a specific store returns HTTP 403 or non-JSON (a few sit behind Cloudflare or Akamai).

## Actor input object example

```json
{
  "storeUrls": [
    "mystore.com",
    "https://shop.example.com"
  ],
  "maxProductsPerStore": 1000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per product: price range, sale price, stock, vendor, type, tags, variant and image counts, quality flags.

## `storeSummary` (type: `string`):

productsScraped, onSaleCount, outOfStockCount, avgPrice, minPrice, maxPrice per store.

## `overview` (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 = {
    "storeUrls": [
        "https://www.allbirds.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("malek_oweis/shopify-store-product-price-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 = { "storeUrls": ["https://www.allbirds.com"] }

# Run the Actor and wait for it to finish
run = client.actor("malek_oweis/shopify-store-product-price-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 '{
  "storeUrls": [
    "https://www.allbirds.com"
  ]
}' |
apify call malek_oweis/shopify-store-product-price-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,malek_oweis/shopify-store-product-price-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/xD2E6IuugZeyc8Ea2/builds/bJItTwj0tGNo8PqcV/openapi.json
