# Supplier Catalog Change Checker (`dharris289/supplier-catalog-change-checker`) Actor

Supplier price comparison for procurement agents: compare two CSV catalogs by SKU. Get unit-price, packaging and product changes plus review flags in JSON/CSV. Bring authorized files; no scraping or LLM calls. $3 per completed comparison, including review reports; platform usage included.

- **URL**: https://apify.com/dharris289/supplier-catalog-change-checker.md
- **Developed by:** [David Harris](https://apify.com/dharris289) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3,000.00 / 1,000 completed comparisons

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

## Supplier Catalog Change Checker

Compare two supplier price CSV files by product code. Get product appearances and disappearances, unit price and packaging changes, and review flags when the files cannot safely be compared. The service has passed real manufacturer-data validation and hosted billing checks. Pricing is configured at $3 per completed comparison with platform usage included. This service compares files you supply; it does not provide a supplier price database or a Grainger integration.

### Quick start in Apify

1. Use two dated exports from the same supplier, region, currency, customer pricing tier, and product scope. Keep the originals. For Excel, export the product table as CSV first.
2. Open **Input → Form**. Paste the earlier file into **Previous CSV text** and the newer file into **Current CSV text**. Include the header row. Enter a supplier label and pricing context without private account numbers.
3. Use the required headers shown below, or supply explicit column mappings. Select the CSV delimiter (comma, semicolon, or tab); the same delimiter applies to both files. Confirm price quantity and base unit. Use lowercase supported units such as each, ft, or m in the CSV values; mappings do not rewrite unit values. Begin with up to 1,000 rows per file.
4. Set **512 MB memory**, **60-second timeout**, **$3 maximum cost per run**, and **Restart on error: Off**. Start the comparison on demand when a new catalog arrives.
5. On success, open **Storage → Key-value store** and download **REPORT** (JSON), **REPORT-CSV** (CSV), and **OUTPUT**. The default dataset contains only the summary. Check that OUTPUT says completed; review flagged rows before using price changes.

Minimal fictional example for **Input → JSON**:

```json
{
  "old_csv": "sku,price,currency,price_quantity,unit\nDEMO-001,20.00,USD,100,each\n",
  "new_csv": "sku,price,currency,price_quantity,unit\nDEMO-001,22.00,USD,100,each\n",
  "supplier": "Fictional supplier",
  "price_context": "Same tier and scope; fictional dated snapshots"
}
```

This example should report one changed product: unit price rises from $0.20 to $0.22, a 10% increase. Copy the JSON example above into Input → JSON to run a fictional comparison; this completed demo costs $3. Sample prices are demonstrations, not live supplier quotes.

### Using this from another agent

Call this Actor through the official Apify API or SDK with the same input JSON. Run it in your own Apify account and set a maximum charge of $3. Wait for the run to finish, then read OUTPUT and the JSON report from that run's default key-value store. Use decimal strings in JSON for price calculations; the CSV is for viewing and includes spreadsheet-safety escaping. Do not treat the summary dataset as the full product report. Follow Apify's current API examples for authentication and run/storage retrieval, and keep tokens out of URLs and shared logs.

### Connect your AI agent through Apify MCP

Use this tool for supplier price comparison, procurement price-list checks, and supplier catalog changes by SKU. Customers supply two authorized CSV snapshots; this is a comparison service, not a supplier database.

Official Apify setup for an MCP-compatible client (authenticated execution through this connection has not yet been tested by us):

```json
{
  "mcpServers": {
    "supplier-catalog-checker": {
      "url": "https://mcp.apify.com?tools=dharris289/supplier-catalog-change-checker"
    }
  }
}
```

Sign in to Apify through the client's supported OAuth flow using your own account. A completed comparison costs $3, including reports that flag ambiguous rows for review. Review the price and enforce a $3 maximum charge before running; do not expose tokens in URLs or shared configuration.

For discovery only, Apify supports the anonymous server `https://mcp.apify.com?tools=search-actors,fetch-actor-details`. Search for `supplier catalog` or fetch the exact Actor name `dharris289/supplier-catalog-change-checker`. That discovery-only connection cannot execute comparisons.

The MCP-inferred output describes the summary dataset, not the full product report. Wait for success, verify the run's OUTPUT completion marker, and retrieve REPORT and REPORT-CSV from its default key-value store using your authenticated Apify API or a client with authenticated storage access. Keep the returned run identifier; do not retry a paid run blindly after a connection timeout.

Official connection guidance: [Apify MCP server](https://docs.apify.com/integrations/mcp).

### Common problems and support

- **Spending limit:** set maximum cost to at least $3. A lower limit fails before reports or a comparison fee; inspect the run log for the spending-limit message. Billing configuration errors are also reported in the log, not necessarily ERROR.
- **Invalid input:** schema rejections appear in the Console form or API validation response before the program runs and create no ERROR record. For runtime input errors, inspect ERROR and correct the missing fields, mapping, or format. Inputs rejected before delivery do not request the comparison fee.
- **Review required:** the run still delivers a chargeable report. Resolve duplicate codes, missing values, or unclear currency/unit/identity against the original files. The tool does not choose a duplicate for you.
- **Report too large:** partition both snapshots by the same product-code rule into smaller batches. Each new comparison run is separately chargeable.
- **Failed run with pending billing:** reports may already exist and a charge reply may have been lost. Check the run's billing and contact the developer before starting another chargeable run. Do not blindly restart or resurrect it.

Use this Actor's Apify support channel with a run identifier, the error category, and a small fictional or sanitized example. Do not send passwords, tokens, confidential catalogs, or signed report links. Share a private run only if you deliberately want the developer to access its contents.

### Inputs

Supply `old_csv` and `new_csv` as text. Required business fields are `sku`, `price`, `currency`, `price_quantity`, and `unit`. Optional fields are `pack_quantity`, `description`, `brand`, and `manufacturer_part`. Use these canonical headers, or provide `old_columns` and `new_columns` mappings from canonical field names to your file headers. `delimiter` accepts comma, semicolon, or tab and applies to both files.

For Excel price lists, prepare and export the product table to CSV first, then paste the CSV text into the input fields. Native XLSX upload is not supported. Preserve product codes as text, including leading zeroes. Supply prices using a decimal point (for example 12.50), without grouping separators or currency symbols, with at most six fractional digits; remove only known spreadsheet floating-point residue, rather than silently rounding meaningful price precision. Confirm currency, effective date, region, and pricing basis from the source. Manufacturer list prices and account-specific distributor prices are different contexts.

`price_quantity` is the number of base units covered by the quoted price. A $20 quote for 100 ties is price `20`, price quantity `100`, unit `each`. Physical pack size is recorded separately. Confirm the pricing basis rather than inferring it from packaging. Supported units are each, ft, m, kg, lb, and l. Units are matched case-sensitively after trimming. Accepted aliases include ea/each, foot/feet/ft, and meter/metre/m. Uppercase variants (EA, Each, FT, M), box, pack, and other unsupported units are flagged for review; affected unit-price comparisons are withheld. No unit or currency conversions occur.

`old_defaults` and `new_defaults` can supply currency, price quantity, and unit only when the corresponding column is absent. Blank cells in present columns are flagged. Never use defaults to hide missing prices or unverified units.

Codes retain leading zeroes and case. Invisible/control characters and non-NFC codes are flagged for explicit cleaning rather than silently changing identities. Brand, manufacturer part, currency, or base unit changes block the price comparison. Description changes are visible; the customer must confirm the product identity and pricing context.

### Outputs and review flags

The Apify adapter saves `REPORT` as JSON, `REPORT-CSV` as an escaped presentation CSV, a machine-generated summary in the default dataset, and `OUTPUT` as the final completion marker. `ERROR` contains structured input errors on failure. A run must succeed and `OUTPUT.completed` must be true before treating it as delivered. Storage failures may leave partial artifacts; do not use partial files as a completed result.

JSON includes original trimmed text, source line references, input hashes, column mappings, explicit default counts, classifications, issues, and numeric comparisons as decimal strings. `quality: review_required` means flagged records need review. `quality: complete` means no input issues were detected; it does not verify source authority, supplier terms, scope, or economic value.

The CSV includes missing-code issue rows and duplicate source row references. Duplicate values are not selected or aggregated. Consult the original files to resolve duplicates. Only the summary is written to the Apify dataset so automated platform CSV exports contain no customer-controlled product text. The supplied CSV report escapes formula-like text; JSON preserves text for programmatic consumers.

An appearance or disappearance describes the supplied files only, not product availability or discontinuation. Unidentified rows prevent definitive absence classifications. Percent changes from a zero baseline are unavailable. Different quoted quantities have no quoted-price delta; the normalized unit-price comparison remains available when its basis is valid.

### Limits

Each CSV is limited to 2,000,000 UTF-8 bytes, 10,000 records, 50 columns, and 2,000 characters per cell. JSON reports are limited to 8,000,000 serialized bytes. These limits apply together; a 10,000-row input is not a promise that the report will fit. Start with 1,000-row batches and increase after measuring actual results. When batching, partition both snapshots by the same SKU rule so products cannot move between batches and create false additions/removals. Duplicate checks across batches remain the caller's responsibility.

No remote URLs, scraping, document extraction, LLM calls, purchasing recommendations, freight, tax, discounts, volume savings, or currency conversion are implemented. Input schema string limits count characters; runtime UTF-8 byte validation is authoritative.

### Commercial and storage status

The configured price is $3 per completed comparison, including reports that correctly flag ambiguous records for review. Platform usage is included in this event price, with no start or dataset-item fee. Each run is a separate comparison; a fresh run can incur another fee even with identical input. Review the price shown by Apify before starting a run.

The tool checks the spending limit before saving reports. It saves JSON, CSV, and a summary before requesting the comparison fee. Invalid inputs and failures before report delivery do not request this fee. A later billing-confirmation or status failure may leave a delivered report and a recorded charge. Contact support for unresolved billing; do not start another run blindly.

### Privacy and retention

Your catalogs and reports are stored in your Apify account. Before uploading confidential prices, set **Settings → Login & Privacy → General resource access → Restricted** and check any explicit sharing permissions. Customer runs inherit the customer's access settings; our developer account setting does not override them. Sharing a run with the developer can expose its inputs and outputs. Treat signed report links as bearer access: anyone with the link may be able to read the report. Use authenticated requests with a token in the Authorization header rather than a token in a URL.

This tool uses the run's default unnamed storage. It does not create a shared customer database, send catalogs to an LLM, fetch supplier sites, or copy customer files to the developer's systems or accounts. Apify retains input, JSON/CSV reports, delivery/billing state, and a dataset summary. Routine logs contain completion/status messages rather than product rows. Platform personnel and any recipients you authorize remain subject to Apify's policies and your account settings.

Retention follows your Apify plan and settings. The general storage documentation states that the Free plan retains the ten most recent runs for four months; older unnamed storage follows the account retention period. Paid plans follow their configured retention period, including recent runs. Naming a storage exempts it from automatic expiry. **Do not assume every report disappears in seven days.** Download results promptly, review Billing settings, and delete run/storage data through Apify when no longer needed. This tool does not automatically delete inputs or reports and promises no fixed deletion deadline or backup-erasure guarantee.

Upload only data you are authorized to process. Do not include passwords, tokens, payment details, or unrelated personal information. Use a nonsensitive pricing-tier label rather than a customer account number. Contact the developer with a sanitized example; share confidential run data only deliberately.

Validation used fictional hosted examples and public manufacturer price lists converted to prepared CSV batches. Your account access settings and source context must be checked separately.

This service compares customer-supplied files; it does not grant rights to resell supplier catalogs. Confirm authorized data access and permitted use for any future source-collection or resale product.

### Verified sources

- [Apify Actor lifecycle and storage APIs](https://docs.apify.com/sdk/python/reference/class/Actor)
- [Apify input schema](https://docs.apify.com/actors/development/actor-definition/input-schema/specification/v1)
- [Apify Actor definition](https://docs.apify.com/actors/development/actor-definition/actor-json)
- [Official Python SDK release](https://pypi.org/project/apify/4.0.2/)
- [Pay-per-event economics](https://docs.apify.com/actors/publishing/monetize/pay-per-event)
- [Resource access and customer-run ownership](https://docs.apify.com/account/collaboration/general-resource-access)
- [Storage retention, including recent-run exceptions](https://docs.apify.com/storage)

# Actor input Schema

## `old_csv` (type: `string`):

Paste UTF-8 CSV text, not a file path or URL. Maximum 2 MB, 10,000 records, 50 columns, and 2,000 characters per cell.

## `new_csv` (type: `string`):

Paste the matching current snapshot. An 8 MB report limit may require smaller batches.

## `supplier` (type: `string`):

Optional source label. Do not include credentials.

## `price_context` (type: `string`):

Use a nonsensitive tier/scope label, not an account number. The tool does not independently verify this context.

## `delimiter` (type: `string`):

The same delimiter is used for both snapshots.

## `old_columns` (type: `object`):

Optional mapping from sku, price, currency, price_quantity, unit, pack_quantity, description, brand, manufacturer_part to source header names.

## `new_columns` (type: `object`):

Optional source header mapping for the current snapshot.

## `old_defaults` (type: `object`):

Only currency, price_quantity, unit are accepted. Defaults fill absent columns only. Never infer a price basis from a box or pack.

## `new_defaults` (type: `object`):

Only currency, price_quantity, unit are accepted. Defaults and packaging changes may require review.

## Actor input object example

```json
{
  "old_csv": "sku,price,currency,price_quantity,unit\nDEMO-001,20.00,USD,100,each\n",
  "new_csv": "sku,price,currency,price_quantity,unit\nDEMO-001,22.00,USD,100,each\n",
  "delimiter": ","
}
```

# Actor output Schema

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

Full product classifications, issues and decimal-string price changes.

## `csvReport` (type: `string`):

Spreadsheet-safe presentation report.

## `completion` (type: `string`):

Check completed=true and billing status after the run succeeds.

# 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 = {
    "old_csv": `sku,price,currency,price_quantity,unit
DEMO-001,20.00,USD,100,each`,
    "new_csv": `sku,price,currency,price_quantity,unit
DEMO-001,22.00,USD,100,each`
};

// Run the Actor and wait for it to finish
const run = await client.actor("dharris289/supplier-catalog-change-checker").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 = {
    "old_csv": """sku,price,currency,price_quantity,unit
DEMO-001,20.00,USD,100,each
""",
    "new_csv": """sku,price,currency,price_quantity,unit
DEMO-001,22.00,USD,100,each
""",
}

# Run the Actor and wait for it to finish
run = client.actor("dharris289/supplier-catalog-change-checker").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 '{
  "old_csv": "sku,price,currency,price_quantity,unit\\nDEMO-001,20.00,USD,100,each\\n",
  "new_csv": "sku,price,currency,price_quantity,unit\\nDEMO-001,22.00,USD,100,each\\n"
}' |
apify call dharris289/supplier-catalog-change-checker --silent --output-dataset

```

## MCP server setup

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

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/u8WU61D9WvygbJcvS/builds/D1GL8PbQx3oxM0bap/openapi.json
