ECOMMERCEAI

E-Commerce Price Monitor

Track product prices across Shopify stores and any e-commerce website with structured data. This actor automatically detects Shopify stores and uses their product API for bulk extraction, while falling back to JSON-LD, Open Graph, and meta tag parsing for all other e-commerce sites. Price history is stored between runs so you can detect price drops, sales, and competitor pricing shifts over time.

Try on Apify Store
$0.05per event
1
Users (30d)
30
Runs (30d)
90
Actively maintained
Maintenance Pulse
$0.05
Per event

Maintenance Pulse

90/100
Last Build
Today
Last Version
1d ago
Builds (30d)
8
Issue Response
N/A

Cost Estimate

How many results do you need?

product-monitoreds
Estimated cost:$5.00

Pricing

Pay Per Event model. You only pay for what you use.

EventDescriptionPrice
product-monitoredCharged per product price monitored. Uses multi-strategy extraction, maintains price history, detects price changes with direction and magnitude.$0.05

Example: 100 events = $5.00 · 1,000 events = $50.00

Documentation

Track product prices across Shopify stores and any e-commerce website with structured data. This actor automatically detects Shopify stores and uses their product API for bulk extraction, while falling back to JSON-LD, Open Graph, and meta tag parsing for all other e-commerce sites. Price history is stored between runs so you can detect price drops, sales, and competitor pricing shifts over time.

Why Use This Actor?

Manually checking competitor prices is tedious and error-prone. This actor automates price monitoring across two distinct modes:

  • Shopify stores — Fetches up to 10,000 products in bulk via the /products.json API endpoint, including all variants, SKUs, compare-at prices, and availability status. No HTML parsing needed.
  • Any other e-commerce site — Uses a four-layer extraction strategy (JSON-LD → Open Graph → product meta tags → regex) to find prices on any product page that embeds structured data.
  • Price history across runs — Stores the last 30 price points per product in Apify's Key-Value Store, automatically computing direction (up/down/unchanged/new), dollar change, and percentage change.

Whether you're a dropshipper tracking supplier margins, a brand owner enforcing MAP pricing, or a market researcher building pricing benchmarks, this actor handles the data collection so you can focus on decisions.

Features

  • Shopify bulk extraction — Automatically detects Shopify stores and paginates through the /products.json API endpoint (250 products per page), including all variants, SKUs, compare-at prices, and inventory availability
  • Universal e-commerce support — Extracts prices from any product page using a four-layer strategy: JSON-LD structured data, Open Graph meta tags, product meta tags, and regex pattern matching
  • Price change tracking — Stores price history in the Key-Value Store across multiple runs, reporting direction (up/down/unchanged/new), absolute change, and percentage change for every product
  • Variant-level detail — Captures individual product variants with separate prices, SKUs, and stock status for stores that sell products in multiple sizes, colors, or configurations
  • Sale detection — Reports both the current selling price and the original compare-at price on Shopify stores, making it easy to identify active discounts and promotional pricing
  • Flexible output — Download results as JSON, CSV, Excel, or HTML table with product names, prices, availability, brands, categories, and images

How to Use

  1. Click Try for free on this page
  2. Enter one or more product URLs or Shopify store URLs in the Product URLs field
  3. Optionally toggle Track Price History to track changes between runs
  4. Click Start and wait for the run to finish
  5. Download your results from the Dataset tab in JSON, CSV, or Excel format

For Shopify stores, provide the store root URL (e.g., https://store.myshopify.com). The actor will automatically fetch all products. For other e-commerce sites, provide the direct URL of each product page you want to monitor.

To track price changes over time, schedule the actor to run daily or weekly. The actor stores price history in the Key-Value Store and reports changes automatically on each subsequent run.

Input Parameters

ParameterTypeRequiredDescription
productUrlsstring[]YesProduct page URLs or Shopify store root URLs to monitor (e.g., https://store.myshopify.com or https://example.com/products/widget)
checkShopifyApibooleanNoTry the Shopify /products.json API endpoint first. Disable to force generic HTML scraping only. Default: true
trackPriceHistorybooleanNoStore price history in the Key-Value Store so price changes are detected between runs. Default: true
notifyOnChangebooleanNoLog price changes prominently in the actor run log when detected. Default: false
currencystringNoExpected currency code for display when the site does not specify one (e.g., USD, EUR, GBP). Default: USD
maxProductsintegerNoMaximum number of products to extract per store URL. Useful for large Shopify stores. Range: 1–10,000. Default: 100

Input Examples

Monitor a Shopify store (all products):

{
    "productUrls": ["https://store.myshopify.com"],
    "checkShopifyApi": true,
    "trackPriceHistory": true,
    "maxProducts": 500
}

Track specific product pages with change alerts:

{
    "productUrls": [
        "https://example.com/products/wireless-earbuds",
        "https://another-store.com/products/laptop-stand"
    ],
    "trackPriceHistory": true,
    "notifyOnChange": true,
    "currency": "USD"
}

One-time price snapshot (no history tracking):

{
    "productUrls": ["https://store.myshopify.com"],
    "checkShopifyApi": true,
    "trackPriceHistory": false,
    "maxProducts": 50
}

Tips for Input

  • Shopify stores: Provide the store root URL (e.g., https://store.myshopify.com). The actor auto-detects Shopify via the URL and fetches all products via API.
  • Other e-commerce sites: Provide the direct product page URL where the price is displayed. Category or search result pages will not produce useful data.
  • Mixed inputs: You can mix Shopify store URLs and individual product page URLs from different sites in a single run. The actor processes each URL independently.
  • Large stores: Set maxProducts to limit extraction from stores with thousands of products. Start with 10–50 when testing.

Output Example

Each product in the dataset includes the following fields:

{
    "url": "https://allbirds.com/products/mens-tree-runners",
    "source": "shopify",
    "storeDomain": "allbirds.com",
    "productName": "Men's Tree Runners",
    "description": "Our lightweight, breezy sneaker made with responsibly sourced eucalyptus tree fiber for everyday wear.",
    "currentPrice": 98,
    "compareAtPrice": 110,
    "currency": "USD",
    "available": true,
    "sku": "TR-M-NBLK-8",
    "brand": "Allbirds",
    "category": "Shoes",
    "imageUrl": "https://cdn.shopify.com/s/files/1/0076/1045/products/tree-runners-black.jpg",
    "variants": [
        {
            "title": "8 / Natural Black",
            "price": 98,
            "sku": "TR-M-NBLK-8",
            "available": true
        },
        {
            "title": "9 / Natural Black",
            "price": 98,
            "sku": "TR-M-NBLK-9",
            "available": true
        },
        {
            "title": "10 / Natural Black",
            "price": 98,
            "sku": "TR-M-NBLK-10",
            "available": false
        }
    ],
    "priceChange": {
        "previousPrice": 110,
        "changeAmount": -12,
        "changePercent": -10.91,
        "direction": "down",
        "lastChecked": "2025-12-01T08:30:00.000Z"
    },
    "scrapedAt": "2025-12-08T14:22:33.000Z",
    "tags": ["mens", "tree-runners", "shoes", "best-sellers"]
}

Output Fields

FieldTypeDescription
urlstringProduct page URL (constructed from handle for Shopify products)
sourcestringExtraction method used: shopify, json-ld, opengraph, meta, or regex
storeDomainstringHostname of the store (e.g., allbirds.com)
productNamestringProduct title extracted from the store
descriptionstring|nullProduct description (HTML stripped, max 1,000 chars)
currentPricenumber|nullCurrent selling price as a number
compareAtPricenumber|nullOriginal/compare-at price (Shopify only — indicates a sale)
currencystringCurrency code (from site data or input fallback)
availablebooleanWhether the product is currently in stock
skustring|nullProduct SKU (from first variant on Shopify, from JSON-LD on other sites)
brandstring|nullBrand or vendor name
categorystring|nullProduct type or category
imageUrlstring|nullPrimary product image URL
variantsarray|nullProduct variants (included when >1 variant exists) — each has title, price, sku, available
priceChangeobject|nullPrice change data (populated when history tracking is enabled)
priceChange.previousPricenumber|nullPrice from the last run (null for new products)
priceChange.changeAmountnumber|nullAbsolute price change in currency units
priceChange.changePercentnumber|nullPercentage change (positive = increase, negative = decrease)
priceChange.directionstring"up", "down", "unchanged", or "new"
priceChange.lastCheckedstring|nullISO timestamp of the previous run
scrapedAtstringISO timestamp of when this data was collected
tagsstring[]Product tags (Shopify stores only, empty array for other sites)

Use Cases

  • E-commerce managers: Monitor competitor product pages daily to detect price changes and adjust your own pricing strategy in response
  • Dropshippers: Track wholesale supplier prices on Shopify stores to calculate real-time margins and spot new deals as they appear
  • Market researchers: Collect pricing data across an entire product category to build competitive landscape reports and pricing benchmarks
  • Deal hunters and affiliates: Watch product pages for price drops and trigger notifications when items go on sale
  • Brand owners: Verify that authorized retailers are listing your products at the correct MAP (Minimum Advertised Price)
  • Data analysts: Build historical pricing datasets for trend analysis, seasonal pattern detection, and demand forecasting models

API & Programmatic Access

Python

from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("ryanclinton/ecommerce-price-monitor").call(run_input={
    "productUrls": ["https://store.myshopify.com"],
    "checkShopifyApi": True,
    "trackPriceHistory": True,
    "notifyOnChange": True,
    "maxProducts": 200,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    name = item.get("productName", "Unknown")
    price = item.get("currentPrice")
    change = item.get("priceChange", {})
    direction = change.get("direction", "new") if change else "new"
    pct = change.get("changePercent", 0) if change else 0
    print(f"{name}: ${price} ({direction} {pct:+.1f}%)")

JavaScript

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('ryanclinton/ecommerce-price-monitor').call({
    productUrls: ['https://store.myshopify.com'],
    checkShopifyApi: true,
    trackPriceHistory: true,
    notifyOnChange: true,
    maxProducts: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
    const dir = item.priceChange?.direction ?? 'new';
    const pct = item.priceChange?.changePercent ?? 0;
    console.log(`${item.productName}: $${item.currentPrice} (${dir} ${pct > 0 ? '+' : ''}${pct}%)`);
}

cURL

# Start the actor
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~ecommerce-price-monitor/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "productUrls": ["https://store.myshopify.com"],
    "checkShopifyApi": true,
    "trackPriceHistory": true,
    "maxProducts": 200
  }'

# Fetch results (use defaultDatasetId from the response above)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"

How It Works — Technical Details

Input: productUrls[]
  │
  ▼
For each URL ─────────────────────────────────────────────────
  │                                                           │
  ├─ checkShopifyApi = true?                                  │
  │   │                                                       │
  │   ▼                                                       │
  │  ┌─────────────────────────────────────┐                  │
  │  │ SHOPIFY MODE                        │                  │
  │  │                                     │                  │
  │  │ 1. Try /products.json?limit=250     │                  │
  │  │ 2. Paginate (?page=1,2,3...)        │                  │
  │  │ 3. Stop when:                       │                  │
  │  │    - products >= maxProducts         │                  │
  │  │    - empty page returned             │                  │
  │  │    - page < 250 items (last page)    │                  │
  │  │ 4. Map each ShopifyProduct:         │                  │
  │  │    - First variant → main price     │                  │
  │  │    - compare_at_price → sale price  │                  │
  │  │    - Any variant available? → stock │                  │
  │  │    - Build URL from handle          │                  │
  │  │    - Strip HTML from body_html      │                  │
  │  └────────────┬────────────────────────┘                  │
  │               │ Products found?                           │
  │               │                                           │
  │           Yes │    No                                     │
  │               │    │ ──── Fallback ────┐                  │
  │               │                       ▼                   │
  │               │    ┌──────────────────────────────────┐   │
  │               │    │ GENERIC MODE                     │   │
  │               │    │                                  │   │
  │               │    │ fetch HTML (30s timeout, 2       │   │
  │               │    │ retries, exponential backoff)    │   │
  │               │    │                                  │   │
  │               │    │ Strategy 1: JSON-LD              │   │
  │               │    │  <script type="ld+json">         │   │
  │               │    │  → @type: "Product"              │   │
  │               │    │  → offers.price / lowPrice       │   │
  │               │    │  → priceCurrency, availability   │   │
  │               │    │  → sku, brand, image             │   │
  │               │    │                                  │   │
  │               │    │ Strategy 2: Open Graph           │   │
  │               │    │  og:price:amount                 │   │
  │               │    │  product:price:amount            │   │
  │               │    │  og:price:currency               │   │
  │               │    │                                  │   │
  │               │    │ Strategy 3: Product Meta Tags    │   │
  │               │    │  product:price:amount            │   │
  │               │    │  product:price:currency          │   │
  │               │    │                                  │   │
  │               │    │ Strategy 4: Regex Fallback       │   │
  │               │    │  $X.XX / USD X.XX / price: $X.XX │   │
  │               │    │                                  │   │
  │               │    │ (first strategy that finds a     │   │
  │               │    │  price wins — cascading order)   │   │
  │               │    └──────────┬───────────────────────┘   │
  │               │               │                           │
  │               ▼               ▼                           │
  │         ┌─────────────────────────────────────┐           │
  │         │ PRICE HISTORY (per product)          │           │
  │         │                                     │           │
  │         │ Key = sanitized URL (max 200 chars)  │           │
  │         │                                     │           │
  │         │ New product:                        │           │
  │         │   direction = "new"                 │           │
  │         │   Save initial record to KV store    │           │
  │         │                                     │           │
  │         │ Existing product:                   │           │
  │         │   diff = current - previous         │           │
  │         │   |diff| > 0.001 → "up" or "down"  │           │
  │         │   else → "unchanged"                │           │
  │         │   changePercent = (diff/prev) × 100 │           │
  │         │   Append to history (max 30 entries) │           │
  │         │                                     │           │
  │         │ If notifyOnChange + changed:         │           │
  │         │   >>> PRICE UP: ... or              │           │
  │         │   <<< PRICE DOWN: ...               │           │
  │         └────────────┬────────────────────────┘           │
  │                      │                                    │
  │                      ▼                                    │
  │              Push to Dataset                              │
  │                                                           │
  └───────────────────────────────────────────────────────────┘

Four-Layer Extraction Strategy (Non-Shopify Sites)

The actor cascades through four extraction methods in order, stopping at the first one that finds a valid price:

StrategySourceFields ExtractedBest For
JSON-LD<script type="application/ld+json"> with @type: "Product"name, price, currency, availability, sku, brand, category, image, descriptionModern e-commerce sites (WooCommerce, BigCommerce, Magento)
Open Graphog:price:amount / product:price:amount meta tagstitle, price, currency, description, imageSites with social sharing metadata
Product Metaproduct:price:amount / product:price:currency meta tagstitle, price, currency, description, imageSites using product-specific meta tags
RegexPattern matching: $X.XX, USD X.XX, price: $X.XXprice only (title from <title> tag)Last resort for pages without structured data

Shopify API Pagination

The Shopify /products.json endpoint returns up to 250 products per page. The actor paginates automatically:

Page 1: /products.json?limit=250&page=1  → 250 products
Page 2: /products.json?limit=250&page=2  → 250 products
Page 3: /products.json?limit=250&page=3  → 137 products (< 250 = last page)
Total: 637 products (capped by maxProducts setting)

Price History Storage

Price history is stored in Apify's Key-Value Store using sanitized URL keys:

  • Key format: URL with protocol stripped, non-alphanumeric chars replaced with _, max 200 chars
  • Example: https://store.com/products/shoesstore.com_products_shoes
  • History limit: 30 entries per product (rolling window)
  • Change threshold: Price differences smaller than $0.001 are treated as "unchanged"
  • Persistence: Data persists between actor runs on the same Apify account

HTTP Fetch Details

  • User-Agent: Mozilla/5.0 (compatible; ApifyBot/1.0)
  • Timeout: 30 seconds per request
  • Retries: Up to 2 retries with exponential backoff (1s, 2s delays)
  • Shopify detection: URL contains myshopify.com or shopify

How Much Does It Cost?

This actor runs on the Apify platform with very low resource requirements. It uses minimal memory (256 MB) and completes quickly because it relies on API calls and lightweight HTML parsing rather than browser rendering.

ScenarioProductsEstimated TimeEstimated Cost
Single product page1~5 seconds< $0.001
Small Shopify store50 products~15 seconds~$0.005
Medium Shopify store250 products~30 seconds~$0.01
Large Shopify store1,000 products~2 minutes~$0.03
10 product pages10~30 seconds~$0.01

The Apify Free plan includes $5 of monthly credits, which is enough to monitor hundreds of products daily.

PlanMonthly CreditsApproximate Runs (100 products each)
Free$5~500 runs
Starter ($49/mo)$49~5,000 runs
Scale ($499/mo)$499~50,000 runs

Tips

  • Schedule daily runs to build price history. The actor tracks up to 30 historical price points per product, giving you a full month of daily snapshots.
  • Use Shopify store root URLs (e.g., https://store.myshopify.com) rather than individual product URLs to extract the entire catalog in a single run.
  • Enable "Notify on Price Change" when running via the Apify scheduler so price movements appear prominently in the run log and email notifications.
  • Start with a small maxProducts value (e.g., 10) when testing a new store to verify the data looks correct before scaling up.
  • For non-Shopify sites, ensure you provide the actual product page URL where the price is displayed. Category or search result pages will not produce useful data.
  • Combine with webhooks — Set up an Apify webhook to trigger a Slack or email notification whenever the actor finishes, so you can review price changes immediately.
  • Check the source field to understand how the price was extracted. json-ld and shopify sources are the most reliable; regex is a last resort.

Limitations

  • Shopify-specific features only via API — Compare-at prices, variants, SKUs, tags, and vendor names are only available when the Shopify /products.json endpoint is accessible. Stores that disable this endpoint fall back to generic scraping.
  • No JavaScript rendering — The generic scraper fetches raw HTML only. Sites that load prices dynamically via JavaScript (e.g., single-page apps, React-based stores) may not return price data.
  • Large marketplace sites — Amazon, eBay, Walmart, and similar marketplaces use aggressive anti-bot measures and dynamically loaded content. This actor is not designed for these sites.
  • Currency detection — If a site does not include currency in its structured data, the actor uses the currency input parameter as a fallback. It does not perform currency conversion.
  • Regex extraction accuracy — The regex fallback may match non-product prices (e.g., shipping costs, page element prices) on pages without structured data. Check results from source: "regex" carefully.
  • Sequential processing — URLs are processed one at a time. Large batches of individual product pages may take longer than expected.
  • No authentication — The actor cannot access products behind login walls, password-protected stores, or private Shopify storefronts.
  • Rate limits — Shopify stores may rate-limit the /products.json endpoint. The actor uses fetch retries with backoff but cannot bypass persistent rate limiting.

Responsible Use

This actor accesses only publicly visible product data that any website visitor can see. It does not bypass authentication, CAPTCHA, or access controls. When monitoring competitor prices:

  • Respect each site's robots.txt directives
  • Use reasonable scheduling intervals (daily is sufficient for most use cases)
  • Do not use collected pricing data to engage in predatory pricing or price-fixing
  • Comply with all applicable laws regarding competitive intelligence in your jurisdiction
  • See Apify's guide on web scraping legality for general guidance

FAQ

Q: What e-commerce platforms does this actor support? A: The actor has native Shopify support via the /products.json API. For all other platforms (WooCommerce, Magento, BigCommerce, custom stores), it extracts data from JSON-LD structured data, Open Graph tags, product meta tags, and price regex patterns. Any site that includes structured product data in its HTML will work.

Q: How does price history tracking work? A: When "Track Price History" is enabled, the actor stores the last known price for each product in the Apify Key-Value Store (keyed by sanitized URL). On subsequent runs, it compares the current price against the stored value and reports the direction, amount, and percentage of any change. Up to 30 historical price points are kept per product.

Q: Can I monitor products from multiple stores in a single run? A: Yes. Simply add multiple URLs to the "Product URLs" input field. You can mix Shopify store URLs and individual product page URLs from different sites. The actor processes each URL independently.

Q: Does this actor work with Amazon, eBay, or Walmart? A: These large marketplaces use aggressive anti-bot measures and dynamically loaded content. This actor is optimized for Shopify stores and standard e-commerce sites that include product data in their HTML or via JSON-LD. For Amazon scraping, consider dedicated Amazon scraper actors on the Apify Store.

Q: How often should I schedule runs to track prices? A: Daily runs work well for most use cases. For fast-moving markets or flash sales, you can schedule runs every few hours. The actor keeps up to 30 historical entries per product, so daily runs give you a full month of price history.

Q: What does the source field tell me? A: It indicates which extraction method was used: shopify (API endpoint), json-ld (structured data in HTML), opengraph (OG meta tags), meta (product meta tags), or regex (pattern matching). Shopify and JSON-LD are the most reliable and complete. Regex is the least reliable fallback.

Q: Why is compareAtPrice null for non-Shopify products? A: The compare-at price (original price before sale) is a Shopify-specific concept available via their product API. Most other e-commerce platforms do not expose this in their structured data. You can still detect sales by tracking currentPrice changes over time.

Q: Is it legal to scrape product prices from e-commerce websites? A: Product prices are publicly available information displayed to all website visitors. This actor accesses only publicly visible data and does not bypass any authentication or access controls. For guidance on your specific situation, consult legal counsel regarding local regulations. See Apify's guide on web scraping legality.

Q: What happens if a product page does not contain structured price data? A: The actor uses a four-layer extraction strategy. If JSON-LD is not found, it tries Open Graph tags, then product meta tags, and finally regex pattern matching for common price formats (e.g., $29.99). If none of these methods find a price, the product is skipped and a warning is logged.

Integrations

Connect this actor to your existing tools and workflows:

  • Zapier — Trigger actions in 5,000+ apps when prices change
  • Make — Build complex pricing automation workflows
  • Google Sheets — Export price data directly to spreadsheets for analysis
  • Slack — Get instant notifications when products drop in price
  • The Apify API — Programmatic access to results via REST API
  • Apify Webhooks — Trigger custom actions when a run finishes

Related Actors

ActorUse Case
ryanclinton/shopify-store-intelligenceDeep analysis of Shopify stores including technology stack, theme detection, and store metrics
ryanclinton/brand-protection-monitorMonitor unauthorized use of your brand across the web, including pricing violations
ryanclinton/website-change-monitorTrack changes on any web page, useful for detecting product listing updates beyond just price
ryanclinton/serp-rank-trackerTrack search engine rankings for product keywords alongside pricing data
ryanclinton/website-tech-stack-detectorIdentify the e-commerce platform powering any online store

How it works

01

Configure

Set your parameters in the Apify Console or pass them via API.

02

Run

Click Start, trigger via API, webhook, or set up a schedule.

03

Get results

Download as JSON, CSV, or Excel. Integrate with 1,000+ apps.

Use cases

Sales Teams

Build targeted lead lists with verified contact data.

Marketing

Research competitors and identify outreach opportunities.

Data Teams

Automate data collection pipelines with scheduled runs.

Developers

Integrate via REST API or use as an MCP tool in AI workflows.

Ready to try E-Commerce Price Monitor?

Start for free on Apify. No credit card required.

Open on Apify Store