# Supplier Catalog Comparison (`cory8484/my-actor-1`) Actor

Compare two supplier price-list PDFs by exact SKU. Find price increases, decreases and one-sided products, with CSV exports and source evidence. Supports ruled tables and selected three-column borderless layouts. Includes a free demo.

- **URL**: https://apify.com/cory8484/my-actor-1.md
- **Developed by:** [Cory Maag](https://apify.com/cory8484) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 compared products

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?

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

### What does Supplier Catalog Comparison do?

**Compare two supplier price-list PDFs by exact product code.** Find price increases, decreases, unchanged prices, and products appearing in only one extracted catalog. Download a CSV with source evidence for purchasing reviews and catalog updates.

Try the fictional demo by leaving both PDF URLs blank. It returns five comparisons without paid product events. You can run the Actor from Apify Console or connect it to your workflow through the Apify API and integrations.

### Why use it?

Use it to review supplier revisions, prioritize price changes, and prepare catalog updates without manually comparing every line. It compares documents you provide; it does not search suppliers, place orders, or certify that a product is discontinued.

### How to use it

1. Run the blank-input demo to see the output.
2. Enter both direct, public HTTPS PDF URLs.
3. Select the same currency, number format, and price basis for both documents.
4. Choose the appropriate table layout for each PDF. Include all relevant pages and annexes.
5. Set a spending ceiling, run the comparison, and inspect SUMMARY and REVIEW before using COMPARISON.csv.

### Input and supported formats

The default `ruled` layout supports English text-based PDFs with table borders and recognizable SKU, description, and price headers. Optional zero-based column maps select these columns and an optional unit column.

The optional `borderless-price-list` layout supports three single-line columns: description/category, **Product code**, and **List price** followed by USD, CAD, AUD, EUR, or GBP. Product codes and prices must be right-aligned. It does not automatically guess a layout. Wrapped descriptions, shifted columns, or extra columns cause the affected section to require review. Column overrides in this mode must be description=0, sku=1, price=2, with no unit column.

Limits are 10 MiB per PDF, 20 pages and 5,000 candidate rows per PDF. Scanned PDFs require OCR elsewhere. General-purpose borderless tables and password-protected documents are unsupported.

#### Tested historical example

The [2024 Exact Tools list](https://pijpzaagmachine.nl/wp-content/uploads/2023/10/Exact-Tools-price-list-2024.pdf) and [2025 list](https://pijpzaagmachine.nl/wp-content/uploads/2024/10/Exact-Tools-price-list-2025.pdf) were tested across all five pages. Keep the 2025 annex: it contains older models still listed while stocks last.

```json
{
  "beforePdfUrl": "https://pijpzaagmachine.nl/wp-content/uploads/2023/10/Exact-Tools-price-list-2024.pdf",
  "afterPdfUrl": "https://pijpzaagmachine.nl/wp-content/uploads/2024/10/Exact-Tools-price-list-2025.pdf",
  "currency": "EUR",
  "numberFormat": "decimal-comma",
  "maxPages": 3,
  "beforeTableMode": "borderless-price-list",
  "afterTableMode": "borderless-price-list"
}
```

This example produced 68 usable comparisons: 8 increases, 4 decreases, 41 unchanged, 4 only in before, and 11 only in after. Two product codes containing spaces were preserved for review in each document. The cloud CSV matched the locally verified output. These results establish compatibility with this pair, not every supplier PDF.

### Output

The dataset contains one usable comparison per product code. You can download the dataset in formats such as JSON, CSV, or Excel using Apify's export options. COMPARISON.csv is a separate flat export in the key-value store.

| Field or file | Meaning |
| --- | --- |
| sku | Exact product code, with leading zeros preserved |
| change\_type | Increased, decreased, unchanged, or observed in only one document |
| before / after | Price, description, currency, unit, source page and row evidence |
| price\_change | After price minus before price |
| price\_change\_percent | Percentage change from the before price |
| flags | Caveats such as an unstated pack size |
| COMPARISON.csv | Flat export of delivered comparisons |
| REVIEW | Ambiguous identities and rejected records; uncharged |
| SUMMARY | Extraction counts, warnings, delivered count and budget stop |

A simplified fictional result:

```json
{"sku":"001","change_type":"price_increased","price_change":"2.50","price_change_percent":"25.0000"}
```

### Pricing and cost estimation

**$5 per 1,000 delivered comparisons ($0.005 each), with platform usage included.** Unchanged and one-sided observations also count. Only price changes are not the billing unit. Demo and REVIEW records are uncharged.

A 68-comparison run has a listed event price of $0.34. A $0.25 ceiling allows at most 50 paid comparisons; increase it when you need a larger complete output. Inspect `budget_stopped` and `delivered_rows` in SUMMARY. The CSV contains only delivered comparisons. A per-run ceiling is not an account-wide cap.

### Tips and limitations

Match list price to list price or net price to net price. A changed description, currency or unit requires review and does not produce a numeric change claim. Missing units carry a pack-size verification flag. Product codes are compared exactly without case folding or removing leading zeros. Codes containing spaces are conservatively held for review.

Only-in-before/after means absence from the extracted pages, not proof of addition or discontinuation. Partial or unsupported extraction is flagged. If either document has no usable products, no comparisons are emitted. Import SKU columns as text; formula-like CSV values, including negative deltas, are prefixed with an apostrophe for spreadsheet safety.

### FAQ and support

**Will it monitor suppliers automatically?** Each run compares one supplied pair. No recurring schedule is created automatically.

**Does it use an AI model or OCR?** No. It uses deterministic PDF text extraction and exact-code comparison.

**Why does SUMMARY say needs\_review?** Review records, unsupported sections or partial page ranges remain visible even when other rows are usable. Check REVIEW and the source documents before importing prices.

Only process documents you are authorized to use. Inputs, results and evidence remain in Apify run storage under its retention settings. Public document availability can change. This Actor does not certify completeness or correctness.

Use the Actor's Issues tab for support. Include the layout mode and a non-sensitive description of the problem; do not post confidential supplier documents publicly.

# Actor input Schema

## `beforePdfUrl` (type: `string`):

Direct public HTTPS PDF URL. Leave both URLs blank for the fictional demo.

## `beforeFirstPage` (type: `integer`):

Before first page. Applies to each selected PDF range.

## `beforeColumnMap` (type: `object`):

Optional zero-based sku, description, price and unit column indexes.

## `afterPdfUrl` (type: `string`):

Direct public HTTPS PDF URL. Leave both URLs blank for the fictional demo.

## `afterFirstPage` (type: `integer`):

After first page. Applies to each selected PDF range.

## `afterColumnMap` (type: `object`):

Optional zero-based sku, description, price and unit column indexes.

## `currency` (type: `string`):

Select currency explicitly for real PDFs.

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

Maximum pages per PDF. Applies to each selected PDF range.

## `maxRows` (type: `integer`):

Maximum rows per PDF. Applies to each selected PDF range.

## `numberFormat` (type: `string`):

Number format. Applies to each selected PDF range.

## `beforeTableMode` (type: `string`):

Borderless price list: three aligned columns, description/category | Product code | List price with currency. Single-line rows only; ambiguous sections require review.

## `afterTableMode` (type: `string`):

Borderless price list: three aligned columns, description/category | Product code | List price with currency. Single-line rows only; ambiguous sections require review.

## Actor input object example

```json
{
  "beforeFirstPage": 1,
  "afterFirstPage": 1,
  "maxPages": 10,
  "maxRows": 2000,
  "numberFormat": "decimal-dot",
  "beforeTableMode": "ruled",
  "afterTableMode": "ruled"
}
```

# Actor output Schema

## `comparisons` (type: `string`):

No description

## `files` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("cory8484/my-actor-1").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("cory8484/my-actor-1").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 '{}' |
apify call cory8484/my-actor-1 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cory8484/my-actor-1"
        }
    }
}

```

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/mGKOcnAMxtbJ9eAc0/builds/YkQXd6uQbmFqLRKMK/openapi.json
