Shopify Competitor Price Tracker & Stock Monitor
Under maintenancePricing
Pay per usage
Shopify Competitor Price Tracker & Stock Monitor
Under maintenanceTrack Shopify competitor prices, product availability and catalog changes across public stores with automated change detection.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Ege Usta
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Shopify Competitor Price & Stock Monitor
Track competitor pricing and product availability for ecommerce research, pricing intelligence and catalog monitoring. Add public Shopify stores and get structured snapshots plus changes between runs.
Monitors one or more public Shopify stores via their /products.json
endpoint and emits deterministic change events between runs.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
storeDomains | string[] | — (required) | shop.com, https://shop.com, or shop.myshopify.com. Non-http(s) schemes, IP literals and localhost are rejected. Duplicates are collapsed. |
maxProductsPerStore | integer | 2000 | Distinct-product cap per store. |
maxPagesPerStore | integer | 20 | /products.json page cap (page size 250). |
requestTimeoutSecs | integer | 30 | Per-request timeout. |
concurrency | integer | 3 | Stores fetched in parallel. |
minRequestDelayMs | integer | 500 | Client-side rate limit between paginated requests. |
maxResponseBytes | integer | 5000000 | Byte ceiling per response. |
emitSnapshotRows | boolean | true | Also write the current variant-level catalog to the dataset. |
resetSnapshot | boolean | false | Ignore the stored snapshot; treat as a fresh baseline. |
How comparison works
Each run fetches the current catalog, loads the previous snapshot from the
key-value store (SNAPSHOT-<domain>), diffs them deterministically, writes the
new snapshot, and appends events to the dataset.
- First run for a domain (or
resetSnapshot) establishes the baseline and emits no change events (firstRun: truein the summary). - Event types:
new_product,removed_product(a product id appeared / disappeared);price_changed(a shared variant's price, compare-at price or SKU moved, or a new variant appeared under an existing product withbefore: null);availability_changed(a shared variant'savailableflag flipped, or a variant disappeared from a surviving product withafter.removed: true). - Events are fully sorted (type → productId → variantId) so re-running on unchanged data produces byte-identical output.
Resilience
- A request failure stops pagination for that store, is counted in
requestFailures/failuresByReason, and never throws. - If every page fails (
pagesFetched === 0) the stored snapshot is left untouched and no events are emitted — a network blip never looks like "all products removed". - If a previously populated store (> 5 products) suddenly returns an empty
catalog, the run flags
suspicious-empty-catalogand refuses to overwrite the snapshot. - One failing store never affects the others (bounded-concurrency, per-store isolation).
Output
type: "change" and type: "snapshot" rows — see .actor/dataset_schema.json.
A SUMMARY record with per-domain reports, totals, changeCounts and
failuresByReason is written to the key-value store.
Safety
Only the public /products.json endpoint is used — no admin API, no tokens, no
private data. All requests go through the shared safeFetchJson (https upgrade,
DNS checked against private ranges, manual redirects, JSON content-type
allow-list, byte ceiling, timeout cleared in finally).
Known limitations
- Stores that disable
/products.json, sit behind Cloudflare bot protection, or are not Shopify will yieldcatalog-fetch-failed/ an empty parse rather than data. This is reported, not fatal. availablereflects the storefrontavailableflag, not real-time inventory counts (Shopify does not expose those publicly).
Commands
npm ci # monorepo rootnpm run check -w shopify-competitor-price-stock-monitornpm run smoke -w shopify-competitor-price-stock-monitor # offline, two-run diffnpx apify validate-schema
Deployment
Not deployed here. apify push is intentionally not run — the lead engineer
handles deployment.