Shopping Price Monitoring: A Playbook for Google + Yahoo Product SERPs

By Serpent API Team · · 6 min read

Price monitoring lives or dies on coverage. A retailer whose own feed says “$89.99” is only half the story — the other half is what the market actually shows shoppers, and that varies by engine. Google and Yahoo Shopping run independent product indexes, so the same product query can surface different merchants, different prices, and different availability in each. A monitoring loop that reads only one engine sees a slice of the market.

This playbook builds a two-engine price monitor on top of a single endpoint — /api/shopping — that returns Google Shopping with engine=google and Yahoo Shopping with engine=yahoo. You query both, normalize the price strings, store a daily baseline, and alert when the lowest offer drops.

TL;DR: Hit /api/shopping?engine=google and /api/shopping?engine=yahoo for the same product, merge the results.shopping arrays, normalize each price string to cents, and compare against yesterday's stored minimum. When the current lowest offer is lower, you have a price drop. Prices are returned where the placement renders them — some placements omit a price, so price can be null; skip those rather than treating them as $0.

Why two engines, not one

Google Shopping and Yahoo Shopping are separate product indexes with their own merchants and price signals. The same query in both engines returns a different offer set — a merchant may surface on Yahoo and not Google, or price the same product differently in each. Cross-engine monitoring does two things: it widens coverage (you see offers either engine alone would miss) and it gives you a second opinion on any single price change (a drop visible in both engines is far more trustworthy than one visible only in a single listing).

The two calls: Google and Yahoo through /api/shopping

Both engines live on the same endpoint. The only thing that changes is the engine parameter:

RequestReturns
/api/shopping?q=sony+wh-1000xm5&engine=google&num=20Google Shopping product listings
/api/shopping?q=sony+wh-1000xm5&engine=yahoo&num=20Yahoo Shopping product listings (also the default)

Each product result carries position, title, price, currency, url, thumbnail, and a merchant field. The two engines differ slightly in field naming — Google returns link/source/product_rating/product_reviews, while Yahoo returns url/merchant/rating/reviews — but the shared fields (position, title, price, thumbnail) line up, which is all a price monitor needs.

Query both engines in Node.js

Here is a small function that queries either engine and returns the product list, then uses it to pull both sides of the market:

async function shopping(query, engine) {
  const res = await fetch(
    `https://apiserpent.com/api/shopping?q=${encodeURIComponent(query)}&engine=${engine}&num=20`,
    { headers: { 'X-API-Key': 'YOUR_API_KEY' } }
  );
  const json = await res.json();
  return json.results.shopping ?? [];
}

const google = await shopping('sony wh-1000xm5', 'google');
const yahoo = await shopping('sony wh-1000xm5', 'yahoo');
const all = [...google, ...yahoo];

Two HTTP requests, one merged list of offers. That merged list is your raw material — now turn the price strings into numbers you can compare.

Normalizing prices (and handling null)

Prices arrive as display strings like "$399.99". To compare them, strip currency symbols and convert to an integer number of cents. The critical detail: some placements do not render a price at all, so price can be null. Treat null as “no price available,” not as $0 — a $0 reading would instantly and wrongly register as a price drop.

function toCents(price) {
  if (!price) return null;              // honest: some placements have no price
  const m = String(price).replace(/[$,]/g, '').match(/[\d.]+/);
  return m ? Math.round(parseFloat(m[0]) * 100) : null;
}

// Lowest priced offer across both engines, skipping nulls:
const best = all
  .filter(p => toCents(p.price) !== null)
  .sort((a, b) => toCents(a.price) - toCents(b.price))[0];

console.log('Lowest offer:', best.title, best.price, best.merchant || best.source);

Filtering nulls first means your “lowest price” is computed only over placements that actually showed a price — which is the honest answer, not a guess.

The price-drop loop

A one-off comparison is a snapshot. A monitor stores a baseline — the lowest price per product per day — and compares each new reading against it. When the current minimum falls below the stored baseline, fire an alert:

// lastSeen: { [title]: lowest cents observed yesterday }
const today = await shopping('sony wh-1000xm5', 'yahoo');

for (const p of today) {
  const cents = toCents(p.price);
  if (cents === null) continue;                 // no price on this placement
  if (lastSeen[p.title] !== undefined && cents < lastSeen[p.title]) {
    console.log('PRICE DROP:', p.title, '→', p.price, 'at', p.merchant);
  }
  lastSeen[p.title] = Math.min(lastSeen[p.title] ?? cents, cents);
}

// persist lastSeen to a store; it becomes tomorrow's baseline

The loop is intentionally small: query, normalize, compare, store. Run it on a schedule — daily is enough for most product categories — and you get a price history plus a drop alert for every tracked product. For a deeper walkthrough of the alerting half, see our price drop alerts post.

Scheduling and honest cost

Shopping search costs $0.60 per 1,000 requests on the Default tier, $0.06 per 1,000 on Growth, and $0.03 per 1,000 on Scale, for both Google and Yahoo engines. Shopping requires paid credits from call 1 — credits never expire and there is no subscription. Concretely: monitoring one product across both engines once a day is two calls — 60 products a day is 120 calls, which at Scale pricing is a fraction of a cent. The bill tracks the number of queries you run, not the number of products you track.

Two practical notes. First, request num=20 or higher so your baseline covers more than the top few placements — the lowest offer is often below the fold. Second, store the raw price string alongside the numeric value, so when a price changes you can see exactly what the market showed rather than only the delta. The Shopping API hub and the Google Shopping and Yahoo Shopping references document every field.

Monitor both engines. Catch every drop.

Query Google and Yahoo Shopping through one endpoint — /api/shopping — and merge the offers. Flat per-call pricing from $0.03/1K at Scale, credits never expire, no subscription.

Get Your Free API Key

Explore: Google Shopping API · Yahoo Shopping API · Shopping API · Docs

FAQ

Why monitor both Google and Yahoo Shopping?

Google and Yahoo Shopping are independent product indexes. The same query can surface different merchants, different prices, and different product availability in each. Querying both gives a broader view of the market and lets you cross-check a price change instead of trusting a single source.

Is a price always returned for every product?

No. Prices, ratings, and review counts are returned when the shopping source provides them. Some product placements render without a visible price, so the price field can be null. A monitoring loop must skip or handle null prices rather than treating them as a real price of zero.

How do I detect a price drop?

Normalize each price string to a numeric value, store the lowest offer per product per day, and compare each new reading against the previous baseline. When the current minimum is lower than the stored baseline, you have a price-drop signal to alert on.

What does shopping price monitoring cost?

Shopping search costs $0.60 per 1,000 requests on the Default tier, $0.06 per 1,000 on Growth, and $0.03 per 1,000 on Scale for both Google and Yahoo engines. Shopping requires paid credits from call 1. Credits never expire and there is no subscription, so cost scales with how many product queries you run.