Shopify Catalog Change Monitor: Prices & Variants
Pricing
from $2.00 / 1,000 change records
Shopify Catalog Change Monitor: Prices & Variants
Monitor published Shopify catalog changes between bounded snapshots: newly listed and removed products, price moves, variant option differences and availability flips. Start with a baseline, then repeat the same public-store scan. No hidden inventory claims.
Pricing
from $2.00 / 1,000 change records
Rating
0.0
(0)
Developer
Practical AI Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Detects what changed in a public Shopify catalog between two points in time: newly listed products, removed products, added or removed variants, published price movements, compare-at price changes, stock flips and title edits. Output is one dataset row per change, not a full catalog dump.
It is built for recurring monitoring (for example a scheduled daily run), not for one-off exports. If you only need a current product list, a plain Shopify product scraper is a better fit.
How it works
- First run per store reads the public
/products.jsonfeed and saves a compact baseline in a named key-value store (snapshotStoreName). No change records are produced, so nothing is charged. - Every later run reads the feed again, compares it with the saved baseline, emits change records, then replaces the baseline.
- Offline mode (optional): supply
baselineProductsandcurrentProductsin Shopifyproducts.jsonformat that you already hold. No network access happens.
Sample input
{"storeUrls": ["https://www.allbirds.com"],"maxProductsPerStore": 500,"minPriceChangePercent": 1,"changeTypes": ["product_added", "product_removed", "price_changed", "availability_changed"],"snapshotStoreName": "my-catalog-snapshots"}
Replace the store with one you are entitled to monitor. Use the store's canonical domain: redirects are not followed, and the error message tells you where a store redirects to.
Input
| Field | Meaning |
|---|---|
storeUrls | 1-10 public https:// Shopify store addresses. |
maxProductsPerStore | 1-5000, default 1000. |
minPriceChangePercent | Ignore smaller price moves. Default 0. |
changeTypes | Subset of the change types below. Empty means all. |
maxChangeRecords | Per-store cap on emitted rows, default 1000. |
resetBaseline | Replace the baseline with the current catalog; report nothing. |
snapshotStoreName | Named key-value store holding baselines. |
requestDelaySeconds | Pause between page requests, 0.5-30. |
baselineProducts, currentProducts | Optional offline comparison. |
Output
Change types: product_added, product_removed, variant_added, variant_removed, price_changed, compare_at_price_changed, availability_changed, title_changed.
Example row:
{"store": "https://www.example-store.com","change_type": "price_changed","product_id": "123","title": "Example Shirt","product_url": "https://www.example-store.com/products/example-shirt","variant_id": "456","variant_title": "M","sku": "SHIRT-M","old_value": "20.00","new_value": "15.00","price_delta": "-5.00","price_change_percent": "-25.00","detected_at": "2026-01-02T00:00:00Z","baseline_taken_at": "2026-01-01T00:00:00Z"}
For product_added and product_removed, variant_count and lowest_price are filled instead of old/new values. A per-store summary (status, product count, change counts, warnings, errors) is saved to the OUTPUT record of the run's key-value store.
Pricing and errors
The Actor emits one change-record event per change row, and only after the row is stored. Runs that fail, stores that error, baseline-creation runs and runs with no changes produce no charge events. The payable plan is configured separately on the platform; this repository does not set one.
Safety
- Only
https://store domains on the default port; IP addresses, credentials, local and internal host names are rejected. - The host is resolved before use and must resolve only to public addresses.
robots.txtis checked first; a disallow rule, or a 401/403/5xx on robots.txt, stops that store.- Redirects are never followed; requests are sequential, delayed, size-limited and capped at 40 pages per store.
- No logins, proxies, cookies or personal data are used. Only product, variant, price and availability fields are kept.
Limitations
- Works only for stores that leave
/products.jsonpublicly enabled. Many stores disable or restrict it. - The feed shows the storefront default prices. It does not show currency, per-market prices, discounts applied at checkout, customer-specific prices, or exact inventory counts (only an in/out-of-stock flag).
- Catalogs larger than
maxProductsPerStoreare truncated. A truncated current snapshot cannot prove removal, so removals are skipped; a truncated baseline cannot prove addition, so additions are skipped. Warnings are written to the summary. - Draft, hidden or unpublished products are not visible; "removed" can also mean "unpublished".
- Change detection depends on schedule frequency: several changes between two runs collapse into the net difference.
- DNS is checked before connecting but not pinned to the connection; a hostile DNS change between check and request is not fully excluded.
- Shopify store data may be subject to the store's terms and applicable law. You are responsible for lawful use.
- Results from a few stores or a few runs are anecdotal; treat price movement statistics from small samples with caution.
Development
Offline tests: python -m unittest discover -s tests