Originally posted on the Scrapio blog — sharing here too.
Price monitoring is a common automation need — whether you're tracking a competitor, waiting for a deal, or monitoring supplier costs. The traditional path involves a server, a cron job, a scraper, and a notification system. With Scrapio you only need the last two.
Scrapio now also has native Monitors — set the URL, the fields to extract, and which ones to watch from the dashboard, and Scrapio owns the schedule, the "last value" comparison, and the webhook delivery for you. The walkthrough below is still useful if you want the cron trigger and comparison logic running in your own infrastructure (e.g. to chain into other systems), but for most teams the native Monitor is the faster path — skip to Next steps to try it.
What you'll need
- A Scrapio API key
- A cron trigger (GitHub Actions, cron-job.org, or any scheduler)
- A webhook URL to receive notifications (use webhook.site for testing)
The approach
The pattern is simple:
- A cron trigger fires on a schedule (e.g. every Monday at 9am)
- It calls Scrapio to extract the current price from the product page
- It compares against the last recorded price
- If the price dropped, it sends a notification
Step 1 — Fetch the price with Scrapio
Use the extract parameter to pull just the fields you care about:
import httpx
API_KEY = "sk-..."
def get_price(url: str) -> dict:
resp = httpx.post(
"https://api.scrapio.dev/v1/fetch",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"url": url,
"output": ["json"],
"extract": {
"mode": "schema",
"schema": {
"price": "number",
"availability": "string",
},
},
"render_js": True,
},
timeout=30,
)
resp.raise_for_status()
return resp.json()["outputs"]["json"]
Step 2 — Compare and notify
import json
import os
import httpx
PRICE_FILE = "last_price.json"
WEBHOOK_URL = "https://your-webhook-url.com/price-alert"
PRODUCT_URL = "https://example.com/products/iphone-15"
def load_last_price() -> float | None:
if os.path.exists(PRICE_FILE):
return json.loads(open(PRICE_FILE).read()).get("price")
return None
def save_price(price: float) -> None:
open(PRICE_FILE, "w").write(json.dumps({"price": price}))
def run():
current = get_price(PRODUCT_URL)
price = current["price"]
last = load_last_price()
if last is not None and price < last:
httpx.post(WEBHOOK_URL, json={
"message": f"Price dropped from ${last:.2f} to ${price:.2f}",
"url": PRODUCT_URL,
"price": price,
})
save_price(price)
run()
Step 3 — Schedule with GitHub Actions
Create .github/workflows/price-monitor.yml:
name: Price Monitor
on:
schedule:
- cron: "0 9 * * 1" # Every Monday at 9am UTC
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install httpx
- run: python monitor.py
env:
SCRAPIO_API_KEY: ${{ secrets.SCRAPIO_API_KEY }}
GitHub Actions is free for public repos and the free tier covers hundreds of runs per month for private ones. No server required.
Cron expressions quick reference
| Expression | Meaning |
|---|---|
0 9 * * 1 |
Every Monday at 9am UTC |
0 */6 * * * |
Every 6 hours |
0 8 * * * |
Every day at 8am UTC |
*/30 * * * * |
Every 30 minutes |
Next steps
- Try the native Monitors dashboard — no cron trigger or webhook server to host
- See the Native Price Monitoring template for a step-by-step walkthrough
- Monitoring content beyond price? See Website Change Detector — or use a native monitor with
"watch": {"mode": "content"}for the same thing without hosting anything - Prefer to run it yourself? Try the Price Drop Alert template for the GitHub Actions recipe
- Read the Fetch API docs
Top comments (0)