# Shopify Listing Error Trend Ranker (`practical_ai_lab_jp/pal-shopify-marketplace-listing-error-trends`) Actor

Compare dated merchant-channel product error exports by SKU and rule, rank newly recurring failures and export fix actions.

- **URL**: https://apify.com/practical_ai_lab_jp/pal-shopify-marketplace-listing-error-trends.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 analysis reports

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 Listing Error Trend Ranker

Upload two or more dated product rejection/error exports from a merchant sales channel. The Actor groups failures by SKU and rule, compares snapshots over time, ranks newly recurring data-quality problems, and outputs action-ready correction rows.

It works only on the data you paste in. It never logs into any account, calls any marketplace API, or accesses the network.

### What you get

- **Action rows** (`recordType: action`): one per SKU + rule still failing in the latest snapshot, with a status, severity, streak length, first/last seen dates, score, rank, the latest message and a suggested correction.
- **Rule trend rows** (`recordType: rule_trend`): per rule, the number of affected SKUs in every snapshot, change versus the previous snapshot, and counts of new, newly recurring, reappeared, chronic and resolved SKUs.
- **`OUTPUT` record** in the key-value store: totals, status counts, caveats and limitations.

#### Statuses

| Status | Meaning |
| --- | --- |
| `new` | Failing in the latest snapshot only, never seen before |
| `newly_recurring` | No earlier history, then failing in 2 up to *newlyRecurringMaxStreak* consecutive latest snapshots |
| `reappeared` | Failing now, was fixed or absent in the previous snapshot, but seen earlier |
| `chronic` | Long streak, or recurring with earlier history |

Score = severity weight (error 3, warning 1.5, unknown 1, info 0.5) × status weight (newly recurring 3, new 2, reappeared 2, chronic 1.5) × a small breadth bonus for rules affecting many SKUs. The weights are heuristics, not measured revenue impact.

### Input

Copy and edit the prefilled sample. Each snapshot has:

- `snapshotDate` – `YYYY-MM-DD` (required)
- `channel` – optional label; channels are analysed separately
- `rows` (array of objects) **or** `csv` (text with header row), not both

Recognised columns (case-insensitive): SKU (`sku`, `offer_id`, `item_id`, `id`), rule (`rule`, `error_code`, `issue`, `reason`), message (`message`, `description`), severity (`severity`, `status`), field (`attribute`, `field`). Rows without a SKU or rule are skipped and reported.

Other options: `newlyRecurringMaxStreak`, `maxActions`, `minRuleSampleSize`, `includeRuleTrends`, `maxRowsPerSnapshot`.

### Limitations and sample-size caveats

- Use at least three evenly spaced snapshots per channel. With two, "newly recurring" only means "present in both".
- Rules affecting fewer SKUs than *minRuleSampleSize* are flagged as low sample; percentage changes on small counts are noisy.
- SKUs are matched by exact text. Renamed or re-imported SKUs look like new failures.
- Suggested actions are generic keyword guidance. Always verify against your channel's current requirements.
- Limits: 60 snapshots, 300,000 total rows, configurable per-snapshot row cap; large inputs are truncated and reported.
- Rankings describe data quality trends in your files only. They do not estimate sales or guarantee approval.

### Billing

The Actor emits a single `analysis-report` event per successful run that produces results. Runs that fail on invalid input, or that find nothing to rank, are not charged. Pricing is configured separately in Apify Console, if at all.

### Development

Tests are offline: `python -m unittest discover -s tests -t .`

# Actor input Schema

## `snapshots` (type: `array`):

List of snapshots. Each item needs snapshotDate (YYYY-MM-DD), optional channel, and EITHER rows (array of objects) OR csv (text with a header row). Recognised columns: sku / offer_id / item_id, rule / error_code / issue, message / description, severity / status, attribute / field. Use at least 3 snapshots per channel for meaningful recurrence.

## `newlyRecurringMaxStreak` (type: `integer`):

A SKU+rule failure with no earlier history that appears in 2 up to this many consecutive latest snapshots is labelled newly_recurring. Longer streaks are chronic.

## `maxActions` (type: `integer`):

Maximum ranked SKU+rule action rows per run (across all channels).

## `minRuleSampleSize` (type: `integer`):

Rules affecting fewer SKUs in the latest snapshot are flagged with a low-sample caveat.

## `includeRuleTrends` (type: `boolean`):

Also output one row per rule with counts per snapshot and change versus the previous snapshot.

## `maxRowsPerSnapshot` (type: `integer`):

Rows beyond this limit in a snapshot are ignored and reported as truncated.

## Actor input object example

```json
{
  "snapshots": [
    {
      "snapshotDate": "2026-10-01",
      "channel": "merchant-feed",
      "rows": [
        {
          "sku": "TSHIRT-RED-M",
          "rule": "invalid_gtin",
          "severity": "error",
          "attribute": "gtin",
          "message": "GTIN checksum is invalid"
        },
        {
          "sku": "MUG-BLUE",
          "rule": "image_too_small",
          "severity": "warning",
          "attribute": "image_link",
          "message": "Image below minimum size"
        }
      ]
    },
    {
      "snapshotDate": "2026-10-08",
      "channel": "merchant-feed",
      "csv": "sku,rule,severity,attribute,message\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\nCAP-BLACK,missing_brand,error,brand,Brand is required\n"
    },
    {
      "snapshotDate": "2026-10-15",
      "channel": "merchant-feed",
      "csv": "sku,rule,severity,attribute,message\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\nHAT-GREEN,missing_brand,error,brand,Brand is required\nSOCK-WHITE,title_too_long,warning,title,Title exceeds 150 characters\n"
    }
  ],
  "newlyRecurringMaxStreak": 3,
  "maxActions": 500,
  "minRuleSampleSize": 5,
  "includeRuleTrends": true,
  "maxRowsPerSnapshot": 50000
}
```

# 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 = {
    "snapshots": [
        {
            "snapshotDate": "2026-10-01",
            "channel": "merchant-feed",
            "rows": [
                {
                    "sku": "TSHIRT-RED-M",
                    "rule": "invalid_gtin",
                    "severity": "error",
                    "attribute": "gtin",
                    "message": "GTIN checksum is invalid"
                },
                {
                    "sku": "MUG-BLUE",
                    "rule": "image_too_small",
                    "severity": "warning",
                    "attribute": "image_link",
                    "message": "Image below minimum size"
                }
            ]
        },
        {
            "snapshotDate": "2026-10-08",
            "channel": "merchant-feed",
            "csv": "sku,rule,severity,attribute,message\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\nCAP-BLACK,missing_brand,error,brand,Brand is required\n"
        },
        {
            "snapshotDate": "2026-10-15",
            "channel": "merchant-feed",
            "csv": "sku,rule,severity,attribute,message\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\nHAT-GREEN,missing_brand,error,brand,Brand is required\nSOCK-WHITE,title_too_long,warning,title,Title exceeds 150 characters\n"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("practical_ai_lab_jp/pal-shopify-marketplace-listing-error-trends").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 = { "snapshots": [
        {
            "snapshotDate": "2026-10-01",
            "channel": "merchant-feed",
            "rows": [
                {
                    "sku": "TSHIRT-RED-M",
                    "rule": "invalid_gtin",
                    "severity": "error",
                    "attribute": "gtin",
                    "message": "GTIN checksum is invalid",
                },
                {
                    "sku": "MUG-BLUE",
                    "rule": "image_too_small",
                    "severity": "warning",
                    "attribute": "image_link",
                    "message": "Image below minimum size",
                },
            ],
        },
        {
            "snapshotDate": "2026-10-08",
            "channel": "merchant-feed",
            "csv": """sku,rule,severity,attribute,message
TSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid
HAT-GREEN,price_mismatch,error,price,Price differs from landing page
CAP-BLACK,missing_brand,error,brand,Brand is required
""",
        },
        {
            "snapshotDate": "2026-10-15",
            "channel": "merchant-feed",
            "csv": """sku,rule,severity,attribute,message
TSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid
HAT-GREEN,price_mismatch,error,price,Price differs from landing page
HAT-GREEN,missing_brand,error,brand,Brand is required
SOCK-WHITE,title_too_long,warning,title,Title exceeds 150 characters
""",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("practical_ai_lab_jp/pal-shopify-marketplace-listing-error-trends").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 '{
  "snapshots": [
    {
      "snapshotDate": "2026-10-01",
      "channel": "merchant-feed",
      "rows": [
        {
          "sku": "TSHIRT-RED-M",
          "rule": "invalid_gtin",
          "severity": "error",
          "attribute": "gtin",
          "message": "GTIN checksum is invalid"
        },
        {
          "sku": "MUG-BLUE",
          "rule": "image_too_small",
          "severity": "warning",
          "attribute": "image_link",
          "message": "Image below minimum size"
        }
      ]
    },
    {
      "snapshotDate": "2026-10-08",
      "channel": "merchant-feed",
      "csv": "sku,rule,severity,attribute,message\\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\\nCAP-BLACK,missing_brand,error,brand,Brand is required\\n"
    },
    {
      "snapshotDate": "2026-10-15",
      "channel": "merchant-feed",
      "csv": "sku,rule,severity,attribute,message\\nTSHIRT-RED-M,invalid_gtin,error,gtin,GTIN checksum is invalid\\nHAT-GREEN,price_mismatch,error,price,Price differs from landing page\\nHAT-GREEN,missing_brand,error,brand,Brand is required\\nSOCK-WHITE,title_too_long,warning,title,Title exceeds 150 characters\\n"
    }
  ]
}' |
apify call practical_ai_lab_jp/pal-shopify-marketplace-listing-error-trends --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-marketplace-listing-error-trends"
        }
    }
}
```

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/fu9jiMogz3r1ZKrLX/builds/z3JFo1et1azThcxL9/openapi.json
