PAL Shopify Catalog & Variant Change Tracker avatar

PAL Shopify Catalog & Variant Change Tracker

Pricing

from $2.00 / 1,000 product variant exporteds

Go to Apify Store
PAL Shopify Catalog & Variant Change Tracker

PAL Shopify Catalog & Variant Change Tracker

Recheck bounded public product feeds for newly listed, removed, repriced or changed variants. For Shopify operations and migration teams. Check the live Pricing tab and input limits.

Pricing

from $2.00 / 1,000 product variant exporteds

Rating

0.0

(0)

Developer

Practical AI Lab

Practical AI Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Practical AI Lab (PAL) Actor for pricing and market-research teams. It reads the public product feed of up to three Shopify storefronts, produces a clean variant-level dataset, and – when you hand it the previous snapshot – tells you exactly what changed:

  • variants added or removed
  • price changes (absolute and % delta)
  • compare-at price changes
  • availability flips (in stock ⇄ sold out)

Store version: production-ready. Pay-per-event pricing is configured; the active plan is listed in the Pricing tab.

Try a real public storefront: the input form is pre-filled with https://www.allbirds.com and a low-cost starter limit of two products, one page. This public feed was reachable during a read-only test on October 24, 2026; availability can change. For a bigger snapshot, increase the product/page limits (up to 200 products per store). This tool is not affiliated with Allbirds or Shopify.

How it works (buyer steps)

  1. Baseline run – enter 1–3 store URLs (https://shop.example.com) and run. Every row has changeType: "baseline".
  2. Open the run's Key-value store and copy the SNAPSHOT record (JSON).
  3. Comparison run (days or weeks later) – same store URLs, paste that JSON into Previous snapshot.
  4. Download the dataset as JSON or CSV. Filter on changeType (added, removed, changed, unchanged) and changeTypes (price_changed|compare_at_price_changed|availability_changed). Tick off Output unchanged variants to get only the differences.
  5. Save the new SNAPSHOT as the baseline for the next comparison.

RUN_SUMMARY in the same key-value store lists a status per store.

Example input

{
"storeUrls": ["https://shop.example.com"],
"previousSnapshot": { "schemaVersion": 1, "variants": [ ... ] },
"maxProductsPerStore": 200,
"emitUnchanged": false
}

Example output row (changed)

{
"variantKey": "shop.example.com:7001:42001",
"productKey": "shop.example.com:7001",
"sourceStore": "shop.example.com",
"productTitle": "Trail Bottle", "variantTitle": "750 ml", "sku": "TB-750",
"price": "24.00", "previousPrice": "28.00", "priceDelta": "-4.00", "priceDeltaPercent": -14.29,
"compareAtPrice": "28.00", "available": true, "previousAvailable": false,
"changeType": "changed", "changeTypes": "price_changed|compare_at_price_changed|availability_changed",
"currency": null,
"productUrl": "https://shop.example.com/products/trail-bottle",
"variantUrl": "https://shop.example.com/products/trail-bottle?variant=42001"
}

Stable keys

variantKey = <store host>:<Shopify product id>:<Shopify variant id>. Keys use Shopify's numeric ids, so renamed titles or handles do not break comparisons. If a merchant deletes and recreates a product, Shopify issues new ids and it will show as removed + added.

Safety behaviour

  • Only https:// store roots; reads only /robots.txt and /products.json (GET, no cookies, no login, no checkout, no customer data, no CAPTCHA handling).
  • robots.txt is honoured; a Disallow covering /products.json ends that store's run. An unreadable robots file (403/429/5xx) also stops it.
  • HTTP 403, 429, non-JSON or non-Shopify responses stop the store immediately (no retries, no workarounds).
  • SSRF protection: hostnames must be public domains; every DNS answer must be a public IP (loopback, private, link-local, reserved, multicast and IPv4-embedding IPv6 ranges are refused); the connection is pinned to the validated IP; redirects are followed only over HTTPS to the same host and re-validated.
  • Caps: 3 stores, 200 products/store, 8 pages/store, 5 MB/response, 15 s per request, 90 s and 20 requests per store.
  • A store that fails emits no rows and is never charged. Failed stores are never treated as "everything removed".

Limitations – please read

  • Availability is a boolean (available) from the public feed. It is not an inventory count.
  • Currency is null. Public /products.json does not reliably expose it; prices are the storefront's numeric amounts (formatted to 2 decimals). Market-specific or discount-code pricing is not reflected.
  • Max 200 products per store. For larger catalogs the store is partial_limit, and removed-variant detection is skipped (otherwise unseen products would be reported as removed).
  • Stores that disable or hide /products.json, password-protect the storefront, or disallow it in robots.txt cannot be read. Shopify may also return a subset of products on some themes/apps.
  • Only data published by the store itself is returned; no customer, order or checkout information.
  • Comparisons only cover stores present in the supplied snapshot (others are not_compared). Baseline rows for variants of a store that could not be read are simply left untouched in your own saved copy.
  • The Actor is not affiliated with Shopify. Use it only on stores and for purposes your legal advice and the store's terms allow.

Output views & schema

Dataset fields are listed in the Variant snapshot & changes view. Per-store statuses: ok, partial_limit, robots_denied, blocked, no_public_feed, non_json, http_error, timeout, network_error, response_too_large, redirect_blocked, blocked_destination, robots_unavailable, request_limit, invalid_url, duplicate, stopped_charge_limit, skipped_charge_limit.

Pricing

Pay-per-event pricing is configured. The Actor charges the event variant-emitted once per successfully emitted current variant row (removed rows, failures and skipped stores are free) and stops cleanly when your run's charge limit is reached. It does nothing at all if that event is not configured.

Development

python3 -m unittest discover -s tests # offline, standard library only