Price Drop Alerts with a Shopping API

By Serpent API Team · · 9 min read

A price-drop alert is a four-step loop: poll a product query on a schedule, read the numeric extractedPrice from each listing, compare it to your stored baseline, and notify when it falls. The Shopping API supplies everything the loop needs in one call — price, currency, merchant, and a stable product URL to key the alert on.

This guide walks through the pattern with a tested Python script and honest cost math, so you know what a real price-watch system costs before you build it.

TL;DR: Poll /api/shopping for your watchlist, use extractedPrice (a number, not a string) to compare, store a baseline per product, and fire when the current price drops below it. Skip null prices. At the Scale tier a 1,000-keyword daily sweep costs a few cents a day.

Table of Contents

The price-drop loop

Every price-watch system, from a hobby script to an enterprise repricer, is the same four steps:

  1. Poll. On a schedule, query each product you watch.
  2. Normalize. Turn the display price into a number you can compare.
  3. Compare. Against the last price you stored for that product.
  4. Alert. When the current price drops below the baseline (or your threshold).

The hard part is never the loop — it is getting a clean, comparable price reliably. That is where the API earns its keep.

Price data the API gives you

Each listing in the Shopping API response includes both a display price string and a numeric extractedPrice. The numeric one is what your comparison logic should use:

{
  "title": "Sony WF-1000XM6",
  "price": "$299.99",        // display string
  "extractedPrice": 299.99,  // number, ready for math
  "currency": "USD",
  "merchant": "Best Buy",
  "url": "https://www.bestbuy.com/product/sony-wf1000xm6-..."
}

Keying alerts on url (the merchant product URL) keeps the same product stable across polls. Keying on the title alone is fragile — two merchants can sell "Nike Vomero 18" at different prices, and that is exactly the difference you want to catch.

Working Python: a price watcher

Here is a complete, runnable watcher. It keeps baselines in a JSON file, polls a watchlist, and prints an alert for every product whose price dropped since the last run. Wire the print to your email, Slack, or push channel.

Replace sk_live_your_key with your key from the dashboard.

import json
import os
import time
import requests

API_KEY = "sk_live_your_key"
BASE_URL = "https://apiserpent.com/api/shopping"
STATE_FILE = "price_baselines.json"

def fetch_prices(query):
    resp = requests.get(
        BASE_URL,
        params={"q": query, "engine": "yahoo", "num": 20},
        headers={"X-API-Key": API_KEY},
        timeout=60,
    )
    resp.raise_for_status()
    out = {}
    for item in resp.json()["results"]["shopping"]:
        price = item.get("extractedPrice")
        if price is None:                 # Yahoo didn't show a price this poll
            continue
        out[item["url"]] = {
            "title": item["title"],
            "price": price,
            "merchant": item.get("merchant"),
        }
    return out

def load_state():
    if os.path.exists(STATE_FILE):
        return json.load(open(STATE_FILE))
    return {}

def save_state(state):
    json.dump(state, open(STATE_FILE, "w"), indent=2)

WATCHLIST = ["nike running shoes", "sony headphones", "iphone 15 case"]

state = load_state()
for query in WATCHLIST:
    for url, listing in fetch_prices(query).items():
        previous = state.get(url, {}).get("price")
        current = listing["price"]
        if previous is not None and current < previous:
            drop = previous - current
            print(f"PRICE DROP ({drop:.2f}) {listing['title']} "
                  f"${current:.2f} was ${previous:.2f} @ {listing['merchant']}")
        state[url] = listing

save_state(state)
print(f"\nWatched {len(state)} products. Baselines saved to {STATE_FILE}.")

Run it once to seed baselines, then again later — any product whose extractedPrice fell prints a PRICE DROP line. The script skips listings with no price instead of treating null as a catastrophic drop to zero.

Cost math for a real watchlist

Here is what a price-watch system actually costs on the Shopping API, billed per 1,000 calls (no page multiplier, no subscription):

TierPer 1,000 calls500 keywords, 1×/day5,000 keywords, 1×/day
Default$0.60$0.30/day$3.00/day
Growth$0.06$0.03/day$0.30/day
Scale$0.03$0.015/day$0.15/day

At the Scale tier a 500-keyword daily sweep is a cent and a half a day. Even hourly checks of a 200-product watchlist (4,800 calls/day) stay well under a dollar a day. See the pricing page for the current full table.

Honest limits

Next step: pull a key from the dashboard, try the Shopping API in the playground, then adapt the watcher above. Pair it with price monitoring, e-commerce price intelligence, or the cross-engine Google vs Yahoo comparison.

FAQ

How do price drop alerts work with a shopping API?

Poll a query on a schedule, read the numeric extractedPrice, compare it to the baseline you stored for that product URL, and alert when it falls below a threshold.

What is the cheapest way to track price drops?

Shopping calls cost $0.00003 each at the Scale tier. A 1,000-keyword catalog checked once a day is a few cents a day, so even hourly sweeps of a small watchlist are affordable.

Why is the price sometimes missing?

The product rail hydrates prices asynchronously, so a small share of listings can lack a displayed price at read time. Skip nulls in your loop and log them; never treat a missing price as a zero.

Can I get historical price data?

No API returns the prices it showed yesterday. You build history by storing baselines as you poll. The API supplies the current price; your store supplies the past.

Does engine=yahoo vs engine=google matter for price alerts?

Both engines return price and extractedPrice. Query the same product on both for a cross-engine view of the lowest offer — see the Google vs Yahoo comparison for the pattern.