# Shopify Product Catalog Quality Audit | PAL (`practical_ai_lab_jp/pal-shopify-store-product-catalog-qa`) Actor

Audit public Shopify product feeds for duplicate SKUs, missing imagery, weak descriptions, invalid variant prices and option clashes. Prioritized fixes and export.

- **URL**: https://apify.com/practical_ai_lab_jp/pal-shopify-store-product-catalog-qa.md
- **Developed by:** [Practical AI Lab](https://apify.com/practical_ai_lab_jp) (community)
- **Categories:** E-commerce, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 store audit completeds

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 Catalog Quality Audit | PAL

Audit a public Shopify storefront product feed or a product export you already have. Get **specific fixes**, not a vague health score. For ecommerce agencies and merchants reviewing product-data quality before campaigns.

### What's checked

Missing or duplicate product handles; short or missing titles; thin product descriptions; missing product images and alt text; missing variants, missing/duplicate SKUs, invalid/zero/negative prices, compare-at prices below selling prices, and duplicate variant option combinations. All findings include severity, evidence, identifying public product fields and an actionable correction. Each run produces an issue table and an overall summary, exportable as JSON or CSV.

### First run

The initial example uses two explicitly **fictional** product rows. Press Start to preview a real audit result without visiting a website. Replace these rows with your own Shopify product JSON export, or **clear the products array** and enter a public Shopify URL in the publicStore field. The Actor reads the store's publicly accessible products.json feed up to maxPages pages with up to pageSize records per page.

It does not request login credentials, Shopify Admin API tokens or private inventory.

### Product value

Agencies can quickly check an existing or competitor storefront's public catalog for feed-health issues; merchants can prioritize corrections and rerun after changes. Results are ordered by severity, with exact SKU/variant identifiers and recommended action. The AUDIT_SUMMARY record includes counts by issue type and severity, plus a partial-catalog warning.

### Limitations, compliance and security

The public feed path uses only HTTPS, validates publicly routable DNS and pins the validated IP, disallows redirects and checks robots.txt. Public data can be absent or blocked; this causes a non-billable failure. It never circumvents access controls, signs in, scrapes private data or promises an entire-catalog audit. The sampleIsPartial flag denotes bounded feeds or supplied exports. A zero-priced product can legitimately be free, and decorative images can legitimately have blank alt text; findings should be reviewed, not automatically changed.

### Pricing

One pay-per-event event named store-audit-completed is charged only after the dataset and summary are successfully stored. See the live Pricing tab for the price. A failed input or unavailable feed is not intentionally charged. No paid proxies or other external APIs are needed. No user data is sold.

### What this is not

This is not a full SEO crawl, payment/checkout audit, stock quantity verification, website owner authentication, or guaranteed revenue increase. It is a transparent quality analysis of public or user-supplied product metadata.

### Accuracy note

The public Shopify product feed may omit image alt text metadata. A missing alt field is not proof of missing alt text on the live storefront. This audit reports blank alt text only when the source explicitly includes an empty alt field. A zero compare-at price is treated as unset, not as a false discount.

# Actor input Schema

## `publicStore` (type: `string`):

An accessible HTTPS public Shopify store. No login or private inventory access.

## `products` (type: `array`):

Inline products array. When supplied, audit without fetching any website. Fictional demonstration products are prefilled.

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

Caps public catalog network requests and cost.

## `pageSize` (type: `integer`):

Requested Shopify products per page; the result may cover only part of the catalog.

## Actor input object example

```json
{
  "products": [
    {
      "id": 101,
      "handle": "demo-tumbler",
      "title": "Insulated Steel Travel Tumbler",
      "body_html": "<p>A durable insulated steel tumbler for everyday use. Includes a non-slip lid and easy cleaning instructions for long-term product care.</p>",
      "images": [
        {
          "src": "https://example.org/a.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "TUMBLER-01",
          "price": "26.00",
          "compare_at_price": "35.00",
          "option1": "Silver"
        }
      ]
    },
    {
      "id": 102,
      "handle": "demo-mug",
      "title": "Everyday Ceramic Mug",
      "body_html": "<p>A reusable ceramic mug with a comfortable handle, durable glaze and microwave safe construction for daily kitchen use.</p>",
      "images": [],
      "variants": [
        {
          "id": 1002,
          "sku": "TUMBLER-01",
          "price": "13.00",
          "option1": "Default Title"
        }
      ]
    }
  ],
  "maxPages": 2,
  "pageSize": 100
}
```

# Actor output Schema

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

Download rows from the latest run in JSON/CSV.

# 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 = {
    "products": [
        {
            "id": 101,
            "handle": "demo-tumbler",
            "title": "Insulated Steel Travel Tumbler",
            "body_html": "<p>A durable insulated steel tumbler for everyday use. Includes a non-slip lid and easy cleaning instructions for long-term product care.</p>",
            "images": [
                {
                    "src": "https://example.org/a.jpg",
                    "alt": ""
                }
            ],
            "variants": [
                {
                    "id": 1001,
                    "sku": "TUMBLER-01",
                    "price": "26.00",
                    "compare_at_price": "35.00",
                    "option1": "Silver"
                }
            ]
        },
        {
            "id": 102,
            "handle": "demo-mug",
            "title": "Everyday Ceramic Mug",
            "body_html": "<p>A reusable ceramic mug with a comfortable handle, durable glaze and microwave safe construction for daily kitchen use.</p>",
            "images": [],
            "variants": [
                {
                    "id": 1002,
                    "sku": "TUMBLER-01",
                    "price": "13.00",
                    "option1": "Default Title"
                }
            ]
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("practical_ai_lab_jp/pal-shopify-store-product-catalog-qa").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 = { "products": [
        {
            "id": 101,
            "handle": "demo-tumbler",
            "title": "Insulated Steel Travel Tumbler",
            "body_html": "<p>A durable insulated steel tumbler for everyday use. Includes a non-slip lid and easy cleaning instructions for long-term product care.</p>",
            "images": [{
                    "src": "https://example.org/a.jpg",
                    "alt": "",
                }],
            "variants": [{
                    "id": 1001,
                    "sku": "TUMBLER-01",
                    "price": "26.00",
                    "compare_at_price": "35.00",
                    "option1": "Silver",
                }],
        },
        {
            "id": 102,
            "handle": "demo-mug",
            "title": "Everyday Ceramic Mug",
            "body_html": "<p>A reusable ceramic mug with a comfortable handle, durable glaze and microwave safe construction for daily kitchen use.</p>",
            "images": [],
            "variants": [{
                    "id": 1002,
                    "sku": "TUMBLER-01",
                    "price": "13.00",
                    "option1": "Default Title",
                }],
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("practical_ai_lab_jp/pal-shopify-store-product-catalog-qa").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 '{
  "products": [
    {
      "id": 101,
      "handle": "demo-tumbler",
      "title": "Insulated Steel Travel Tumbler",
      "body_html": "<p>A durable insulated steel tumbler for everyday use. Includes a non-slip lid and easy cleaning instructions for long-term product care.</p>",
      "images": [
        {
          "src": "https://example.org/a.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "TUMBLER-01",
          "price": "26.00",
          "compare_at_price": "35.00",
          "option1": "Silver"
        }
      ]
    },
    {
      "id": 102,
      "handle": "demo-mug",
      "title": "Everyday Ceramic Mug",
      "body_html": "<p>A reusable ceramic mug with a comfortable handle, durable glaze and microwave safe construction for daily kitchen use.</p>",
      "images": [],
      "variants": [
        {
          "id": 1002,
          "sku": "TUMBLER-01",
          "price": "13.00",
          "option1": "Default Title"
        }
      ]
    }
  ]
}' |
apify call practical_ai_lab_jp/pal-shopify-store-product-catalog-qa --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,practical_ai_lab_jp/pal-shopify-store-product-catalog-qa"
        }
    }
}
```

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/EgQw0Wv2fZkSvbmwu/builds/hJwPdIsKwrKO5i69O/openapi.json
