Overview
Whether you are repricing your own products or tracking competitors, knowing Amazon prices in real time matters. This workflow runs every morning, searches your product list on Amazon via Scavio, records current prices, compares against your baseline, and alerts you to any change above your threshold. It also tracks stock availability so you know when a competitor goes out of stock. Monitoring 20 products daily costs about $0.10 in credits.
Trigger
Cron 6 AM UTC daily
Schedule
Daily 6 AM
Workflow Steps
Load Product Watchlist
Read the list of Amazon ASINs or product names to track from a JSON configuration file.
Search Amazon via Scavio
For each product, call Scavio search on Amazon and extract the current price and availability.
Compare Against Baseline
Load the previous prices from storage and compute the absolute and percentage change.
Detect Significant Changes
Filter products whose price changed more than the configured threshold (default 3%).
Send Alerts
Push price change notifications to Slack, email, or a webhook for immediate action.
Update Price History
Append today's prices to the historical database for trend analysis.
Python Implementation
import requests, os, json
from pathlib import Path
from datetime import date
API_KEY = os.environ["SCAVIO_API_KEY"]
SH = {"x-api-key": API_KEY, "Content-Type": "application/json"}
THRESHOLD = 0.03
WATCHLIST_FILE = Path("amazon_watchlist.json")
HISTORY_FILE = Path("amazon_price_history.jsonl")
BASELINE_FILE = Path("amazon_baseline.json")
def search_amazon(query: str) -> dict:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=SH,
json={"query": query, "platform": "amazon"},
timeout=15,
)
resp.raise_for_status()
data = resp.json()
if data.get("organic"):
top = data["organic"][0]
return {"title": top.get("title", ""), "price": top.get("price"), "in_stock": top.get("in_stock", True), "url": top.get("url", "")}
return {}
def run():
watchlist = json.loads(WATCHLIST_FILE.read_text())
baseline = json.loads(BASELINE_FILE.read_text()) if BASELINE_FILE.exists() else {}
alerts = []
today_prices = {}
for item in watchlist:
slug = item["slug"]
result = search_amazon(item["query"])
current_price = result.get("price")
today_prices[slug] = {"price": current_price, "in_stock": result.get("in_stock"), "title": result.get("title", "")}
prev_price = baseline.get(slug, {}).get("price")
if current_price and prev_price:
change_pct = (current_price - prev_price) / prev_price
if abs(change_pct) >= THRESHOLD:
direction = "UP" if change_pct > 0 else "DOWN"
alerts.append(f"{direction} {abs(change_pct)*100:.1f}%: {item['query']} ${prev_price} -> ${current_price}")
prev_stock = baseline.get(slug, {}).get("in_stock", True)
if prev_stock and not result.get("in_stock", True):
alerts.append(f"OUT OF STOCK: {item['query']}")
BASELINE_FILE.write_text(json.dumps(today_prices, indent=2))
with open(HISTORY_FILE, "a") as f:
f.write(json.dumps({"date": str(date.today()), "prices": today_prices}) + "\n")
print(f"Monitored {len(watchlist)} products on {date.today()}")
for a in alerts:
print(f" ALERT: {a}")
run()JavaScript Implementation
const SH = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
const fs = await import('fs');
const THRESHOLD = 0.03;
const watchlist = JSON.parse(fs.readFileSync('amazon_watchlist.json', 'utf8'));
let baseline = {};
try { baseline = JSON.parse(fs.readFileSync('amazon_baseline.json', 'utf8')); } catch {}
async function searchAmazon(query) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {method:'POST', headers:SH, body:JSON.stringify({query, platform:'amazon'})});
const data = await r.json();
if (data.organic && data.organic.length > 0) {
const top = data.organic[0];
return {title:top.title||'', price:top.price, inStock:top.in_stock!==false, url:top.url||''};
}
return {};
}
const alerts = [];
const todayPrices = {};
for (const item of watchlist) {
const result = await searchAmazon(item.query);
todayPrices[item.slug] = {price:result.price, inStock:result.inStock, title:result.title};
const prev = baseline[item.slug] || {};
if (result.price && prev.price) {
const changePct = (result.price - prev.price) / prev.price;
if (Math.abs(changePct) >= THRESHOLD) {
alerts.push((changePct>0?'UP':'DOWN')+' '+(Math.abs(changePct)*100).toFixed(1)+'%: '+item.query+' $'+prev.price+' -> $'+result.price);
}
}
if (prev.inStock && !result.inStock) alerts.push('OUT OF STOCK: '+item.query);
}
fs.writeFileSync('amazon_baseline.json', JSON.stringify(todayPrices, null, 2));
fs.appendFileSync('amazon_price_history.jsonl', JSON.stringify({date:new Date().toISOString().split('T')[0], prices:todayPrices})+'\n');
console.log('Monitored '+watchlist.length+' products');
alerts.forEach(a => console.log(' ALERT: '+a));Platforms Used
Amazon
Product search with prices, ratings, and reviews