I Tested 20 Google Product SERPs for Shopping Fields. Here's What Came Back
Method note: Measurements in this article were run locally against authenticated Serpent API endpoints on August 3, 2026. Sample sizes, query sets, and limitations are stated in the article. Treat the numbers as a dated field check, not a permanent guarantee.
Short answer: I tested a Google SERP API against 20 product-intent searches to see whether a product-data pipeline could safely expect Shopping fields. The answer was no. All 20 calls returned HTTP 200 and organic results, but none returned normalized Shopping items in this August 3, 2026 pilot.
If you are comparing Shopping data providers rather than designing a field contract, start with the separate Best Google Shopping API comparison. This article is narrower: it measures what showed up in public Google SERP responses for 20 product queries.
That sounds negative until you build a real ecommerce monitor. The useful lesson is not "product data is impossible." The useful lesson is that product-query SERPs are mixed surfaces: sometimes you get organic merchant pages, sometimes comparison pages, sometimes answer modules, and sometimes a Shopping module. A production schema has to preserve what was observed without inventing product fields that were not returned.
What I Tested
I ran 20 product-intent queries through /api/search using engine=google, country=us, and num=10. The query set intentionally mixed electronics, appliances, apparel, cameras, toys, and furniture so the result would not depend on one category.
This is still a pilot sample. It is strong enough to design a safer parser and write an honest field guide. It is not a claim about every country, every device, every query, or every future Google layout.
| Query | HTTP | Organic | PAA | Shopping items | Elapsed |
|---|---|---|---|---|---|
| sony wh-1000xm5 | 200 | 7 | 6 | 0 | 6.5s |
| airpods pro 2 | 200 | 7 | 6 | 0 | 8.2s |
| dyson v15 detect | 200 | 7 | 6 | 0 | 7.9s |
| nintendo switch oled | 200 | 7 | 0 | 0 | 6.6s |
| kindle paperwhite | 200 | 7 | 6 | 0 | 5.3s |
| anker power bank 20000mah | 200 | 7 | 6 | 0 | 6.7s |
| logitech mx master 3s | 200 | 7 | 8 | 0 | 5.9s |
| samsung galaxy s25 case | 200 | 7 | 6 | 0 | 8.1s |
| ipad air 13 inch | 200 | 7 | 6 | 0 | 11.0s |
| garmin forerunner 965 | 200 | 7 | 6 | 0 | 5.8s |
| instant pot duo 6 quart | 200 | 7 | 6 | 0 | 4.6s |
| breville barista express | 200 | 7 | 6 | 0 | 6.0s |
| roomba j7 | 200 | 7 | 6 | 0 | 5.7s |
| patagonia nano puff jacket | 200 | 7 | 6 | 0 | 6.1s |
| nike pegasus 41 | 200 | 7 | 6 | 0 | 5.4s |
| adidas sambas | 200 | 7 | 6 | 0 | 4.9s |
| lego millennium falcon | 200 | 7 | 6 | 0 | 5.5s |
| canon eos r50 | 200 | 7 | 6 | 0 | 5.7s |
| sony a6700 lens | 200 | 7 | 6 | 0 | 5.1s |
| standing desk converter | 200 | 7 | 6 | 0 | 5.6s |
What Came Back
The headline result is simple: 20/20 HTTP 200, 20/20 with organic results, 0/20 with normalized Shopping items. Median elapsed time was 5.9s.
The organic result count was stable at seven results for every query in this run. People Also Ask was present on 19 of the 20 queries. The Shopping array was empty every time.
If your product monitor expects a seller, price, shipping estimate, product thumbnail, and product URL on every product query, this is where the bug enters. The response can be successful and still not have those fields.
| Shopping field | Observed non-empty values | Coverage across shopping rows |
|---|---|---|
| title | 0 | 0% |
| seller | 0 | 0% |
| price | 0 | 0% |
| availability | 0 | 0% |
| delivery | 0 | 0% |
| shipping | 0 | 0% |
| rating | 0 | 0% |
| image | 0 | 0% |
| thumbnail | 0 | 0% |
| url | 0 | 0% |
| product_url | 0 | 0% |
What the Empty Shopping Block Means
An empty Shopping array is not the same thing as a failed search. It means the normalized response did not include Shopping items for that query at that time. Your pipeline should record the search, record the absence, and avoid turning absence into false product data.
For ecommerce dashboards, this is especially important because a blank price column can mean several different things: no Shopping block, no merchant price exposed, no result for the product, or a parser contract change. Those should be separate states in your warehouse.
shopping_observed separately from shopping.length. Then your reports can distinguish "the API returned no Shopping items" from "the job never ran."Merchant API vs SERP Data
Google's Merchant API documentation describes a programmatic surface for Merchant Center accounts and related resources. Google's product data specification explains the product information merchants provide so Google can match products to user queries. Google's Merchant Center help also says the legacy Content API for Shopping remains available until August 18, 2026, then moves aside for Merchant API.
Those docs are about products you manage. This post is about observing what a shopper-facing Google result returns for a query. If you want a dedicated product listing grid rather than the organic SERP, the Shopping API is the surface for that — this post deliberately measures the SERP surface, which is why the Google SERP API is the link here.
| Question | Best surface | Why |
|---|---|---|
| What products did I upload to Merchant Center? | Google Merchant API | You own the feed and account context. |
| What did a user see when searching for a product? | Google SERP API | You need the public result page, not your feed record. |
| Did a competitor page outrank my product page? | Google SERP API | Organic result order matters even when Shopping fields are absent. |
| Do I want a product listing grid with prices and merchants? | Shopping API (Google engine) | Dedicated product search, not the organic SERP. |
| Can I safely compare prices for this SKU? | SERP data plus matching logic | First prove the result is the same product, then compare price. |
The Field Contract I Would Use
I would store the product SERP response as an observation, not as a guaranteed product offer. That means the search row should survive even when Shopping fields are empty.
{
"query": "sony wh-1000xm5",
"engine": "google",
"country": "us",
"measured_at": "2026-08-03T12:01:00Z",
"organic_count": 7,
"paa_count": 6,
"shopping_observed": false,
"shopping_items": [],
"top_organic": [
{
"position": 1,
"title": "Sony WH-1000XM5 Premium Wireless Noise Canceling Headphones ...",
"url": "https://electronics.sony.com/..."
}
]
}
When a Shopping item does appear, use nullable columns for title, seller, price, availability, shipping, rating, thumbnail, and product_url. Do not force defaults like 0, unknown seller, or an empty string unless your downstream system explicitly needs them.
Python Example
This example is intentionally boring. It is a contract check that writes the fields you can rely on and marks Shopping absence explicitly.
import csv
import os
import requests
from datetime import datetime, timezone
BASE = "https://apiserpent.com"
API_KEY = os.environ["SERPENT_API_KEY"]
QUERIES = [
"sony wh-1000xm5",
"airpods pro 2",
"dyson v15 detect",
]
def fetch(query):
response = requests.get(
f"{BASE}/api/search",
headers={"X-API-Key": API_KEY},
params={"q": query, "engine": "google", "country": "us", "num": 10},
timeout=60,
)
response.raise_for_status()
data = response.json()
results = data.get("results", {})
return {
"query": query,
"measured_at": datetime.now(timezone.utc).isoformat(),
"organic_count": len(results.get("organic") or []),
"paa_count": len(results.get("peopleAlsoAsk") or []),
"shopping_count": len(results.get("shopping") or []),
"shopping_observed": bool(results.get("shopping")),
}
with open("product_serp_observations.csv", "w", newline="") as handle:
writer = csv.DictWriter(handle, fieldnames=[
"query", "measured_at", "organic_count", "paa_count",
"shopping_count", "shopping_observed",
])
writer.writeheader()
for query in QUERIES:
writer.writerow(fetch(query))
How to Use the Organic Candidates
The organic results still matter. In this pilot, all 20 queries returned organic product or product-adjacent pages. For many ecommerce jobs, those pages are the first candidate pool for SKU matching, reseller discovery, and brand-owned-page visibility.
I would store the top organic title, URL, host, position, and a normalized token list. Then I would run a separate matching job that decides whether the page is the exact product, an accessory, a comparison article, a category page, or an unrelated result. That separation keeps your SERP collection simple and your product logic auditable.
| Organic result type | Example signal | Suggested action |
|---|---|---|
| Brand product page | Brand host plus model token in title | High-confidence candidate for product ownership and canonical specs. |
| Retailer PDP | Retailer host plus model token and purchase intent | Candidate for price or availability review if product match passes. |
| Marketplace search page | Retailer host but category/search URL | Do not treat as exact SKU without deeper matching. |
| Review article | Review/comparison wording in title | Useful for visibility, weak for price monitoring. |
| Accessory page | Negative token like case, charger, cover, compatible | Reject for exact-product price comparisons. |
Edge Cases That Break Product Dashboards
The most common bug is treating a successful API response as a successful product-offer response. They are not the same state. A search can succeed, return organic candidates, return PAA, and still have no Shopping offers.
The second bug is mixing query intent. "iPad Air 13 inch" can return Apple pages, retailer pages, support pages, and model-comparison pages. "Samsung Galaxy S25 case" is an accessory query, not a phone query. If your dashboard expects one SKU per query, those differences need explicit review rules.
The third bug is using price as a matching feature too early. Price is volatile and can differ by bundle, condition, seller, tax, shipping, and region. Match the product first. Compare price second.
Warehouse Checks I Would Add
Add a daily assertion that counts successful product queries with no Shopping rows. That number should be allowed, visible, and trended. If it suddenly changes from 0 of 20 to 18 of 20, that is a product-surface event worth reviewing. If it stays near zero, your dashboard should still show organic product visibility instead of looking broken.
Also track query class. Exact model queries, accessory queries, broad category queries, and brand-only queries should not share one success threshold. The result shape is different enough that one global "product data coverage" metric will confuse the team using it.
I would add one more check before this reaches an executive dashboard: compare the SERP collection table against the product catalog table by query intent, not by SKU alone. A catalog SKU can map to several public search queries, and one query can expose several product candidates. The join should preserve that many-to-many shape instead of collapsing everything into one row too early.
For auditability, keep the raw query, normalized query, country, measured timestamp, top organic host list, and Shopping observation state in the same fact table. Then a reviewer can explain why a product had visibility without price fields, or why a price comparison was skipped for lack of exact-match evidence.
What I Would Not Build From This Data
I would not build an automated price monitor that assumes every product query returns comparable offers. I would not build a seller-share dashboard from this sample. I would not claim "Google Shopping is empty" as a universal fact. The only honest conclusion is narrower and more useful: in this 20-query pilot, product-intent SERPs returned organic/PAA data but no normalized Shopping items.
The next layer is SKU matching. For that, use the organic product pages as candidate evidence, then apply brand, model, variant, seller, and negative-token rules before a price comparison. The related guide Google Shopping SKU Matching in Python is the right follow-up after this pilot standard is approved.
Limitations
- The pilot used 20 product queries, one country, and one date.
- The test used web search output, not a Merchant Center account export.
- The result does not prove Shopping modules never appear. It proves the code must handle absence correctly.
- Field availability can vary by query, country, language, date, device, and result layout.
Recommendation
Use product SERP data as an observation layer. Keep the raw query, timestamp, country, organic candidates, PAA count, and explicit Shopping presence flag. Then let downstream jobs decide whether the observation is strong enough for product matching, price intelligence, or a manual review queue.
For production SERP collection, start with the Google SERP API. For a dedicated product listing grid with prices and merchants, use the Shopping API with the Google Shopping API engine. For broader ecommerce strategy, pair this with ecommerce price intelligence, price monitoring with SERP data, and Google Shopping price scraping caveats.
References
- Google Merchant API documentation
- Google Merchant Center product data specification
- Google Merchant Center Help: Merchant API transition and Content API sunset
FAQ
Is Google Merchant API the same thing as Google Shopping SERP data?
No. Merchant API manages products and related Merchant Center resources for your own account. SERP data records what public search returned for a shopper query.
Did this test find any normalized Shopping results?
No. In the August 3, 2026 pilot, 20 of 20 Google product-intent SERP calls returned HTTP 200 and organic results, but 0 returned normalized shopping items.
Does zero Shopping items mean the query failed?
No. Every query in this pilot returned organic results. The right interpretation is that the Shopping block was not observed in the normalized response shape for this run.
Should I store empty Shopping fields as nulls or zeros?
Store missing fields as null or an empty array, and keep a separate observed flag. Do not create fake prices, sellers, or product URLs.
Why link this post to the Google SERP API pillar?
The post measures what a public Google SERP response returns for product-intent queries, so the Google SERP API is the surface under test. A dedicated product listing grid is available separately through the Shopping API.



