# Shopify Catalog Quality Auditor — CatalogGuard (`nounkim/shopify-catalog-quality-auditor`) Actor

Audit public Shopify catalogs for duplicate SKUs, missing images, invalid compare-at prices, zero prices, and other review signals. Export CSV, JSON, and HTML.

- **URL**: https://apify.com/nounkim/shopify-catalog-quality-auditor.md
- **Developed by:** [Ashim Credeor](https://apify.com/nounkim) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 completed store audits

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

## CatalogGuard

### Shopify catalog quality signals, ready to review

**Unofficial tool. CatalogGuard is not affiliated with, endorsed by, or sponsored by Shopify.**

Audit a public Shopify catalog for actionable data-quality and merchandising signals. CatalogGuard finds duplicate or missing SKUs, missing images, invalid compare-at prices, duplicate titles, zero prices and optional catalog-hygiene issues, then exports a readable HTML report plus CSV and JSON.

Designed for Shopify store operators, agencies, migration teams and catalog QA workflows. No store password, Shopify Admin API credential, browser automation, proxy or external AI subscription is required.

### Quick start on Apify

1. Run with **Synthetic demo** enabled to inspect a safe example. It makes no store requests and does not charge a `store-audit` event.
2. Switch demo off and enter 1–5 canonical HTTPS Shopify store homepages, such as `https://your-store.example`.
3. Choose a product limit. A limit reached before the end of the public feed is reported as partial coverage.
4. Keep **Include low-severity review signals** off for a focused report. Turn it on to include blank SKUs, image-alt gaps, vendor/type gaps, short or long titles and fully unavailable products.
5. Open **Readable HTML audit report** in the Output tab. Download `AUDIT.csv`, `FINDINGS` or `SUMMARY` from Storage → Key-value store. The default dataset contains the same finding rows for integrations.

### Signals

#### High

- `DUPLICATE_SKU`: the same non-empty SKU is used by multiple observed variants. Review whether the duplication is intentional before changing fulfillment data.

#### Medium

- `INVALID_COMPARE_AT_PRICE`: compare-at price is equal to or below the current price.
- `MISSING_PRODUCT_IMAGE`: no image is present in the public product feed.
- `DUPLICATE_PRODUCT_TITLE`: multiple products have the same normalized title.
- `ZERO_PRICE`: variant price is zero and should be confirmed as intentional.

#### Optional low-severity signals

- `MISSING_SKU`, `IMAGE_ALT_MISSING`, `MISSING_VENDOR`, `MISSING_PRODUCT_TYPE`
- `TITLE_TOO_SHORT`, `TITLE_TOO_LONG`, `ALL_VARIANTS_UNAVAILABLE`

These are review signals, not automatic proof of defects. For example, a blank SKU or a sold-out product may be intentional.

### Heuristic score

Each enabled check has a documented weight. The score is the percentage of weighted checks that did not trigger. High-confidence operational signals carry more weight than optional hygiene signals.

The score is a triage aid only. It is **not** a Shopify, SEO, accessibility, performance or legal certification and should not be used as one.

### Outputs

- `REPORT.html`: standalone readable audit with severity, evidence and suggested review steps.
- `AUDIT.csv`: all findings, UTF-8 with spreadsheet-formula protection.
- `FINDINGS`: JSON array of all findings.
- `SUMMARY`: per-store completion, coverage, score and severity counts.
- Default dataset: one row per finding for API and integration workflows.
- Per-store records use an `audit-v1-<hash>` prefix.

Finding fields include store URL, severity, signal code, scope, product and variant identifiers, title, SKU, affected count, evidence, suggested review and public product URL.

### Pricing

Current Store price: **$0.01 per completed store audit** ($10 per 1,000). Platform usage is included.

Failed collection, blocked/private feeds, budget-limited runs and synthetic demos do not request a `store-audit` charge. Output is delivered before the custom event charge is requested. If billing cannot be confirmed, the delivered audit remains available and the run stops instead of retrying automatically.
The pricing shown in Apify Console at run time is authoritative. Configure a maximum run cost. Each live store needs at least one remaining `store-audit` event in that budget.

### Limits and safe interpretation

- Maximum 5 stores, 1,000 products per store and 10,000 product/variant pairs per store.
- Reads only public `/products.json` feeds after checking `robots.txt`.
- No login, anti-bot bypass, CAPTCHA solving, proxy rotation or private/Admin API access.
- Cross-origin redirects are refused. Enter the final canonical store homepage.
- HTTP 401, 403 and 429 responses fail without retrying or claiming an empty catalog.
- Partial feeds are labeled. Catalog-wide duplicate checks then cover only observed products.
- Availability is a public boolean, not inventory quantity or a checkout guarantee.
- Image files are not downloaded. The audit sees only image metadata in the public feed.
- Private/unpublished products, themes, rendered SEO, accessibility, checkout, regional pricing, apps and legal compliance are outside scope.
- Shopify can change while pages are fetched, so a complete pagination pass is not a transactional snapshot.

### Local use

Requires Node.js 22 or newer.

```sh
npm ci --ignore-scripts
npm test
npm run demo
node scripts/run-local.js examples/demo-input.json output/local-demo
node scripts/run-local.js examples/live-input.json output/local-live
```

Optional report preview:

```sh
node scripts/preview.js
```

Then open `http://127.0.0.1:4391`.

### Data handling and appropriate use

CatalogGuard stores only public product metadata needed for the audit. It does not download image bytes or send catalog data to an external AI or analytics service. Run storage is managed by Apify.

Use the Actor only where you have permission and where applicable site terms permit it. Robots permission alone is not legal permission. Do not treat findings or the heuristic score as professional, legal, accessibility or compliance advice.

When reporting an issue, include the store domain, run ID and error message. Never include store passwords, Admin API credentials or customer data.

# Actor input Schema

## `demoMode` (type: `boolean`):

Uses invented catalog issues without network requests or charges. Turn off for live store audits.

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

1–5 canonical HTTPS homepages. Do not enter collection or product paths.

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

1–1000. If this limit is reached, coverage is marked partial and catalog-wide findings may be incomplete.

## `includeLowSeverity` (type: `boolean`):

Include optional hygiene signals such as blank SKUs, missing image alt text, vendor/type gaps, short or long titles, and fully unavailable products.

## Actor input object example

```json
{
  "demoMode": true,
  "storeUrls": [],
  "maxProducts": 250,
  "includeLowSeverity": false
}
```

# Actor output Schema

## `findings` (type: `string`):

No description

## `report` (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 = {
    "demoMode": true,
    "storeUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("nounkim/shopify-catalog-quality-auditor").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 = {
    "demoMode": True,
    "storeUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("nounkim/shopify-catalog-quality-auditor").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 '{
  "demoMode": true,
  "storeUrls": []
}' |
apify call nounkim/shopify-catalog-quality-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nounkim/shopify-catalog-quality-auditor"
        }
    }
}

```

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/OH6Or29umhmLbWFFc/builds/3i1iAmksofVKunlho/openapi.json
