# Amazon Variation Coverage Change Audit (`practical_ai_lab_jp/pal-amazon-variation-coverage-change-audit`) Actor

Compare two dated parent-child ASIN exports to find missing variation combinations, duplicate child ASINs and broken SKU mappings.

- **URL**: https://apify.com/practical_ai_lab_jp/pal-amazon-variation-coverage-change-audit.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 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

## Amazon Variation Coverage Change Audit

Compare two dated exports of your own parent-child ASIN data and get a ranked list of variation problems:

- missing variation combinations (for example Blue / L has no child although Blue and L both exist)
- combinations that existed in the older export and are gone now
- duplicate child ASINs and duplicate variation combinations
- broken SKU mappings (one SKU on several ASINs, a SKU re-pointed to another ASIN, missing SKUs)
- child ASINs that are **absent from the current sample** versus **confirmed deleted**

The Actor works only on the text you paste in. It does not contact Amazon, log in anywhere, or use proxies.

### Absent sample is not a deleted listing

A child ASIN missing from the newer export can mean many things. This Actor never guesses:

| Disposition | Meaning | Confidence |
| --- | --- | --- |
| `confirmed_deleted` | Current export shows a deleted-type status, or you listed the ASIN in `confirmedDeletedAsins` | `status_column` / `user_confirmed` |
| `absent_from_current_sample` | Parent is still in the current export, child is not | `unconfirmed` |
| `parent_not_in_current_sample` | The whole parent family is missing, usually a scope or sampling difference | `unconfirmed` |

### Input

Required: `baselineDate`, `currentDate` (YYYY-MM-DD, baseline earlier), and one export per snapshot as CSV text (`baselineCsv`, `currentCsv`) or JSON rows (`baselineRows`, `currentRows`).

Columns are matched by name (case and punctuation ignored): `parent_asin`, `child_asin` (or `asin`), optional `sku`, optional `status`, and your variation columns. Comma, tab and semicolon separators work.

Copyable example:

```json
{
  "baselineDate": "2026-10-01",
  "currentDate": "2026-10-15",
  "baselineCsv": "parent_asin,child_asin,sku,color,size,status\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,active\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\nB0PARENT01,B0CHILD004,SKU-BLU-M,Blue,M,active",
  "currentCsv": "parent_asin,child_asin,sku,color,size,status\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,deleted\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\nB0PARENT01,B0CHILD007,SKU-BLU-S,Blue,L,active",
  "variationDimensions": ["color", "size"]
}
```

Other options: `deletedStatusValues`, `confirmedDeletedAsins`, `maxGridCombinationsPerParent`, `includeInfoFindings`, `maxFindings`, `maxRowsPerExport`.

### Output

The dataset starts with one `audit_summary` row (counts, warnings, caveats), followed by findings sorted by severity. Each finding has `findingType`, `severity`, `snapshot` (`baseline`, `current` or `comparison`), ASIN/SKU/combination fields, `disposition`, `confidence`, `detail`, `evidence` and a suggested check. The summary is also stored under the key `SUMMARY` in the key-value store. Row numbers in evidence count data rows, starting at 1 after the header.

### Pricing event

The code emits one pay-per-event event, `audit-completed`, after a finished audit has been written. Runs that fail on invalid input are not charged. Current pay-per-event prices are shown in the Store Pricing tab.

### Limitations and sample-size caveats

- Results are only as good as the two exports. Different filters, marketplaces or catalogue slices between exports create false absences. The summary warns when row counts differ by more than about 25% or fewer than 80% of baseline parents reappear.
- The expected variation grid is inferred from values seen on the current children of a parent. A value missing from all children cannot be detected, and a deliberately sparse catalogue (not every colour comes in every size) will produce gaps that are intentional.
- Grids larger than `maxGridCombinationsPerParent` are skipped, and the Actor reports that.
- Parents with only a few children give weak evidence; treat gap findings as prompts for checking, not as errors.
- One child ASIN with several SKUs is reported as low severity because it can be legitimate.
- ASIN validation checks only for ten letters or digits. It does not prove the ASIN exists.
- Values are compared after lower-casing and whitespace collapsing; spelling variants such as `Grey` and `Gray` count as different values.
- No data is verified against Amazon, so deletion is only reported as confirmed from your own status column or list.
- Memory use grows with export size; the default limit is 50,000 rows per export (adjustable up to 200,000).

### Local tests

The unit tests run offline: `python -m unittest discover -s tests`.

# Actor input Schema

## `baselineDate` (type: `string`):

Date of the older export (YYYY-MM-DD). Must be earlier than the current date.

## `currentDate` (type: `string`):

Date of the newer export (YYYY-MM-DD).

## `baselineCsv` (type: `string`):

Header row plus data. Needs parent_asin and child_asin (or asin); sku, status and variation columns are used when present. Comma, tab or semicolon separated. Use this or Baseline rows.

## `currentCsv` (type: `string`):

Same column layout as the baseline. Use this or Current rows.

## `baselineRows` (type: `array`):

Alternative to CSV text: an array of row objects keyed by column name.

## `currentRows` (type: `array`):

Alternative to CSV text for the newer export.

## `variationDimensions` (type: `array`):

Column names that define a variation, for example color and size. Leave empty to auto-detect common names (color, size, style, pattern, material, flavor, scent, configuration, capacity, count, model).

## `deletedStatusValues` (type: `array`):

Status values that mean a listing is deleted. Leave empty for: deleted, closed, removed, archived.

## `confirmedDeletedAsins` (type: `array`):

Child ASINs you have verified as deleted. Only these (and rows with a deleted-type status) are reported as confirmed deleted; other absences stay 'absent from sample'.

## `maxGridCombinationsPerParent` (type: `integer`):

Parents whose inferred variation grid is larger are skipped for the gap check.

## `includeInfoFindings` (type: `boolean`):

Also list child ASINs that appear only in the current export.

## `maxFindings` (type: `integer`):

Findings beyond this limit are dropped (most severe are kept). The summary still counts all of them.

## `maxRowsPerExport` (type: `integer`):

Safety limit to protect memory. Larger exports fail with a clear message.

## Actor input object example

```json
{
  "baselineDate": "2026-10-01",
  "currentDate": "2026-10-15",
  "baselineCsv": "parent_asin,child_asin,sku,color,size,status\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,active\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\nB0PARENT01,B0CHILD004,SKU-BLU-M,Blue,M,active\nB0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active\nB0PARENT02,B0CHILD006,SKU-GRN-XL,Green,XL,active",
  "currentCsv": "parent_asin,child_asin,sku,color,size,status\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,deleted\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\nB0PARENT01,B0CHILD007,SKU-BLU-S,Blue,L,active\nB0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active\nB0PARENT02,B0CHILD005,SKU-GRN-L2,Green,XL,active",
  "variationDimensions": [
    "color",
    "size"
  ],
  "maxGridCombinationsPerParent": 500,
  "includeInfoFindings": false,
  "maxFindings": 5000,
  "maxRowsPerExport": 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 = {
    "baselineDate": "2026-10-01",
    "currentDate": "2026-10-15",
    "baselineCsv": `parent_asin,child_asin,sku,color,size,status
B0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active
B0PARENT01,B0CHILD002,SKU-RED-M,Red,M,active
B0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active
B0PARENT01,B0CHILD004,SKU-BLU-M,Blue,M,active
B0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active
B0PARENT02,B0CHILD006,SKU-GRN-XL,Green,XL,active`,
    "currentCsv": `parent_asin,child_asin,sku,color,size,status
B0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active
B0PARENT01,B0CHILD002,SKU-RED-M,Red,M,deleted
B0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active
B0PARENT01,B0CHILD007,SKU-BLU-S,Blue,L,active
B0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active
B0PARENT02,B0CHILD005,SKU-GRN-L2,Green,XL,active`,
    "variationDimensions": [
        "color",
        "size"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("practical_ai_lab_jp/pal-amazon-variation-coverage-change-audit").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 = {
    "baselineDate": "2026-10-01",
    "currentDate": "2026-10-15",
    "baselineCsv": """parent_asin,child_asin,sku,color,size,status
B0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active
B0PARENT01,B0CHILD002,SKU-RED-M,Red,M,active
B0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active
B0PARENT01,B0CHILD004,SKU-BLU-M,Blue,M,active
B0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active
B0PARENT02,B0CHILD006,SKU-GRN-XL,Green,XL,active""",
    "currentCsv": """parent_asin,child_asin,sku,color,size,status
B0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active
B0PARENT01,B0CHILD002,SKU-RED-M,Red,M,deleted
B0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active
B0PARENT01,B0CHILD007,SKU-BLU-S,Blue,L,active
B0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active
B0PARENT02,B0CHILD005,SKU-GRN-L2,Green,XL,active""",
    "variationDimensions": [
        "color",
        "size",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("practical_ai_lab_jp/pal-amazon-variation-coverage-change-audit").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 '{
  "baselineDate": "2026-10-01",
  "currentDate": "2026-10-15",
  "baselineCsv": "parent_asin,child_asin,sku,color,size,status\\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,active\\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\\nB0PARENT01,B0CHILD004,SKU-BLU-M,Blue,M,active\\nB0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active\\nB0PARENT02,B0CHILD006,SKU-GRN-XL,Green,XL,active",
  "currentCsv": "parent_asin,child_asin,sku,color,size,status\\nB0PARENT01,B0CHILD001,SKU-RED-S,Red,S,active\\nB0PARENT01,B0CHILD002,SKU-RED-M,Red,M,deleted\\nB0PARENT01,B0CHILD003,SKU-BLU-S,Blue,S,active\\nB0PARENT01,B0CHILD007,SKU-BLU-S,Blue,L,active\\nB0PARENT02,B0CHILD005,SKU-GRN-L,Green,L,active\\nB0PARENT02,B0CHILD005,SKU-GRN-L2,Green,XL,active",
  "variationDimensions": [
    "color",
    "size"
  ]
}' |
apify call practical_ai_lab_jp/pal-amazon-variation-coverage-change-audit --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-amazon-variation-coverage-change-audit"
        }
    }
}
```

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/1wu8B9qOgFP1Q82No/builds/aHTMmd81ZkxZ6F4ED/openapi.json
