# Shopify Store Intelligence — Catalog, Price & Stock Tracker (`constructive_calm/shopify-store-intel`) Actor

Track product launches, price changes, and stock signals across hundreds of Shopify stores. KV-checkpointed delta detection plus AI-powered store audits. Replaces Storeleads and Particl at PPE pricing.

- **URL**: https://apify.com/constructive\_calm/shopify-store-intel.md
- **Developed by:** [Omar Eldeeb](https://apify.com/constructive_calm) (community)
- **Categories:** E-commerce, Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Intelligence — Catalog, Price & Stock Tracker

Track product launches, price changes, and stock signals across hundreds of Shopify stores in one actor. KV-checkpointed delta detection plus AI-powered store audits. Replaces Storeleads ($75–950/mo) and Particl ($250–1000/mo) at fraction-of-a-cent PPE pricing.

### What does Shopify Store Intelligence do?

Five modes against the public Shopify storefront endpoints (`/products.json` + `/products/<handle>.json` + sitemap fallback):

1. **`catalog_snapshot`** — full product dump for one or many stores
2. **`new_launches`** — products published in the last N days OR new since your last run
3. **`price_changes`** — variant-level price + compare-at-price deltas vs your previous run (the **Particl-killer**)
4. **`stock_signals`** — variants going in/out of stock; with deep-probe enabled, true `inventory_quantity` deltas including low-stock alerts
5. **`store_audit`** — one-shot per-store report with aggregate stats and Gemini-powered niche classification (BD/M&A use case)

All output is one unified row shape discriminated by `type` (`product` / `delta` / `audit`).

### Why use Shopify Store Intelligence?

- **DTC competitive intel teams** — track 50–500 competitor stores weekly, surface price moves and new launches the same day
- **Trend hunters / dropshippers** — find what competitors test before it explodes
- **M&A scouts / agencies** — one-shot `store_audit` returns niche, buyer persona, brand positioning, price tier, and full catalog stats per store
- **Repricing / brand pricing analysts** — `price_changes` deltas down to the variant SKU level
- **Demand forecasters** — `stock_signals` flag products selling out fast (predictive of hot SKUs)

### How to use Shopify Store Intelligence

1. Pick a mode (start with `store_audit` for one store to see what you get)
2. Paste 1–500 store domains (`allbirds.com`, `kith.com`, `mvmt.com` — bare domains, http stripped automatically)
3. Set `maxProductsPerStore` to control PPE budget (small catalogs: leave default; big brands: cap at 500)
4. For `price_changes` / `stock_signals`: schedule the actor weekly or daily — the second-onwards run emits real deltas
5. For big brands behind WAF (Gymshark-tier), enable `proxyConfiguration → useApifyProxy: true` — sitemap fallback handles the rest
6. Export results as JSON / CSV / Excel via Apify's standard download

### Input

Minimal example (audit one store with AI niche classification):
```json
{
  "mode": "store_audit",
  "storeDomains": ["allbirds.com"],
  "enableAiNiche": true
}
````

Track price changes across a competitor set (run weekly):

```json
{
  "mode": "price_changes",
  "storeDomains": ["allbirds.com", "rothys.com", "vejashoes.com"],
  "maxProductsPerStore": 500,
  "concurrency": 8
}
```

Find new launches in the last 14 days:

```json
{
  "mode": "new_launches",
  "storeDomains": ["mvmt.com", "thursdayboots.com"],
  "lookbackDays": 14
}
```

Stock signals with true inventory probe (slower, more expensive, higher signal):

```json
{
  "mode": "stock_signals",
  "storeDomains": ["bombas.com"],
  "deepInventoryProbe": true,
  "lowStockThreshold": 10
}
```

Bypass WAF on big brands with residential proxy:

```json
{
  "mode": "catalog_snapshot",
  "storeDomains": ["gymshark.com"],
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Output

Sample `product` row (from `catalog_snapshot` / `new_launches`):

```json
{
  "type": "product",
  "store": "allbirds.com",
  "title": "Trino® Cozy Crew - Heathered Onyx",
  "vendor": "Allbirds",
  "productType": "Socks",
  "available": true,
  "variantCount": 4,
  "priceMin": 12,
  "priceMax": 12,
  "currency": "USD",
  "publishedAt": "2026-04-21T12:39:05-07:00",
  "productUrl": "https://allbirds.com/products/trino-cozy-crew-heathered-onyx",
  "variants": [
    {
      "title": "S (W5-7)",
      "sku": "PCC1HONU301",
      "price": 12,
      "compareAtPrice": 24,
      "available": true,
      "inventoryQuantity": null
    }
  ],
  "source": "products.json"
}
```

Sample `delta` row (from `price_changes` / `stock_signals`):

```json
{
  "type": "delta",
  "store": "allbirds.com",
  "deltaType": "price_change",
  "productTitle": "Wool Runner",
  "variantTitle": "Black / Size 10",
  "oldValue": 110,
  "newValue": 88,
  "detectedAt": "2026-05-08T12:00:00.000Z"
}
```

Sample `audit` row (from `store_audit` with `enableAiNiche: true`):

```json
{
  "type": "audit",
  "store": "allbirds.com",
  "isShopify": true,
  "productCount": 50,
  "vendorCount": 1,
  "avgPrice": 32.90,
  "medianPrice": 25,
  "currency": "USD",
  "availableShareOfCatalog": 0.16,
  "primaryNiche": "sustainable footwear and apparel",
  "secondaryNiches": ["eco-friendly accessories", "comfortable everyday wear"],
  "buyerPersona": "Environmentally conscious consumers who prioritize comfort, sustainability, and minimalist design",
  "brandPositioning": "Allbirds positions itself as a leader in sustainable fashion, offering comfortable products made from natural, renewable materials",
  "priceTier": "premium",
  "aiConfidence": 0.95
}
```

#### Data fields

| Field | Type | Where it appears | Notes |
|---|---|---|---|
| `type` | string | every row | `product` / `delta` / `audit` discriminator |
| `store` | string | every row | bare domain (no scheme) |
| `productId` | string | product, delta | `<domain>::<shopifyId>` |
| `variants[]` | array | product | array of `{ title, sku, price, compareAtPrice, available, inventoryQuantity }` |
| `inventoryQuantity` | number|null | variant | only populated when store exposes it (depends on Shopify config) |
| `deltaType` | string | delta | `price_change`, `compare_at_change`, `stock_in`, `stock_out`, `low_stock`, `restock` |
| `primaryNiche` | string | audit | Gemini classification when `enableAiNiche: true` |
| `priceTier` | enum | audit | `budget` / `mid` / `premium` / `luxury` |
| `source` | enum | product | `products.json` / `product-handle` / `sitemap-fallback` |

### How much does it cost to scrape Shopify with this actor?

| Event | Price | When it fires |
|---|---|---|
| Actor start | $0.01 | Once per run, per GB of memory |
| Product fetched | $0.005 | Each product written in `catalog_snapshot` mode |
| Price change detected | $0.02 | Variant `price` or `compare_at_price` changed since last run |
| New launch detected | $0.01 | Product published in lookback window OR new since last run |
| Stock signal detected | $0.01 | Variant flipped in/out of stock or crossed low-stock threshold |
| Store audited | $0.50 | One-shot per-store report with aggregate stats |
| AI niche classified | $0.05 | Gemini classification appended to a `store_audit` row |
| Residential proxy fetch | $0.003 | Fired only when `proxyConfiguration.useApifyProxy: true` |

**Free trial:** the first **200 custom chargeable events per run** are free.

Typical-run costs:

- **Audit 5 stores with AI**: 5 × ($0.50 + $0.05) = **$2.75**
- **Catalog snapshot 10 stores × 200 products**: 2,000 × $0.005 = **$10**
- **Weekly price-change monitor across 100 stores** (~50 deltas/week observed): 50 × $0.02 = **$1/week**
- **Stock signals on 50 high-traffic stores** (~30 signals/run): 30 × $0.01 = **$0.30/run**

Compare: Storeleads $75–950/mo, Particl $250–1,000/mo, Charm.io enterprise.

### Tips & advanced options

- **First run of a delta mode = baseline only.** No deltas are emitted on run #1 — checkpoint is saved instead. Schedule the actor for repeated runs to see real deltas.
- **`maxProductsPerStore` is your budget knob.** Large catalogs (5,000+ products) blow through PPE fast. Cap aggressively for monitoring use cases.
- **WAF-blocked stores** (Gymshark-tier) auto-fall-back to sitemap parsing — slower but works without a proxy. Enable `useApifyProxy: true` for full `/products.json` access.
- **`inventory_quantity` exposure varies by store.** Allbirds returns `null` even on `/products/<handle>.json`; Bombas exposes it. The `available` boolean is always populated.
- **Schedule with Apify Schedules.** Run `price_changes` weekly, `new_launches` daily for a low-cost monitoring stack.
- **One actor for many use cases.** The dataset is discriminated by the `type` field — filter downstream consumers (BI tools, n8n, Make.com webhooks) on `type === 'delta'` or `type === 'audit'`.

### Legal disclaimer

This actor reads only **publicly accessible** Shopify storefront endpoints (`/products.json`, `/products/<handle>.json`, `/sitemap.xml`) — the same data any browser can request without authentication. No Shopify accounts, OAuth, or admin access is required or used. We do not bypass paywalls, login walls, or rate limits.

Each store's robots.txt should be respected by users; if a store explicitly disallows crawling, do not use this actor against it. Public catalog data is generally not personal information under GDPR/CCPA, but consult counsel for your jurisdiction before storing or republishing.

Shopify and the Shopify storefront APIs are trademarks of Shopify Inc. This actor is not affiliated with, endorsed by, or sponsored by Shopify Inc.

### FAQ

**Will this work on every Shopify store?**
Most. About 70–80% of Shopify stores leave `/products.json` open by Shopify default. Big brands (Gymshark, fashion-world enterprise) WAF-block the JSON path — for those, the actor automatically falls back to sitemap-based discovery. Enable Apify residential proxy to recover full coverage on these.

**Why does `inventoryQuantity` come back as `null` sometimes?**
Shopify lets store owners hide inventory counts via theme settings. When hidden, you only get `available: true|false`. The `deepInventoryProbe` option fetches `/products/<handle>.json` (which exposes counts on stores that allow it) but cannot bypass intentional hiding.

**How is this different from existing Shopify actors on Apify?**
Existing actors return raw catalog dumps. This one adds: KV-checkpointed delta detection (price + stock changes between runs), per-store AI niche classification, sitemap fallback for WAF-blocked stores, and unified output shape discriminated by `type`. No incumbent ships these together.

**Can I find Shopify stores I don't already know about?**
Not in v1. Pass your own domain list. There is no public Shopify store directory — paid aggregators (BuiltWith, Wappalyzer) are required for at-scale discovery. We may add a niche-seeded discovery mode in v2.

**Does this respect Shopify's ToS?**
We use only public storefront endpoints. Shopify's general ToS prohibits abusive scraping; this actor uses one User-Agent, defensive concurrency caps, and respects 4xx/429 responses. We recommend you respect each store's robots.txt and rate-limit your runs to the data freshness you actually need.

For issues / feature requests: report at [Apify Console → Actor → Issues](https://console.apify.com/actors).

# Actor input Schema

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

What to do. catalog\_snapshot = full one-time product dump per store. new\_launches = products published in the last N days (or new since last KV checkpoint). price\_changes = variant-level price deltas vs the previous run on the same input (the Particl-killer). stock\_signals = variants going in/out of stock + true inventory\_quantity when exposed. store\_audit = one-shot per-store report with aggregate stats and AI niche classification (BD/M\&A use case).

## `storeDomains` (type: `array`):

List of Shopify store domains to scan. Accepts: allbirds.com, https://kith.com, kith.com/collections/all (path is stripped). Bare domains auto-prefix with https://. ~70-80% of Shopify stores expose /products.json publicly (their default). Stores behind WAF (Gymshark-tier) auto-fall-back to sitemap parsing — enable proxy below for best coverage.

## `lookbackDays` (type: `integer`):

Used only by new\_launches mode. Returns products with published\_at within the last N days. Ignored by other modes (which use KV checkpointing instead). Default 30 days.

## `deepInventoryProbe` (type: `boolean`):

If enabled, the actor fetches each product's individual JSON (/products/<handle>.json) to extract true inventory\_quantity per variant. Adds 1 request per product (slower + more expensive) but unlocks accurate low-stock detection. When disabled, only the boolean 'available' flag is captured. Many stores don't expose inventory\_quantity even with this on — depends on store config.

## `lowStockThreshold` (type: `integer`):

When deepInventoryProbe is on, variants with inventory\_quantity <= this threshold are flagged as low\_stock. Set to 0 to only flag fully-out-of-stock items. Ignored when deep probe is disabled.

## `enableAiNiche` (type: `boolean`):

When enabled (default), each store\_audit report runs through Gemini 2.5 Flash to extract: primary niche, secondary niches, target buyer persona, brand positioning, price tier (budget/mid/premium/luxury). Adds $0.05 per store. Auto-disabled in non-audit modes.

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

Cap on products fetched per store. Big catalogs (Shein/Allbirds/large brands) can have 5,000+ products. Set this to control PPE budget per store. 0 = no cap.

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

Hard cap on total dataset rows across all stores. Pagination + per-store collection stops once reached. Safety net for runaway runs.

## `concurrency` (type: `integer`):

Parallel HTTP fetches across stores. Shopify storefronts are bot-friendly. Default 8 is safe; increase for large prospect lists.

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

Most Shopify stores work without proxy. Big brands (Gymshark-tier) WAF-block direct fetches — enable RESIDENTIAL proxy here for best coverage. Each proxied request fires the proxy-fetch event ($0.003). Sitemap fallback runs automatically when JSON is blocked, but residential proxy unlocks the full /products.json on these stores.

## Actor input object example

```json
{
  "mode": "catalog_snapshot",
  "storeDomains": [
    "allbirds.com"
  ],
  "lookbackDays": 30,
  "deepInventoryProbe": false,
  "lowStockThreshold": 5,
  "enableAiNiche": true,
  "maxProductsPerStore": 30,
  "maxItems": 50,
  "concurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset containing products (catalog\_snapshot/new\_launches), variant deltas (price\_changes/stock\_signals), and store audits (store\_audit). Discriminated by the 'type' field on each row.

# 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 = {
    "storeDomains": [
        "allbirds.com"
    ],
    "maxProductsPerStore": 30,
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("constructive_calm/shopify-store-intel").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 = {
    "storeDomains": ["allbirds.com"],
    "maxProductsPerStore": 30,
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("constructive_calm/shopify-store-intel").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "storeDomains": [
    "allbirds.com"
  ],
  "maxProductsPerStore": 30,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call constructive_calm/shopify-store-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=constructive_calm/shopify-store-intel",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Shopify Store Intelligence — Catalog, Price & Stock Tracker",
        "description": "Track product launches, price changes, and stock signals across hundreds of Shopify stores. KV-checkpointed delta detection plus AI-powered store audits. Replaces Storeleads and Particl at PPE pricing.",
        "version": "1.0",
        "x-build-id": "7RyoMppBOXCeqvYWM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/constructive_calm~shopify-store-intel/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-constructive_calm-shopify-store-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/constructive_calm~shopify-store-intel/runs": {
            "post": {
                "operationId": "runs-sync-constructive_calm-shopify-store-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/constructive_calm~shopify-store-intel/run-sync": {
            "post": {
                "operationId": "run-sync-constructive_calm-shopify-store-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Scraping mode",
                        "enum": [
                            "catalog_snapshot",
                            "new_launches",
                            "price_changes",
                            "stock_signals",
                            "store_audit"
                        ],
                        "type": "string",
                        "description": "What to do. catalog_snapshot = full one-time product dump per store. new_launches = products published in the last N days (or new since last KV checkpoint). price_changes = variant-level price deltas vs the previous run on the same input (the Particl-killer). stock_signals = variants going in/out of stock + true inventory_quantity when exposed. store_audit = one-shot per-store report with aggregate stats and AI niche classification (BD/M&A use case).",
                        "default": "catalog_snapshot"
                    },
                    "storeDomains": {
                        "title": "Shopify store domains",
                        "type": "array",
                        "description": "List of Shopify store domains to scan. Accepts: allbirds.com, https://kith.com, kith.com/collections/all (path is stripped). Bare domains auto-prefix with https://. ~70-80% of Shopify stores expose /products.json publicly (their default). Stores behind WAF (Gymshark-tier) auto-fall-back to sitemap parsing — enable proxy below for best coverage.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "lookbackDays": {
                        "title": "Lookback window (days) — new_launches mode",
                        "minimum": 1,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Used only by new_launches mode. Returns products with published_at within the last N days. Ignored by other modes (which use KV checkpointing instead). Default 30 days.",
                        "default": 30
                    },
                    "deepInventoryProbe": {
                        "title": "Deep inventory probe (stock_signals + store_audit)",
                        "type": "boolean",
                        "description": "If enabled, the actor fetches each product's individual JSON (/products/<handle>.json) to extract true inventory_quantity per variant. Adds 1 request per product (slower + more expensive) but unlocks accurate low-stock detection. When disabled, only the boolean 'available' flag is captured. Many stores don't expose inventory_quantity even with this on — depends on store config.",
                        "default": false
                    },
                    "lowStockThreshold": {
                        "title": "Low-stock threshold (stock_signals mode)",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "When deepInventoryProbe is on, variants with inventory_quantity <= this threshold are flagged as low_stock. Set to 0 to only flag fully-out-of-stock items. Ignored when deep probe is disabled.",
                        "default": 5
                    },
                    "enableAiNiche": {
                        "title": "Enable Gemini AI niche classification (store_audit mode)",
                        "type": "boolean",
                        "description": "When enabled (default), each store_audit report runs through Gemini 2.5 Flash to extract: primary niche, secondary niches, target buyer persona, brand positioning, price tier (budget/mid/premium/luxury). Adds $0.05 per store. Auto-disabled in non-audit modes.",
                        "default": true
                    },
                    "maxProductsPerStore": {
                        "title": "Max products per store",
                        "minimum": 0,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Cap on products fetched per store. Big catalogs (Shein/Allbirds/large brands) can have 5,000+ products. Set this to control PPE budget per store. 0 = no cap.",
                        "default": 500
                    },
                    "maxItems": {
                        "title": "Max items (global cap)",
                        "minimum": 1,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Hard cap on total dataset rows across all stores. Pagination + per-store collection stops once reached. Safety net for runaway runs.",
                        "default": 5000
                    },
                    "concurrency": {
                        "title": "Concurrent stores fetched",
                        "minimum": 1,
                        "maximum": 25,
                        "type": "integer",
                        "description": "Parallel HTTP fetches across stores. Shopify storefronts are bot-friendly. Default 8 is safe; increase for large prospect lists.",
                        "default": 8
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration (recommended for big-brand stores)",
                        "type": "object",
                        "description": "Most Shopify stores work without proxy. Big brands (Gymshark-tier) WAF-block direct fetches — enable RESIDENTIAL proxy here for best coverage. Each proxied request fires the proxy-fetch event ($0.003). Sitemap fallback runs automatically when JSON is blocked, but residential proxy unlocks the full /products.json on these stores.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
