Skip to main content
Thirdwatchthirdwatch
E-commerce & products

Automate Price Drop Alerts for Any E-Commerce Product (2026)

Set up automated price drop alerts for Amazon, Shopify, and any e-commerce product. Python pipeline with Slack and email notifications on price changes.

May 26, 2026 · 6 min read · 1,477 words
See the scraper →

Thirdwatch's Price Tracker provides the data layer for building automated price drop alerts on any e-commerce product. Monitor Amazon listings, Shopify stores, and any site with structured pricing data — get notified via Slack, email, or webhook when prices fall below your target. Built for developers building deal-alert services, ops teams watching procurement costs, and anyone who wants to buy at the right price without manual checking.

Why automate price drop alerts

Price drops on e-commerce are time-limited by design. According to Feedvisor's 2025 Amazon Pricing Report, the median duration of an Amazon price drop below historical average is 4.2 hours. Flash sales, lightning deals, pricing errors, and algorithmic undercuts all create windows that close before manual monitoring catches them. The gap between "price dropped" and "someone noticed" is where money is left on the table.

For procurement teams, a 10% drop on a bulk-purchased commodity saves thousands if caught within the buying window. For deal-alert services, detection speed is the product — your users pay for the alert, and a 6-hour-late alert is worthless. For personal shoppers, automation replaces the daily ritual of checking 15 product pages manually.

The architecture is a detection loop: scheduled price extraction, comparison against target or historical prices, conditional notification. The Price Tracker handles the extraction layer and this guide builds the detection and notification layers on top.

How does this compare to the alternatives?

Three approaches for price drop alerts:

Approach Coverage Alert speed Customization Ongoing effort
Browser extensions (Honey, Keepa, CamelCamelCamel) Amazon-only or single-site Varies (hourly to daily) Limited (preset thresholds) None
Consumer alert services (Google Shopping, Idealo) Major retailers Daily at best Minimal None
Thirdwatch Price Tracker + custom alert pipeline Amazon + Shopify + any structured-data site As fast as your schedule (minutes to hours) Full control (per-product thresholds, multi-channel alerts) Pipeline maintenance

Browser extensions work for personal use on a single site. Consumer services cover major retailers but with limited control. The Price Tracker actor page gives you cross-site coverage with full control over thresholds, alert channels, and detection logic.

How to automate price drop alerts in 5 steps

Step 1: How do I define products and target prices?

Create a watchlist with per-product alert thresholds. Each entry has a URL, a target price (alert when price drops below this), and an optional percentage threshold.

# watchlist.py
PRODUCTS = [
    {
        "url": "https://www.amazon.com/dp/B09V3KXJPB",
        "name": "Apple AirPods Pro 2",
        "target_price": 180.00,
        "pct_threshold": 5.0,   # alert on 5%+ drop from last check
    },
    {
        "url": "https://www.amazon.com/dp/B0BSHF7WHW",
        "name": "Samsung Galaxy S24 Ultra",
        "target_price": 1050.00,
        "pct_threshold": 3.0,
    },
    {
        "url": "https://gymshark.com/products/vital-seamless-leggings",
        "name": "Gymshark Vital Seamless Leggings",
        "target_price": 40.00,
        "pct_threshold": 10.0,
    },
    {
        "url": "https://www.allbirds.com/products/mens-tree-runners",
        "name": "Allbirds Tree Runners",
        "target_price": 85.00,
        "pct_threshold": 8.0,
    },
    {
        "url": "https://www.stanley1913.com/products/quencher-h2-0-flowstate-tumbler-40-oz",
        "name": "Stanley Quencher 40oz",
        "target_price": 35.00,
        "pct_threshold": 10.0,
    },
]

Step 2: How do I fetch current prices?

Run the Price Tracker against your watchlist URLs.

# fetch_prices.py
import os
from apify_client import ApifyClient
from watchlist import PRODUCTS

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("thirdwatch/price-tracker").call(run_input={
    "urls": [p["url"] for p in PRODUCTS],
    "maxRetries": 3,
    "proxyCountry": "US",
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
price_map = {item["url"]: item for item in items}
print(f"Fetched prices for {len(price_map)} products")

Step 3: How do I detect price drops against targets and history?

Compare current prices against both absolute targets and recent historical prices.

# detect.py
import json, pathlib, datetime

HISTORY_FILE = pathlib.Path("price_history.json")
history = json.loads(HISTORY_FILE.read_text()) if HISTORY_FILE.exists() else {}

alerts = []

for product in PRODUCTS:
    url = product["url"]
    if url not in price_map:
        continue

    current = price_map[url]
    if not current.get("success") or current.get("price") is None:
        continue

    price = current["price"]
    currency = current["currency"]

    # Alert type 1: price below absolute target
    if price <= product["target_price"]:
        alerts.append({
            "type": "target_hit",
            "product": product["name"],
            "price": price,
            "currency": currency,
            "target": product["target_price"],
            "url": url,
            "availability": current["availability"],
        })

    # Alert type 2: percentage drop from last known price
    if url in history and history[url]["price"]:
        prev_price = history[url]["price"]
        pct_change = ((price - prev_price) / prev_price) * 100
        if pct_change <= -product["pct_threshold"]:
            alerts.append({
                "type": "pct_drop",
                "product": product["name"],
                "price": price,
                "currency": currency,
                "prev_price": prev_price,
                "pct_change": round(pct_change, 1),
                "url": url,
                "availability": current["availability"],
            })

    # Update history
    history[url] = {
        "price": price,
        "currency": currency,
        "availability": current["availability"],
        "checked_at": datetime.datetime.utcnow().isoformat(),
    }

HISTORY_FILE.write_text(json.dumps(history, indent=2))
print(f"Detected {len(alerts)} price alerts")

The two-tier detection catches both absolute bargains (price under your target) and relative drops (sudden decreases from last check). A product at your target price is a buy signal regardless of trend, while a 15% overnight drop on a product above your target is worth knowing about.

Step 4: How do I send Slack and email notifications?

Route alerts to the appropriate channel based on severity.

# notify.py
import requests, smtplib
from email.mime.text import MIMEText

SLACK_WEBHOOK = "https://hooks.slack.com/services/.../..."
EMAIL_TO = "alerts@yourcompany.com"
SMTP_SERVER = "smtp.gmail.com"
SMTP_USER = "alerts@yourcompany.com"
SMTP_PASS = "your_app_password"

for alert in alerts:
    if alert["type"] == "target_hit":
        msg = (f"TARGET HIT: *{alert['product']}* is now "
               f"{alert['currency']} {alert['price']} "
               f"(target: {alert['currency']} {alert['target']})\n"
               f"Availability: {alert['availability']}\n{alert['url']}")
    else:
        msg = (f"PRICE DROP: *{alert['product']}* dropped {abs(alert['pct_change'])}%\n"
               f"{alert['currency']} {alert['prev_price']} -> {alert['price']}\n"
               f"Availability: {alert['availability']}\n{alert['url']}")

    # Slack notification
    requests.post(SLACK_WEBHOOK, json={"text": msg}, timeout=10)

    # Email for target hits (high priority)
    if alert["type"] == "target_hit":
        email = MIMEText(msg.replace("*", ""))
        email["Subject"] = f"Price Alert: {alert['product']} hit target price"
        email["From"] = SMTP_USER
        email["To"] = EMAIL_TO
        with smtplib.SMTP_SSL(SMTP_SERVER, 465) as server:
            server.login(SMTP_USER, SMTP_PASS)
            server.send_message(email)

print(f"Sent {len(alerts)} notifications")

Target hits go to both Slack and email (high priority — someone should consider buying). Percentage drops go to Slack only (informational — monitor but not necessarily act). Adjust routing based on your workflow.

Step 5: How do I schedule the full alert pipeline?

Wire everything into a single script and schedule it.

# alert_pipeline.py
"""
Run via cron: 0 */6 * * *  (every 6 hours)
Or schedule the actor on Apify and use a webhook to trigger this script.
"""
import subprocess, sys

# Fetch fresh prices
subprocess.run([sys.executable, "fetch_prices.py"], check=True)

# Detect price drops
subprocess.run([sys.executable, "detect.py"], check=True)

# Send notifications (only runs if alerts exist)
subprocess.run([sys.executable, "notify.py"], check=True)

For a fully serverless setup, schedule the actor on Apify's scheduler and configure an Apify webhook to POST results to your notification endpoint.

Sample output

The actor returns one record per product URL. Three records weigh approximately 1 KB.

[
  {
    "url": "https://www.amazon.com/dp/B09V3KXJPB",
    "productName": "Apple AirPods Pro (2nd Generation)",
    "price": 169.99,
    "currency": "USD",
    "availability": "In Stock",
    "brand": "Apple",
    "rating": 4.7,
    "platform": "amazon",
    "success": true
  },
  {
    "url": "https://gymshark.com/products/vital-seamless-leggings",
    "productName": "Vital Seamless 2.0 Leggings",
    "price": 38.00,
    "currency": "USD",
    "availability": "In Stock",
    "brand": "Gymshark",
    "rating": 4.5,
    "platform": "shopify",
    "success": true
  },
  {
    "url": "https://www.stanley1913.com/products/quencher-h2-0-flowstate-tumbler-40-oz",
    "productName": "Quencher H2.0 FlowState Tumbler 40 oz",
    "price": 45.00,
    "currency": "USD",
    "availability": "Out of Stock",
    "brand": "Stanley",
    "rating": 4.8,
    "platform": "shopify",
    "success": true
  }
]

Notice the availability field on the Stanley Quencher — "Out of Stock" means the price is visible but the product cannot be purchased. Fields use camelCase (productName, originalPrice, imageUrl) consistent with the actor's JSON-LD extraction approach. Your alert logic should flag this: a price drop on an out-of-stock item is not actionable for buying, but it may indicate an upcoming restock at a lower price point.

Common pitfalls

Four things go wrong in production price-alert pipelines. According to Deloitte's 2025 retail pricing study, major e-commerce platforms adjust prices an average of 2-3 times per day per SKU. Alert fatigue from micro-fluctuations — without meaningful thresholds, you get notified every time Amazon's algorithm tweaks a price by 0.3%. Set minimum thresholds of 3-5% for high-ticket items and 10%+ for low-ticket items. The per-product pct_threshold configuration in this guide handles this. Stale history file corruption — if your pipeline crashes between fetching prices and writing the history file, the next run compares against stale data and may produce false alerts. Use atomic writes (write to a temp file, then rename) and add a timestamp check that skips comparison if the last snapshot is over 48 hours old. Missing availability context — a product that drops 30% but shows "Out of Stock" is a clearance signal, not a deal. Always include availability in your alert message so the recipient can act appropriately.

A fourth issue: retailer-specific pricing quirks. Amazon shows "List Price" crossed out with a "Deal Price" in the UI, but the structured data may report either price depending on the listing. Calibrate targets by running one manual check per URL. Normalize URLs by stripping query parameters and trailing slashes before using them as dictionary keys.

Related use cases

Frequently asked questions

How quickly can the alert pipeline detect a price drop?

Detection speed depends on your scheduling cadence. A run scheduled every 6 hours catches price drops within 6 hours of occurrence. Every hour catches drops within 60 minutes. The actor itself completes in under 2 minutes for typical watchlists of 20-50 URLs. The bottleneck is always schedule frequency, not extraction speed. For most products, every-6-hour cadence is the sweet spot between freshness and run cost.

Can I set different alert thresholds for different products?

Yes. Store per-product thresholds in your configuration alongside the URL and target price. High-ticket items like electronics warrant 3-5% thresholds because even small percentage drops represent meaningful savings. Low-ticket items need 10-15% thresholds to avoid alerting on sub-dollar fluctuations. The pipeline code in this guide shows how to implement per-product threshold logic.

Related

Try it yourself

100 free credits, no credit card.

About 30 real searches. Add the MCP to Claude or Cursor in two minutes.