Shopify Price & Restock Monitor avatar

Shopify Price & Restock Monitor

Under maintenance

Pricing

$3.00 / 1,000 product checkeds

Go to Apify Store
Shopify Price & Restock Monitor

Shopify Price & Restock Monitor

Under maintenance

Monitor a Shopify product shortlist. Export variant-level prices, availability and before/after changes. Public available is not warehouse inventory.

Pricing

$3.00 / 1,000 product checkeds

Rating

0.0

(0)

Developer

Atlas

Atlas

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Check a shortlist of public Shopify product URLs and get variant-level prices and availability, plus before/after changes on repeated runs. No Shopify installation, admin credentials or browser is required.

Restock means a public available: false → true observation. It does not reveal inventory quantities, warehouse stock or sales. This is a polling tool; changes between checks can be missed.

Start with one competitor product

1. Create your first price check

  1. Open this Actor in Apify Store, click Try for free, and sign in. Account credits may cover your trial; successful checks use the price shown in the Pricing tab.
  2. In Input, paste a public Shopify product page into Product URLs. Start with one URL, not a store homepage or collection. You can try https://www.allbirds.com/products/mens-tree-runners and then replace it with your competitor's product.
  3. Enter Watch ID my-competitors. Keep this exact ID on future checks of this list. Leave Mode at Compare with last successful check and leave the other fields at their defaults.
  4. Under Run options, select Build: latest and set Maximum cost per run to $0.01 for this one-product test. Click Start or Save & start.
  5. Once finished, open Output → Monitoring report. Read the OK / incomplete / skipped counts first. The report lists every requested product and links to changes CSV/JSON. Choose Current product options for option-level prices and availability. Several size/color rows still count as one product check.

You can also paste this into the JSON input editor:

{
"productUrls": ["https://www.allbirds.com/products/mens-tree-runners"],
"watchId": "my-competitors",
"mode": "monitor"
}

Expected first result: status: ok, isBaseline: true, and no changes. The first run saves today's prices and availability for the next comparison. The example returned seven USD options in testing on September 30, 2026; its price, options and accessibility can change.

2. Check the same product every day

  1. Return to the Actor's Input and click Save as a new task. Name it Competitor daily check and keep the option to copy your input selected.
  2. Open the Task's Input. Confirm the same product URL, Watch ID my-competitors, and monitor mode. Check its Run options, including Build: latest and the maximum cost. Click Save if you changed anything.
  3. Click Start on the Task once. A successful run with isBaseline: false confirms it is comparing against your first check. No change is normal when the store has not changed.
  4. In the left menu, open Schedules → Create new. Under Schedule setup, select daily at 09:00 in your own time zone (for example, Asia/Seoul). If using cron, 0 9 * * * means daily at 09:00 in the selected zone.
  5. Use Add → Task and select Competitor daily check. Leave input overrides empty so it uses the Task's saved input. Enable exclusive execution if offered, check Next runs, then click Enable when ready.

Keep only one schedule for this watch and avoid starting another run while it is running. To stop future checks, open that schedule and click Disable. Disabling does not abort an already running check.

3. Read changes and spot failed checks

Open your Task's Runs, choose the latest finished run, and open Output → Monitoring report first. It lists every requested product, including unprocessed URLs and the reason (for example budget_limit). The platform label Succeeded means the process finished; the report tells you whether every product was checked.

What you needWhere to lookWhat it means
Current prices and availabilityOutput tableavailable: true means publicly available to buy; it is not a stock quantity.
Price drops and restocksMonitoring report → Download changes CSV or Changes JSONJSON list or spreadsheet-ready rows with before/after values. Output links may also appear as Changes JSON and Changes CSV.
Whether all products were checkedMonitoring report → Summary JSONstatus: complete, ok: 1, processedProducts: 1 confirms this one-product example completed.

CHANGES: [] is expected on the first run or when nothing changed. Check SUMMARY before treating an empty list as “no changes”: a partial or failed check can also produce an empty list. Each run has its own files; open the latest run rather than yesterday's download link.

Change labels are price_drop, price_increase, discount_changed, became_available (restock), and became_unavailable (sold out). The Actor provides files; email, Slack and Sheets delivery require a separate integration.

What will it cost?

At the current launch price of $0.003 per successful product check, daily checks for 30 days cost:

ProductsProduct-check fees for 30 days
1$0.09
10$0.90
100$9.00

These examples assume one successful check per product per day. The first setup run and extra manual checks are additional. Options and changes do not add event fees. Failed, partial and duplicate products have no product-check fee. Platform usage is included in the current Actor price; check Pricing for current terms. Your account plan and retained storage can have separate charges.

Maximum cost per run is not a monthly budget. A $0.01 event budget covers up to three successful checks at this rate. Raise it when expanding your list (100 products need at least $0.30); if too low, SUMMARY reports skipped products or a budget stop. Disable the schedule to stop future runs.

If your first check does not work

ResultNext step
not_foundOpen the product in your browser and copy its current product URL.
blocked or unsupportedThe store may block automated access, require a queue/CAPTCHA, or redirect to another domain. Use its final product hostname if it is a normal Shopify product page; access barriers are not bypassed.
partialInspect warningCode and SUMMARY. The price/currency or options were incomplete; no change comparison was made and the previous good baseline was preserved.
Every run says isBaseline: trueKeep the same Watch ID, account and monitor mode. A different currency, product identity or locale can also reset the baseline.
Run is Succeeded but SUMMARY is partialSome products could not be checked. Inspect their status rows before relying on the result.

Report a failing public URL through the Store Issues tab, with the run ID and warning code. Exclude credentials and private URLs.

Input options

Use mode: "snapshot" for current state only; no baseline is read or written. Up to 500 URL strings are accepted. Locale paths and variant selections are retained; tracking parameters are discarded. Set Options to monitor → Selected options only (variantScope: "selected") to return and compare only the option IDs in your URLs. Products without an option ID still include all options. Missing selected options produce a free partial check, with the previous baseline preserved. The same canonical product is fetched and billed once, even when multiple variants are selected. The default variantScope: "all" retains the previous behavior: all options are returned and compared. The baseline always stores the full product, and billing remains per successful product.

Optional minPriceChangePct filters price drop/increase events only; discount events are unaffected. changeTypes selects price_drop, price_increase, discount_changed, became_available, and became_unavailable. Filtering never changes billing or baseline updates. Price thresholds compare the immediately previous successful observation, not an accumulated change.

Results

  • Default Dataset: one row per valid returned variant; failed products have one status row. First runs and unchanged runs also return current data.
  • CHANGES: JSON change list. Empty array means no reported changes.
  • CHANGES.csv: one row per change, or headers only. Text is escaped to limit spreadsheet formula injection.
  • REPORT.html: readable product coverage, baseline explanation, changes and downloads; selected by default in Output.
  • SUMMARY: processed/skipped counts, status, baseline updates, change count, billing counts and a products list including skipped URLs/reasons. Platform cost is null until measured on Apify.

The Output tab links to these records. Multiple fields changing produces multiple events. eventId identifies a specific before/after observation; deduplicate on it downstream. Times are observation times, not actual change times. An error never becomes a sold-out event.

Synthetic change example:

{
"changeType": "price_drop",
"currency": "USD",
"previousPrice": "30.00",
"currentPrice": "24.00",
"changePct": -20,
"previousObservedAt": "2026-09-29T00:00:00Z",
"observedAt": "2026-09-30T00:00:00Z"
}

Full events also contain product/variant IDs, selected watch/run, compare-at values, availability and discount percentages. Prices are decimal strings; IDs are strings. rawPrice, rawCompareAtPrice and priceConversion preserve the Ajax source and /100 conversion rule. SKU does not replace variant ID.

Support and history

Only public Shopify Ajax product endpoints are supported. Collections, store-wide discovery, headless stores without Ajax endpoints, CAPTCHA bypass, proxies, discount codes, selling-plan prices and private stores are outside this version.

Currency is checked through cart.js before and after the product request in the same cookie session. Missing/unstable currency or malformed options produce a free partial result, suppress all change events and preserve the last successful baseline. This version accepts recognized currencies with 0 or 2 ISO fractional digits; 3-digit currencies are conservatively partial. The Ajax /100 representation also applies to supported zero-decimal currencies.

Observable context is the final product URL/locale and currency. Changes of this context or product ID create a new baseline. Geo/market rules sharing the same currency cannot always be detected; use consistent execution location for a watch. Redirects to another origin are reported as unsupported, so use the store's final canonical hostname. Responses with 250 options carry a coverage warning; Shopify can truncate larger products. Missing/new option IDs do not create deletion/restock events.

Baselines live in your named Key-value store shopify-watch-<hash(actor + watch)>, one last successful record per canonical product. Past run outputs follow your storage retention policy; named storage can incur storage charges. To reset a watch, use a new watch ID or delete only its named store after ensuring no run is active. Removing a URL does not delete its existing baseline.

Use exclusive schedules. Local watch locking uses exclusive file creation; a crashed process can leave a lock under storage/watch-locks/, removable only after confirming no process is running. Cloud locking uses one pending Request queue item per watch with a renewable lease. Cloud lock contention has been tested in the developer account; expired-lease and migration recovery remain experimental. Avoid overlapping runs for the same watch.

Results are saved before charging. The default KVS contains a run manifest and per-product ENTRY-* recovery records; Dataset rowId prevents duplicate rows on resume. If a charge may have happened but its response was not durably recorded, the run reports billing_unknown, does not retry that charge and does not advance that product's baseline. Review the platform ledger rather than blindly retrying billing. Storage and billing are not one transaction.

Pricing

The launch price is $0.003 per successful product check, including first checks and unchanged checks, with platform usage included. Multiple options, changes and output rows incur no extra event fee. Duplicate URLs, blocked/not-found/unsupported/error and partial products are free. Check the Store Pricing tab for the active configuration before running.

100 products daily for 30 days produce $9 in product-check fees at this rate. Maximum run cost is not a monthly cap. Set a small maximum run cost for your first test. The Actor stops before processing the next product when its event budget is exhausted.

This is an early release. On September 30, 2026, two runs of a 100-product sample across eight stores each checked 99 products; one Gymshark URL redirected to a queue and was unsupported. Independently fetched data matched 407 options. This sample does not guarantee support for every Shopify store.

Send alerts with n8n

  1. Finish one Actor run and open Monitoring report → Download n8n alert workflow. Import the JSON into n8n (workflow menu → Import from File). It is inactive and starts manually.
  2. In Configuration, replace REPLACE_WITH_FINISHED_RUN_ID with your finished run ID and notificationUrl with your own HTTP webhook. Keep apiBase at https://api.apify.com/v2.
  3. Create an n8n Header Auth credential: name Authorization, value Bearer YOUR_APIFY_TOKEN. Select it on Get run, Get summary, and Get changes. Never paste a token into Configuration or exported workflow JSON. Add your receiver's authentication to Send notification if required.
  4. Click Execute workflow. The workflow checks that the run finished successfully, reads that run's SUMMARY and CHANGES, and sends a JSON notification for changes or incomplete checks. A complete run with zero changes sends nothing. A failed/unfinished run stops with an error; use n8n's error workflow for operational alerts.
  5. The receiver gets text, kind, runId, watchId, eventIds, changes and incompleteProducts. A webhook accepting a JSON text field can display the summary; use a field-mapping node for other receiver formats. Deduplicate eventIds at your receiver if retrying or replaying runs; this example does not provide exactly-once delivery across workflow executions.

After testing manually, replace Manual run → Configuration with the Apify Actor Run Finished trigger and map its run ID into Configuration. For Saved Tasks use Actor Task Run Finished. Filter to this Actor/Task, keep API and receiver credentials in n8n, then activate. Match the actual trigger payload in your n8n version; do not leave the example run ID fixed in an automatic workflow. Use exclusive Actor schedules.

The example was tested in the real n8n engine with a controlled cloud change event and a local HTTP receiver, including incomplete-check warnings and no-change suppression. This is not proof of a naturally occurring restock or delivery to Slack/email. The Actor itself sends no messages.

For independent lists, leave Watch ID blank in a Saved Task to use its unique Task ID. Manual/API monitor runs still need an explicit ID. When copying a Task that has an explicit Watch ID, clear it or assign a new one; preserving it shares the same baseline. Filtering compares the immediately previous successful observation. For example, minPriceChangePct: 5 with changeTypes: ["price_drop", "discount_changed"] can still report a discount change when the price drops less than 5%.

References