# Shopify Public Catalog & Variant Change API (`soilair/shopify-public-catalog-change-api`) Actor

Read public Shopify catalogs and variant prices with product hashes for change detection. No login or invented sales estimates.

- **URL**: https://apify.com/soilair/shopify-public-catalog-change-api.md
- **Developed by:** [Salih Can Kurnaz](https://apify.com/soilair) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product snapshots

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 Public Catalog & Variant Change API

Read public Shopify catalogs and variant prices with product hashes for change detection. No login or invented sales estimates.

### What you can do

Track publicly exposed product and variant prices across repeated catalog snapshots.

### Quick start

```json
{
  "storeUrl": "https://www.allbirds.com/",
  "maxItems": 10,
  "maxPages": 1
}
```

Run the Actor and download the default dataset as JSON, CSV or Excel. Inspect the `OUTPUT` key-value-store record before treating the run as complete. Live example sources can change or become unavailable.

### Behavior and limitations

Uses a store's public /products.json endpoint, up to 100 products per page. Products include variants, price, compare_at_price, availability flags, tags and image URLs as exposed by the source. No authentication, bypass, proxies or browser is used. Prices are source strings; currency is not inferred. Public variant available values do not provide stock counts. Pass previousHashes keyed by productId to detect changed product snapshots. No removals are inferred. complete is true only after an empty pagination page, with no errors or truncation; reaching maxItems or maxPages is explicitly partial. Robots restrictions, HTTP blocking or absent endpoints are reported as errors. Compatibility depends on the individual storefront, not just Shopify branding.

Every result preserves its source URL and an `observedAt` UTC timestamp. Network or parsing errors are listed by source in `OUTPUT.errors`; other successful sources still return results. `OUTPUT.warnings`, `complete` and `status` distinguish a full observation from partial output. If every requested source fails, the run fails rather than silently returning an empty success.

### Pricing

USD 1 per 1,000 successful product snapshot rows ($0.001 per row), plus a $0.005 Actor-start event for the default 256 MB run. No result event is charged for a failed source. The Actor-start event can still apply to a failed run. Higher memory can increase start-event quantity according to Apify's rules. This description must match the currently effective Store pricing; check the pricing tab before running. Apify charges only as configured there.

### Resource and access limits

At most 1,000 output rows; public ports 80/443 only; five redirects; 2 MiB decoded body per request; approximately 100 seconds for fetching. Requests are sequential with no retries, CAPTCHA bypass, credentials, residential proxies or paid upstream APIs. robots.txt is respected; missing robots.txt (404/410) allows fetching, while blocked or unavailable policies produce errors. Public DNS addresses are validated and pinned for each connection. Use only sources you are permitted to access and respect source terms. Private networks and URLs with embedded credentials are rejected.

### API and automation

Call `POST https://api.apify.com/v2/actors/soilair~shopify-public-catalog-change-api/runs` with the example JSON and your own Apify authorization header. Poll the returned run ID, then fetch `/v2/datasets/{defaultDatasetId}/items`. Schedule subsequent runs in Apify Console; pass earlier keys/hashes explicitly where supported. The Actor never schedules jobs itself.

### Data handling and support

Input and results remain in your Apify run's storage under the platform's retention settings. The Actor sends requests only to the input sources, their public redirects and robots.txt. No separate analytics or customer-data endpoint is used. Do not put secrets or private customer URLs in the input. Developed with AI assistance and tested with deterministic fixtures plus public-source smoke checks; this does not guarantee all storefronts or websites will work. For support, send the run ID, source URL and expected behavior via the Apify issue tab without credentials.

# Actor input Schema

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

Bounds output rows. Truncation is reported in OUTPUT.

## `storeUrl` (type: `string`):

Public Shopify store origin without a path or query.

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

At most 100 products requested per page.

## `previousHashes` (type: `object`):

Map productId to its previous contentHash. Maximum 5,000 entries.

## Actor input object example

```json
{
  "maxItems": 100,
  "storeUrl": "https://www.allbirds.com/",
  "maxPages": 3,
  "previousHashes": {}
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (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 = {
    "storeUrl": "https://www.allbirds.com/"
};

// Run the Actor and wait for it to finish
const run = await client.actor("soilair/shopify-public-catalog-change-api").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 = { "storeUrl": "https://www.allbirds.com/" }

# Run the Actor and wait for it to finish
run = client.actor("soilair/shopify-public-catalog-change-api").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 '{
  "storeUrl": "https://www.allbirds.com/"
}' |
apify call soilair/shopify-public-catalog-change-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,soilair/shopify-public-catalog-change-api"
        }
    }
}
```

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/Td4CinOmazR7v5uUM/builds/I3hiAVDgGBEN22UJr/openapi.json
