Shopify Variant Monitor - Prices & Availability avatar

Shopify Variant Monitor - Prices & Availability

Pricing

from $0.90 / 1,000 variant observations

Go to Apify Store
Shopify Variant Monitor - Prices & Availability

Shopify Variant Monitor - Prices & Availability

Monitor public Shopify variants for price, availability and option changes. Save stable IDs and previous observations. No login, API key or proxy required; bounded catalog and product URL inputs.

Pricing

from $0.90 / 1,000 variant observations

Rating

0.0

(0)

Developer

Brandt May

Brandt May

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Follow the variant, not just the page — illustrative workflow

Follow the variant, not just the page

For product and pricing research: collect public Shopify variant observations with stable product and variant IDs, listed prices, options and purchasing availability. Use a bounded catalog or selected product pages.

Open this Actor in Console · First run · Results · Cost · Full guide

Try this Actor

  • First run: Use Death Wish Coffee - Variant Price Sample below: up to five products and 25 saved rows. Inspect the variant IDs and currency evidence before enabling saved comparisons.
  • Read the results: Open the default Dataset for variant rows and SUMMARY for store coverage. The saved price, change types and source product link provide the evidence for a comparison.
  • Keep in mind: Availability means the variant is purchasable, not a stock quantity. Prices remain decimal strings; currency is populated only when verified from the source. Unsupported storefronts or catalog limits can leave gaps.

Death Wish Coffee - Variant Price Sample — copy this input into the JSON editor in Console.

{
"stores": [
"https://www.deathwishcoffee.com"
],
"maxProductsPerStore": 5,
"maxResults": 25
}

Result preview

The dataset view highlights these columns:

  • Product · title
  • Variant · variantTitle
  • Product URL · productUrl
  • Product ID · productId
  • Variant ID · variantId
  • Listed price · price

Use the original source links and the field definitions below when interpreting the results. CSV works well for flat columns; JSON preserves nested values.

Usage and pricing

Base result rate on the FREE tier: $1.5 per 1,000 variant observations. The Pricing tab shows your plan's result rate and any Actor Start charge. Set a small result limit for the first run; the requested limit is not a guarantee of that many results.


Customer workflow: A variant price and availability review board

Watch a small list of exact public product URLs, update each variant in place, and route verified price or availability changes for review without inventing inventory quantities or cross-currency discounts.

Setup: Connect your own Apify and Google Sheets latest-variant register and merchant review queue through Make or n8n. Keep credentials in your connector's credential manager.

{
"stores": [],
"productUrls": [
"https://www.deathwishcoffee.com/products/klean-kanteen-camp-mug"
],
"maxResults": 250,
"comparePrevious": true,
"onlyChanges": false,
"snapshotName": "customer-product-watch-v1",
"maxRunSeconds": 240
}

Start with a 300-second Run timeout and $0.50 maximum run charge, alongside the input's 240-second budget. Check current pricing and the selected scope before increasing either limit.

  1. Create a Variants sheet and replace the demo URL with your product watchlist. Run the bootstrap above before switching onlyChanges to true. Keep product URLs, locale, source mode and snapshotName consistent between runs.
  2. Review Run report, SUMMARY.failedSources, sourcesNotReached, and sourceCoverage. Resolve source, time or spending failures first. Inspect hasMore and publicVariantLimitReached before calling the selected scope fully observed.
  3. Use JSON.stringify([storeUrl, variantId]) as your destination key. Upsert with Sheets "Append or Update Row" in n8n or a lookup/update branch in Make. Preserve locale roots, string IDs, exact decimal prices and nullable currency.
  4. After baseline, send new/changed rows to a merchant review queue. Use changeTypes for price and availability routing. Send price_changed_currency_unverified to manual review rather than calculating a cross-currency increase or discount.
Destination informationActor fields
Store/locale and variantstoreUrl, variantId
Producttitle, variantTitle, productUrl
Exact moneyprice, compareAtPrice, currency
Public purchasabilityavailable
Revision evidencecomparisonStatus, changeTypes, previous, observedAt

Keep the meaning: available is public storefront purchasability, not stock quantity or checkout success. The public endpoint has a 250-variant boundary. Keep decimal price strings as supplied; do not divide them by 100 again. Unknown currency stays null.

Empty or interrupted runs: A healthy change-only repeat may save zero rows. Keep existing variants; missing observations never mean deletion or stockout. History can advance for saved rows even when a later source fails, so replay the original dataset after delivery trouble.

Reliable delivery: Read the completed run's own SUMMARY and paginated dataset. Retain its run ID; if destination delivery fails, replay that dataset and deduplicate by run ID plus row key. Keep destination writes sequential, and write source text literally.

Validation: Inputs and mappings were checked locally against this Actor. The exact customer connection has not been run end to end. Choose recurrence after a manual bootstrap; this guide creates no schedule. See the run API, pagination guide, and the full Actor guide below for detailed setup and limits.

Full guide

Build a repeatable feed of public Shopify variant prices and availability for merchandising research, competitor comparisons, and saved-observation alerts. No API key or merchant credentials are required. Empty input {} inspects five products from Death Wish Coffee; it is a bounded sample.

What each row contains

One variant observation: stable string productId and variantId, product and variant titles, public product URL, vendor/product type, source SKU/barcode, option names and values, price, compareAtPrice, currency, explicit boolean available, observation time and optional comparison details. A barcode is raw source text, not a validated GTIN.

Prices are exact decimal strings derived from Shopify Ajax integer hundredths, without floating-point arithmetic. Shopify uses this representation even for currencies such as JPY. Currency is emitted only when the same product's public HTML explicitly declares one unambiguous Shopify.currency.active; otherwise it is null. Price increases/decreases are classified only when both observations have the same verified currency; otherwise a price edit is price_changed_currency_unverified.

available means the storefront reports the variant as purchasable. Stock quantity is not available and is not inferred. A product may have up to 250 variants exposed by Shopify Ajax; publicVariantLimitReached flags this boundary. Headless/custom stores lacking /products.json or /products/handle.js, password pages and robots-disallowed paths are unsupported. Product URL mode needs only the product endpoint, not the catalog endpoint.

Inputs

  • stores: up to 10 store homepage or locale-root URLs.
  • productUrls: up to 100 /products/handle HTML URLs. Both arrays can be used; overlapping saved variants are deduplicated by store origin, locale prefix and variant ID. Different locale roots retain separate observations and history.
  • maxProductsPerStore: 5 by default, up to 1,000. maxPagesPerStore: 10 by default, up to 40.
  • maxResults: 100 saved variants by default, up to 10,000.
  • comparePrevious, onlyChanges, snapshotName, maxRunSeconds: described below.

Currency HTML failure does not invent a currency: the variant remains usable with null currency, and currencyUnavailableProducts records the limitation. Catalog shape/identity failures are source failures.

Three example inputs

Death Wish Coffee - Variant Price Sample

Inspect five public catalog products with exact price strings and availability, capped at 25 variant rows.

Use the copyable first-run input above.

Klean Kanteen Mug - Public Variant Snapshot

Get variants for one exact public product URL, without scanning a store catalog.

{
"productUrls": [
"https://www.deathwishcoffee.com/products/klean-kanteen-camp-mug"
],
"maxResults": 20
}

Coffee Merchandise - Price & Availability History

Compare two products with their last saved observations. The first run establishes a baseline; later runs still emit unchanged variants.

{
"productUrls": [
"https://www.deathwishcoffee.com/products/klean-kanteen-camp-mug",
"https://www.deathwishcoffee.com/products/white-chocolate-pistachio-klean-kanteen-20oz"
],
"comparePrevious": true,
"snapshotName": "coffee-merchandise",
"maxResults": 30
}

Saved observations and change detection

comparePrevious: true enables persistent, named comparison history. onlyChanges: true also enables comparison and suppresses unchanged rows. The first observation emits comparisonStatus: "baseline"; later rows are new, changed, or unchanged. Without comparison they are not_requested. changedFields, changeTypes and previous explain each comparison.

Only confirmed saved rows update history. Existing records outside the selected window are retained. A partial run never establishes removals, and neither Actor emits deletion events. Comparison means last successfully saved observation, not an uninterrupted history of every change between runs. The state limit is 50,000 identities per source and snapshot name.

Run a given snapshot name sequentially. A reread detects an already changed snapshot before writing and reports a conflict, but this is not a transactional lock. Dataset and history writes are separate: a storage failure can leave saved rows without a new baseline; retrying may repeat observations. Use distinct names for independent workflows.

Coverage, limits and failures

maxResults caps saved rows across sources. Source/product/page limits select a bounded sample and are reported through SUMMARY.sourceCoverage, including hasMore; reaching a selected cap is not itself an operational failure. Always inspect SUMMARY before interpreting an empty or partial dataset. The output tab links to both results and SUMMARY.

Requests honor robots.txt, reject nonpublic network destinations and unsafe redirects, and stay within maxRunSeconds (default 240, range 30–3600) and 25 seconds before the platform deadline. HTTP 429, server errors and transient connection failures receive at most two bounded retries, honoring Retry-After. No browser rendering, login, proxy or anti-bot bypass is used.

Failures appear in failedSources, never as data rows. If all sources fail before usable output, the run fails. Genuine empty results or no changes produce a warning and succeed. Spending limits stop output cleanly, preserve existing rows, and prevent unsaved observations from advancing history. A source outage, robots restriction or time limit can produce partial coverage.

Development

Node 20 Docker image; exact Apify SDK 3.7.2 and Cheerio 1.1.2 lockfile. npm ci installs dependencies and npm test runs offline regression tests. npm start reads the normal Apify INPUT record. Public storefronts may change independently of this Actor.

Pricing

Planned pay-per-result rate: $1.50 per 1,000 saved variant observations, plus the configured Actor-start event. The current Apify pricing tab is authoritative. An unchanged row is billable when saved; onlyChanges avoids saving unchanged rows. Errors are not dataset results.

Source documentation

Shopify Ajax API · Product endpoint · Shopify price representation

Help with your run

Open the Issues tab on this Actor with the run URL, the input field that caused trouble and what you expected to receive. Remove API keys and private information before posting.

Explore more Mayd-It Actors

Understand your run

Open Run report in the run’s Output tab for saved-record counts, reported source issues and limits, and suggested next steps. Use CSV export to take the saved results into a spreadsheet. The existing JSON results and detailed machine-readable summary remain available.

The report reflects this run’s recorded coverage. A successful run or a saved result does not establish that every possible source record was collected.