# Supplier CSV & Shopify Import Checker (`fluffy_ingot/supplier-catalog-preflight`) Actor

Review supplier price and stock changes or Shopify CSV blank overwrites, missing option dependencies and variant recreation risks. Upload files; get HTML, CSV and JSON.

- **URL**: https://apify.com/fluffy\_ingot/supplier-catalog-preflight.md
- **Developed by:** [yipee Gameplay](https://apify.com/fluffy_ingot) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / completed catalog comparison

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Supplier CSV & Shopify Import Checker

Review a product CSV before using it. Compare supplier prices, stock and SKUs, or switch to Shopify mode to spot blank overwrites, missing variant dependencies and option changes that may recreate variant IDs. Get an HTML review, spreadsheet-safe CSV findings and structured JSON from one comparison.

[Watch/download the 32-second synthetic portfolio demo](https://api.apify.com/v2/key-value-stores/pUK33haAXl69dRu1G/records/preflight-actors-demo.mp4?signature=1nIZqH2Dg5GUlcwpyKtnI). A quick walkthrough of all four tools using synthetic sample data.

Try the [Shopify CSV blank-overwrite and variant-change example](https://apify.com/fluffy_ingot/supplier-catalog-preflight/examples/check-shopify-csv-blank-overwrites-and-variant-changes). Displayed Actor pricing applies when you run it.

### Try a supplier comparison

1. Keep **Supplier CSV comparison** selected. The prefilled input is a small synthetic example.
2. Start one comparison, then open **Review report** in Output.
3. For your own comparison, replace both examples with your previous and new CSVs, or clear the text and upload two files.

Standard columns are `sku`, `price`, `currency`, with optional `stock` and `unit`. The **Wholesale** preset maps `Item Code`, `Wholesale Price`, `Currency`, `Available` and `Pack`. Explicit old/new mappings override the preset. Headers and SKUs are case-sensitive; surrounding whitespace is trimmed in supplier mode. Repeated SKUs are reported and excluded from pairwise checks.

```json
{
  "mode": "supplier",
  "oldCsv": "sku,price,currency,stock\nMUG,10,USD,12\n",
  "newCsv": "sku,price,currency,stock\nMUG,15,USD,0\n",
  "priceChangePercent": 20
}
```

This example produces two warnings: a 50% price rise and stock dropping to zero. The generic checks also identify added/absent SKUs, currency/unit changes, duplicates and invalid values. Extra supplier fields are included when counting changed matches but do not each generate a finding.

### Check a Shopify import

Choose **Shopify product CSV import risks**. Supply a current product export from the same store as the previous CSV and your proposed import as the new CSV. Set **will you overwrite matching handles?** to match your intended Shopify import choice. Clear supplier mappings. No store connection is required.

The native preset recognizes current headers such as `URL handle`, `SKU`, `Price` and `Option1 value`, plus legacy names including `Handle`, `Variant SKU`, `Variant Price` and `Option1 Value`. Both files need a handle and Title header. Mixing aliases for the same field is rejected. Unknown columns are listed for separate review.

Shopify matches products by handle. With overwrite enabled, included blank fields can clear existing values; omitted optional columns generally preserve them. Variant fields depend on option columns, and option-value edits can recreate variant IDs. The checker distinguishes those situations and warns about default/reset behavior separately. Omitting a product from an import does not delete it. These rules are based on [Shopify's import guidance](https://help.shopify.com/en/manual/products/import-export/import-products).

Product metadata is compared on each handle's first row. Blank metadata on subsequent variant/image rows is normal. Extra image-only rows do not become variants. Variant comparisons use handle plus option values; a unique SKU within the same handle supplies additional evidence of an option edit. Reordered variants are not paired by row position. Ambiguous option combinations or product grouping are excluded and reported. See [Shopify's CSV structure](https://help.shopify.com/en/manual/products/import-export/using-csv).

**Synthetic Shopify example — cleared vendor and renamed color:**

```json
{
  "mode": "shopify",
  "shopifyOverwriteExisting": true,
  "oldCsv": "Handle,Title,Vendor,Option1 Name,Option1 Value,Variant SKU,Variant Price\ntrail-mug,Trail Mug,Northwind Goods,Color,Blue,MUG-BLUE,12.50\n",
  "newCsv": "Handle,Title,Vendor,Option1 Name,Option1 Value,Variant SKU,Variant Price\ntrail-mug,Trail Mug,,Color,Azure,MUG-BLUE,12.50\n"
}
```

Expected findings: `SHOPIFY_BLANK_OVERWRITE_RISK`, `SHOPIFY_VARIANT_SET_CHANGED` and `SHOPIFY_VARIANT_RECREATION_RISK`. These are review warnings, not proof of the final store outcome. A fuller fixture in the source package includes a second variant and an additional image row.

### Uploads and limits

For each side, provide exactly one source: pasted `oldCsv` / `newCsv` text or an `oldFileUrl` / `newFileUrl` upload. Clear the prefilled text when uploading. Uploads must use HTTPS Apify key-value-store record URLs at `api.apify.com/v2/key-value-stores/{id}/records/{key}`. For private uploads, select their stores in `sourceStores` to grant read access. Signed upload links do not need this selection. External file hosts and token-bearing URLs are unsupported. Process only files you are entitled to use.

Each CSV is limited to 2,000,000 characters and 10,000 nonempty rows. Uploads additionally have a 2,000,000-byte UTF-8 limit. Supplier mode allows 40 columns; Shopify allows 200, including image rows within the row limit. Comma delimiters, quoted cells, CRLF and a UTF-8 BOM are supported.

Supplier prices allow 1–12 digits and up to 6 decimal places, without symbols, thousands separators or exponents. Currency is checked for three-uppercase-letter syntax only; stock must be a nonnegative integer. Shopify permits negative inventory quantities and compares prices assuming the same store currency. Price threshold range: 0–1000%; zero-to-positive prices always trigger review.

### Read and automate the result

- **Review report:** `report.html`, readable findings and suggested actions.
- **JSON report:** `REPORT`, summary, findings and recognized columns; Shopify adds matching context.
- **CSV findings:** `findings.csv`, a summary row and the returned findings. Formula-like cells receive a leading apostrophe; JSON preserves parsed values.
- **Summary:** exactly one dataset item per completed comparison, with `mode`, `status`, severity/code counts and report record keys.

Counts include all detected findings; at most 500 details are returned. Always check `findingsTruncated`. In Shopify mode, `checks_passed` allows informational findings; warnings or errors produce `review_required`. In supplier mode any finding produces `review_required`. Neither status certifies an import. Shopify's `addedProducts` means handles not in the supplied baseline, `removedProducts` is always zero, and `handlesNotInImport` counts omitted handles. `report_schema.json` and `dataset_schema.json` document the output contracts in the source package.

A recurring workflow can retain the last accepted export, supply each proposed replacement, and route `review_required` or truncated results to review. Read the dataset summary first, then retrieve `REPORT` from that run's default key-value store for details. Keep the old baseline until the new file is accepted. An empty finding list does not authorize an import. The Actor does not remember prior files, schedule checks, send messages or import data.

### Scope and pricing

This is a bounded review tool, not Shopify's import engine or a full platform validator. It does not check a live store, image reachability, market-specific prices, metafield definitions, all required/default rules or every field dependency. A stale or partial baseline limits coverage. Missing/blank option identity limits variant comparison. Product-only changes can leave variant checks unavailable. Review the official import preview and your backup process separately.

USD **0.50 per completed comparison**, plus **0.00005 per start** at the configured memory allocation. Platform usage is included. One completed comparison writes one summary dataset item and charges once, whether it finds problems or not. HTML, CSV and JSON are included; there is no separate per-product or per-finding charge. A started run can incur the start fee even if invalid input prevents a completed report.

At these settings, set the spending limit to at least USD 0.50005; USD 0.51 covers one completed comparison. The Store may display USD 500 per 1,000 comparisons. Check the live price before running. Both supplier and Shopify modes use the same price.

Inputs and reports follow your Apify storage access and retention settings. For support, provide a small anonymized reproduction and finding code, without credentials or confidential product files. This Actor is independently developed and is not affiliated with Shopify.

# Actor input Schema

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

Supplier mode matches SKUs with configurable headers. Shopify mode uses native current/legacy headers, product handles and option values. Supply a current export and proposed import; no Shopify login is needed and no store is changed.

## `columnPreset` (type: `string`):

Supplier mode only. The wholesale preset also maps Available and Pack when present. Explicit mappings below override this preset. Shopify headers are mapped automatically.

## `shopifyOverwriteExisting` (type: `boolean`):

Model the overwrite choice you intend to select in Shopify. True checks clearing/reset risks for existing handles. False reports matching handles as skipped. This only changes the report; it does not configure Shopify.

## `oldCsv` (type: `string`):

Paste CSV text OR use the file upload below. Replace the synthetic supplier example with your data; clear it when uploading. Shopify: current export here for Previous, proposed import for New. Maximum 2 million characters, 10,000 rows, 40 supplier columns or 200 Shopify columns.

## `oldFileUrl` (type: `string`):

Upload UTF-8 CSV to Apify storage. Only api.apify.com key-value-store record URLs (unsigned or signature links) are supported. Maximum 2 MB. Clear the CSV text above first.

## `oldColumns` (type: `object`):

Supplier mode only: optional explicit mapping, case-sensitive. Leave empty in Shopify mode; native current/legacy headers are mapped automatically.

## `newCsv` (type: `string`):

Paste CSV text OR use the file upload below. Replace the synthetic supplier example with your data; clear it when uploading. Shopify: current export here for Previous, proposed import for New. Maximum 2 million characters, 10,000 rows, 40 supplier columns or 200 Shopify columns.

## `newFileUrl` (type: `string`):

Upload UTF-8 CSV to Apify storage. Only api.apify.com key-value-store record URLs (unsigned or signature links) are supported. Maximum 2 MB. Clear the CSV text above first.

## `newColumns` (type: `object`):

Supplier mode only: optional explicit mapping, case-sensitive. Leave empty in Shopify mode; native current/legacy headers are mapped automatically.

## `sourceStores` (type: `array`):

When using private uploads, select the temporary stores created by the upload dialogs. The Actor receives read access only to the stores you select. Unneeded for pasted CSV or valid signed file URLs.

## `priceChangePercent` (type: `number`):

Flag changes at or above this percentage. Zero-to-nonzero prices are always flagged.

## Actor input object example

```json
{
  "mode": "supplier",
  "columnPreset": "standard",
  "shopifyOverwriteExisting": true,
  "oldCsv": "sku,price,currency,stock,unit\nA,10,USD,5,each\nB,20,USD,3,each\n",
  "newCsv": "sku,price,currency,stock,unit\nA,15,USD,0,each\nC,30,EUR,4,box\n",
  "priceChangePercent": 20
}
```

# Actor output Schema

## `report` (type: `string`):

Readable HTML with severity, before/after values and review actions. Shopify results identify handles and option values. This is a risk review, never a guarantee of import safety.

## `json` (type: `string`):

Summary and up to 500 findings. Counts remain complete; truncation is explicit.

## `csv` (type: `string`):

Spreadsheet-safe export of returned findings.

## `summary` (type: `string`):

Exactly one result per completed comparison. Inspect mode, status, findingsByCode, findingsBySeverity and findingsTruncated. Shopify removedProducts is always zero; handlesNotInImport counts omission, not deletion.

# 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 = {
    "oldCsv": `sku,price,currency,stock,unit
A,10,USD,5,each
B,20,USD,3,each`,
    "newCsv": `sku,price,currency,stock,unit
A,15,USD,0,each
C,30,EUR,4,box`
};

// Run the Actor and wait for it to finish
const run = await client.actor("fluffy_ingot/supplier-catalog-preflight").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 = {
    "oldCsv": """sku,price,currency,stock,unit
A,10,USD,5,each
B,20,USD,3,each
""",
    "newCsv": """sku,price,currency,stock,unit
A,15,USD,0,each
C,30,EUR,4,box
""",
}

# Run the Actor and wait for it to finish
run = client.actor("fluffy_ingot/supplier-catalog-preflight").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 '{
  "oldCsv": "sku,price,currency,stock,unit\\nA,10,USD,5,each\\nB,20,USD,3,each\\n",
  "newCsv": "sku,price,currency,stock,unit\\nA,15,USD,0,each\\nC,30,EUR,4,box\\n"
}' |
apify call fluffy_ingot/supplier-catalog-preflight --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fluffy_ingot/supplier-catalog-preflight"
        }
    }
}

```

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/MXNJ8XlclKCta1V3Y/builds/dqv1w5pDWQ4ghtP2b/openapi.json
