# Shopify Variant Catalog Export – SKU, Price & Stock (`wavy_toucanet/shopify-variant-catalog-export`) Actor

Paste public Shopify storefront URLs (domain only) and get one row per variant: product, size or color, SKU, price, compare-at price, availability and variant link. Up to 10 stores and 1,000 rows per run as CSV or JSON. Non-Shopify or blocked stores are reported, not charged.

- **URL**: https://apify.com/wavy_toucanet/shopify-variant-catalog-export.md
- **Developed by:** [kalle walle](https://apify.com/wavy_toucanet) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 exported variants

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 Variant Catalog Export – SKU, Price & Stock

Give it public Shopify storefront URLs (domain only) and get one row per variant: product, variant title, SKU, price, compare-at price, availability and a direct variant link. Up to 10 stores and 1,000 variant rows per run, as `OUTPUT.csv` or dataset JSON, CSV or Excel.

The Actor reads the storefront's public `/products.json` catalog. No browser, login, paid proxy or AI model is used. Stores that are not Shopify, are password-protected or block the request are reported in `REPORT` and are not charged.

### What it is for

- **Catalog comparison at variant level:** sizes and colors as separate rows with SKU and price, ready for a spreadsheet.
- **SKU matching for resellers and agencies:** check which variants carry a SKU and whether it matches your own list.
- **Availability snapshot:** see which variants a store shows as available or sold out at the time of the run.
- **AI agents and pipelines:** call it through the Apify API or the Apify MCP server.

What it does not do: inventory quantities, reviews, private Admin API data, order or customer data, price history across runs, or the market currency (always empty, see below). Each run is a snapshot, not monitoring.

### Example

Input:

```json
{
  "stores": ["https://example.com", "https://www.allbirds.com"],
  "maxPagesPerStore": 1,
  "maxItems": 12
}
```

Output from a real local run on 25 October 2026, first rows (selected columns):

| title | variantTitle | sku | price | compareAtPrice | available |
|---|---|---|---|---|---|
| Women's Allbirds Flip Flop - Dusty Pink | 5 | A12513W050 | 25.00 | 50.00 | false |
| Women's Allbirds Flip Flop - Dusty Pink | 10 | A12513W100 | 25.00 | 50.00 | true |
| Men's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole) | 8.5 | A12498M085 | 100.00 | | true |

`REPORT` for the same run: 12 rows, stop reason `max_items`, and one error: `https://example.com` returned `http_404` because it has no Shopify catalog. That store produced no row and no charge. The store in the example was chosen only because its catalog is public; this Actor is not affiliated with it.

### How to run

1. Enter one to ten storefront origins in **Shopify storefront origins**, such as `https://www.example-store.com` (HTTPS, no path or query).
2. **Maximum catalog pages per store** defaults to 2; each page holds up to 250 products.
3. **Maximum output rows** defaults to 100; raise it up to 1,000. Set your maximum charge in Apify.
4. Start the run and download `OUTPUT.csv` from the key-value store, or export the dataset.

### Input

| Field | Default | Behavior |
|---|---|---|
| `stores` | Required | 1–10 public HTTPS storefront origins, no path or query; identical entries are fetched once, and rows already emitted in the run are not charged twice |
| `maxPagesPerStore` | `2` | 1–10 catalog pages per store, up to 250 products each; stops on an empty, short or non-advancing page |
| `maxItems` | `100` | 1–1,000 variant rows per run |
| `maxRunSeconds` | `120` | 30–600 seconds, checked before each request or output row |

### Output

One dataset row per variant:

| Field | Meaning |
|---|---|
| `recordId` | Store host and variant ID |
| `storeUrl` | Storefront origin |
| `productId`, `variantId` | Shopify IDs as strings |
| `title` | Product title |
| `variantTitle` | Variant name, for example a size or color |
| `sku` | Variant SKU as published, or `null` |
| `price`, `compareAtPrice` | Decimal strings as published; `compareAtPrice` is `null` when not set |
| `available` | Availability flag as published (`true`/`false`), not a quantity |
| `currency` | Always `null`: the public catalog response does not reliably state the market currency, so none is guessed |
| `productUrl` | Link to the product page with the variant preselected |
| `retrievedAt` | Time of the observation |

The key-value store contains `OUTPUT.csv`, `REPORT` (`product`, `emittedCount`, `errors` with the affected store, `stopReason` and `paymentsVerified=false`) and `STATE` (recovery checkpoint for the same run and parsed input). `OUTPUT.csv` quotes values and escapes potential spreadsheet formulas; other exporters may behave differently. Source values and observation times are preserved rather than invented.

### Pricing

**$0.0015 per variant row ($1.50 per 1,000 rows)**, with no start event. Invalid input, failed fetches and duplicates already emitted in the same run are not charged. Check the Pricing tab before a run and set your maximum charge in Apify.

### Use it from an AI agent

The [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) can load this Actor as a tool. Add this server URL to an MCP client such as Claude, Cursor or VS Code:

```text
https://mcp.apify.com?tools=wavy_toucanet/shopify-variant-catalog-export
```

You sign in to Apify in the browser on first connection (OAuth); runs are billed to your Apify account.

### Limits and recovery

Only HTTPS storefront origins are accepted, and the store must expose `/products.json`. Password-protected, blocked and non-Shopify stores are reported without result rows. Pagination is bounded, so a run does not guarantee a complete catalog. Prices are observations, not purchase recommendations.

Requests are sequential, bounded and rate-limited. Only public targets on standard ports are allowed, with DNS address validation and pinning. No retries against blocked pages and no paid proxies. On restart, existing rows are checked against a pending-write checkpoint; an uncertain missing write stops for review. This is not an exactly-once billing guarantee. Inputs must stay identical on recovery; a fresh run is a new paid batch. Error reports may contain the supplied store URLs; do not include secret-bearing URLs.

### FAQ

**Can't I just open `/products.json` in my browser?** Yes, for one page of one store. The Actor flattens every variant into its own row, follows pagination, handles several stores, reports failures and writes a spreadsheet-safe CSV.

**Why is the currency empty?** The public catalog does not reliably say which market currency the prices are in. The Actor leaves it empty instead of guessing.

### Source and support

Data comes from each store's public catalog. Only process sources you have permission to access and reuse; public accessibility does not by itself grant redistribution rights. This is an independent tool, not affiliated with or endorsed by Shopify. Report reproducible issues through the Issues tab with a run ID and error code; never include credentials.

# Actor input Schema

## `stores` (type: `array`):

One to ten public HTTPS storefront origins, with no path or query.

## `maxPagesPerStore` (type: `integer`):

Each page requests at most 250 products. Stops on an empty, short or non-advancing page.

## `maxItems` (type: `integer`):

Successful unique result rows. Each row is one dataset event when monetized.

## `maxRunSeconds` (type: `integer`):

Time limit checked before each lookup or output; an in-flight request can finish later.

## Actor input object example

```json
{
  "stores": [
    "https://www.allbirds.com"
  ],
  "maxPagesPerStore": 2,
  "maxItems": 100,
  "maxRunSeconds": 120
}
```

# Actor output Schema

## `dataset` (type: `string`):

Result records

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

Errors and stop reason

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

Spreadsheet-safe 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 = {
    "stores": [
        "https://www.allbirds.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("wavy_toucanet/shopify-variant-catalog-export").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 = { "stores": ["https://www.allbirds.com"] }

# Run the Actor and wait for it to finish
run = client.actor("wavy_toucanet/shopify-variant-catalog-export").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 '{
  "stores": [
    "https://www.allbirds.com"
  ]
}' |
apify call wavy_toucanet/shopify-variant-catalog-export --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wavy_toucanet/shopify-variant-catalog-export"
        }
    }
}
```

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/KYhtfcjWomvLfb8ZG/builds/PsDJavK7LLfoNvYHq/openapi.json
