When a shopper searches for a product on Google, the Shopping results are a live snapshot of the market: which retailers sell it, at what price, with what shipping, as seen from where that shopper is. For an e-commerce team, that snapshot answers questions that usually take dozens of separate crawls: who undercuts us, on which products, in which markets, and by how much.
A Google Shopping API turns that snapshot into structured data you can query on a schedule. This guide covers what teams use it for, how to collect it so the numbers are trustworthy, and a small piece of code that turns search results into a pricing view. It is part of the wider practice of price intelligence, with Shopping data as one of its most efficient inputs.
Why Shopping data is different from crawling retailers
The traditional way to watch competitors’ prices is to crawl each retailer’s product pages. That works, but it scales badly: every retailer needs its own collector, its own parser and its own product matching. Shopping results flip the model:
- One query covers many sellers. A single search returns offers from every retailer Google lists for that product.
- Products are already grouped. Offers for the same item appear together, which takes much of the pain out of matching products across stores.
- It shows the shopper’s view. Results reflect the market and language of the search, including which sellers appear and in what order, which is what actually drives clicks.
The trade-off is coverage. Shopping results show the retailers that list there, not every seller in the market, and they show the listed price, which may differ from the price after a coupon or at checkout. For full-catalogue tracking you still need retailer crawls; for a market-wide view of your key products, Shopping data is often faster and cheaper. Our guide to building a real-time competitive price feed covers combining both.
What teams use it for
| Question | What the data shows |
|---|---|
| Are we competitively priced? | Our rank on price for each product, and the gap to the cheapest seller |
| Who is undercutting us? | Which sellers appear below us, how often and on which products |
| How crowded is this product? | The number of sellers and how widely prices spread |
| Is a competitor running a promotion? | Sudden price drops across a seller’s products |
| How do markets differ? | The same product’s sellers and prices in each country |
| Are resellers breaking price policy? | Authorised sellers listing below the minimum advertised price |
That last use is as much about brand protection as pricing: manufacturers use Shopping data to spot unauthorised sellers and minimum-price violations without crawling every reseller.
Collecting it properly
Shopping results depend on who is asking, so consistent collection matters more than volume.
- Fix the location and language. Results change by country and often by city. Use the same location and language settings on every run, or comparisons between runs will mix markets.
- Use stable queries. Search with the same product terms each time, ideally the product’s name and model number, so the same listings come back.
- Collect on a cadence that matches the market. Research on online prices shows weekly collection captures most regular price changes at large retailers, while fast categories and promotions need daily checks. Our study of how fast online prices change covers the evidence.
- Keep the raw results. Store each run’s full response with its time and settings, so you can re-check a finding later.
- Normalise prices before comparing. Currencies, decimal formats and tax inclusion differ by market. Our guide to normalising prices, numbers and dates across locales covers the parsing.
Running Google searches at scale from your own servers runs into blocks and inconsistent results quickly, which is why most teams use an API built for it. Shifter’s SERP API returns Google Shopping results as structured JSON, with the location and language you set, so the work starts at analysis rather than collection.
From results to a pricing view
Once each listing’s product, seller and price are mapped into a simple record, a few lines of code produce the view a pricing team actually needs. The module below builds the request parameters for one search and turns a run’s offers into a per-product summary: the cheapest seller, the median price, how wide the spread is, and where your store ranks.
from collections import defaultdict
from statistics import median
def shopping_params(query, location, country, language="en", api_key="YOUR_API_KEY"):
"""One Google Shopping search, as seen by a shopper in `location`."""
return {"engine": "google_shopping", "api_key": api_key, "q": query,
"location": location, "gl": country, "hl": language}
def market_view(offers, my_seller):
"""offers: [{"product": key, "seller": name, "price": float}] from one search run.
For each product: the cheapest seller, the median price, how wide the spread
is, and where `my_seller` ranks on price.
"""
by_product = defaultdict(list)
for o in offers:
by_product[o["product"]].append(o)
report = {}
for product, rows in by_product.items():
rows.sort(key=lambda o: o["price"])
prices = [o["price"] for o in rows]
mine = next((i for i, o in enumerate(rows) if o["seller"] == my_seller), None)
report[product] = {
"sellers": len(rows),
"cheapest": f"{rows[0]['seller']} {prices[0]:.2f}",
"median": round(median(prices), 2),
"spread_pct": round(100 * (prices[-1] - prices[0]) / prices[0], 1),
"my_rank": None if mine is None else mine + 1,
"gap_to_cheapest_pct": None if mine is None
else round(100 * (rows[mine]["price"] - prices[0]) / prices[0], 1),
}
return report
Run on a handful of illustrative offers:
from shopping import market_view
offers = [ # illustrative results from one search run, mapped into the offer shape
{"product": "air fryer 6qt", "seller": "Store A", "price": 89.99},
{"product": "air fryer 6qt", "seller": "Our Store", "price": 99.00},
{"product": "air fryer 6qt", "seller": "Store C", "price": 119.95},
{"product": "blender 1.5l", "seller": "Our Store", "price": 54.00},
{"product": "blender 1.5l", "seller": "Store B", "price": 59.99},
]
for product, view in market_view(offers, my_seller="Our Store").items():
print(product, view)
air fryer 6qt {'sellers': 3, 'cheapest': 'Store A 89.99', 'median': 99.0, 'spread_pct': 33.3, 'my_rank': 2, 'gap_to_cheapest_pct': 10.0}
blender 1.5l {'sellers': 2, 'cheapest': 'Our Store 54.00', 'median': 57.0, 'spread_pct': 11.1, 'my_rank': 1, 'gap_to_cheapest_pct': 0.0}
The air fryer is a crowded product with a wide spread, where Our Store sits second, 10% above the cheapest seller. The blender is a quiet product where Our Store is already cheapest. Run the same report every day and the changes, a new seller below you, a spread suddenly widening, are the signals worth acting on.
Turning the signals into decisions
- Price where you are visible. Products where you rank first or second already win on price; there may be margin to recover. Products where you rank last are where a price change moves the most traffic.
- Watch the spread, not just the minimum. A wide spread usually means a market with room to price; a narrow one means a commodity where small differences matter.
- Separate promotions from repricing. A competitor’s drop that reverses in a week is a promotion; one that holds is a new price. Our guide to tracking competitor promotions and discount cycles shows how to tell them apart.
- Compare markets before you expand. The number of sellers and their prices in a new country show how crowded it is before you list there.
Limits to keep in mind
- Not every seller lists on Google Shopping. The data shows the visible market, not the whole market.
- Listed prices are not always final prices. Shipping, taxes, coupons and member prices can change what the shopper pays.
- Results vary between identical searches. Act on patterns that hold across runs, not on one run’s ordering.
- Personalisation is limited but real. Use neutral settings and a fixed location to keep runs comparable.
FAQ
What is a Google Shopping API?
A service that runs Google Shopping searches for you and returns the results as structured data: the products, the sellers offering them and their prices, as seen from the location and language you specify.
What can e-commerce teams do with Google Shopping data?
Track competitors’ prices across many sellers at once, see where their own prices rank, spot promotions and new sellers, compare markets before expanding, and check resellers against minimum advertised prices.
How often should I collect Google Shopping results?
Weekly is enough for many categories; daily for fast-moving ones, around promotions and in peak season. Keep the location, language and queries fixed so runs are comparable.
Does Google Shopping show every seller’s price?
No. It shows the retailers that list their products there, and the listed price, which may differ from the price after shipping, coupons or at checkout. Combine it with direct retailer crawls where you need complete coverage.
The bottom line
Google Shopping results are one of the most efficient views of a product’s market: many sellers, already grouped, as a local shopper sees them. Collect them with fixed location, language and queries, keep the raw results, normalise prices, and summarise each run into rank, spread and gap to the cheapest seller. Watched over time, those few numbers tell an e-commerce team where to move prices and where to leave them alone. For broader e-commerce data needs, see our e-commerce solutions.