---
title: "Google Shopping API: Product Prices and Offers as JSON"
description: "One GET to /v1/google-shopping/search returns product titles, sellers, prices and ratings as JSON. Parameters, a response and the cost of 500 products a day."
url: https://perceptlayer.com/blog/google-shopping-api-product-prices
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# Google Shopping API: Product Prices and Offers as JSON

18 Aug 2026 Perceptlayer 7 min read

To get Google Shopping prices as JSON, send one GET request to `/v1/google-shopping/search` with a search query in `q`. Each result comes back with a title, a seller, a price as text, the same price as a number, a rating and a product ID. A successful call costs 1 credit, and a failed call costs nothing.

This guide covers the request, the parameters, a recorded response and what a daily price check for 500 products costs in credits.

## Key takeaways

-   The Google Shopping API has one endpoint, `GET /v1/google-shopping/search`. It needs only `q`, and every successful call costs 1 credit.
-   Each result carries `price` as display text and `extracted_price` as a number, so you can compare prices without parsing currency symbols.
-   Google's own Merchant API is for managing how a seller's products appear on Google. For price research across sellers, you need a search endpoint like this one.
-   Tracking 500 products once a day is 500 credits a day, or 15,000 credits over 30 days. The 1,000 free monthly credits cover the first two days.
-   Pass `gl` and `hl` to set the country and language, and `start` to page through results.

## Is there an official Google Shopping API for price research?

Google's official option is the Merchant API, and it serves sellers. Google describes it as a way to [manage how your business and products appear on Google](https://developers.google.com/merchant/api/overview). That is a job for the seller who owns the products, not a search over what other sellers charge.

If you sell on Google and want to update your own feed, use the Merchant API; it fits that job better than anything here. If you want to know what a product costs across retailers, you need search results, which is what the endpoint below returns. Perceptlayer collects the data from publicly available sources and returns it as found at the time of the call, so a price is a snapshot, not a guarantee.

## How do you request product prices as JSON?

You make a GET request with a search query and your key in the `X-API-Key` header. The only required parameter is `q`. Adding `gl` (country) and `hl` (language) keeps results consistent from one run to the next, which matters when you compare prices over time.

```bash
curl "https://api.perceptlayer.com/v1/google-shopping/search?q=iphone+15&gl=us&hl=en" \
  -H "X-API-Key: $API_KEY"
```

Keys start with `sk_live_`. If you don't have one, [get a free API key](https://perceptlayer.com/signup); the [quick start](https://docs.perceptlayer.com/quickstart) takes you to a first call, and [authentication](https://docs.perceptlayer.com/authentication) covers the header and the `api_key` query parameter for places where headers aren't possible. You can also run the call from the playground on the [Google Shopping API page](https://perceptlayer.com/apis/google-shopping) before writing any code.

## Which parameters does the search endpoint take?

The search endpoint takes one required parameter, `q`, and eight optional ones: `gl`, `hl`, `location`, `uule`, `start`, `device`, `small_business` and `shoprs`. Types and limits below are as documented for [`/v1/google-shopping/search`](https://perceptlayer.com/apis/google-shopping/search). Nothing else about defaults or page sizes is documented, so test before you depend on them.

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `q` | string | yes | The search query, up to 500 characters |
| `gl` | string | no | Country code, up to 2 characters |
| `hl` | string | no | Language code, up to 2 characters |
| `location` | string | no | Search location, up to 63 characters |
| `uule` | string | no | Encoded location, up to 500 characters |
| `start` | integer | no | Offset for the next page of results |
| `device` | string | no | One of `desktop`, `mobile`, `tablet` |
| `small_business` | boolean | no | Small-business filter |
| `shoprs` | string | no | Filter token, up to 2000 characters |

Prices differ by country, so set `gl` and `hl` deliberately and keep them the same across runs. Use `location` or `uule` when you need a more specific place than a country. The recorded response below echoes the parameters it ran with in `search_parameters`, including `device`, which is worth logging next to every price you store.

## What does the response look like?

The response has three parts: `search_parameters`, which echoes the request; a `shopping_results` array with one object per product listing; and a `pagination` object that points to the next page. This is an excerpt of a recorded response for the request above, trimmed with `…`.

```json
{
  "search_parameters": {
    "q": "iphone 15",
    "gl": "us",
    "hl": "en",
    "start": 0,
    "device": "desktop"
  },
  "shopping_results": [
    {
      "position": 1,
      "category": "Popular products",
      "title": "Apple iPhone 15",
      "source": "Walmart - Wireless Source",
      "rating": 4.7,
      "reviews": 45000,
      "product_id": "4263606017411565992",
      "link": "https://www.google.com/shopping/product/4263606017411565992",
      "price": "$393.73",
      "extracted_price": 393.73,
      …
    },
    {
      "position": 2,
      "title": "Apple iPhone 15 128GB",
      "source": "Best Buy",
      "rating": 4.4,
      "reviews": 94,
      "product_id": "4379032623638529631",
      "price": "$441.00",
      "extracted_price": 441,
      …
    }
  ],
  "pagination": {
    "current_page": 1,
    "start": 0,
    "next_start": 10
  }
}
```

The fields a price pipeline uses are these:

| Field | What it holds |
| --- | --- |
| `title` | The product name as listed |
| `source` | The seller the result points to |
| `price` | The price as display text, with currency symbol |
| `extracted_price` | The same price as a number |
| `product_id` | An ID for each product, usable as a key to store it under |
| `rating`, `reviews` | Star rating and review count |
| `link` | The Google Shopping product page |

The full results also carry `product_token`, `thumbnail`, `extensions` and `rank_absolute`; they're cut here for length. Store `extracted_price` for arithmetic and keep `price` only if you need the display string. Note that the two results above come from different sellers, so a price in one row isn't the price of the same offer in the next.

## How do you track prices for 500 products every day?

The endpoint answers a search; it doesn't track anything on its own. A price tracker needs a product list, a daily loop, a store for history and a retry rule around it. Run one search per product, pick the matching result, and write `product_id`, `source`, `extracted_price` and the date to a table.

This script does that for a list of queries. It keeps the first result as the match, which is a shortcut: for products with common names, match on `title` or a stored `product_id` instead.

```python
import os
import time
import requests

API = "https://api.perceptlayer.com/v1/google-shopping/search"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}

def fetch(query, tries=3):
    params = {"q": query, "gl": "us", "hl": "en"}
    for _ in range(tries):
        r = requests.get(API, params=params, headers=HEADERS, timeout=30)
        if r.status_code == 200:
            return r.json()
        if r.status_code in (429, 503):
            time.sleep(int(r.headers.get("Retry-After", "5")))
            continue
        r.raise_for_status()
    return None

def daily_prices(queries):
    rows = []
    for q in queries:
        data = fetch(q)
        results = (data or {}).get("shopping_results", [])
        if not results:
            continue
        top = results[0]
        rows.append((q, top["product_id"], top["source"], top["extracted_price"]))
    return rows
```

The [requests library](https://requests.readthedocs.io/) handles the HTTP. Rate-limited (429) and temporarily unavailable (503) responses carry a `Retry-After` header with the seconds to wait, and the loop honours it. There is no idempotency key, so a call that timed out on your side may still have been billed; [retrying without paying twice](https://perceptlayer.com/blog/retry-web-api-calls-without-paying-twice) covers how to handle that. For results beyond the first page, see [paginating a web data API safely](https://perceptlayer.com/blog/paginate-web-data-api-python), using `next_start` from `pagination` as the next `start`.

## What does tracking 500 products a day cost?

Tracking 500 products once a day costs 500 credits a day, because each product is one search at 1 credit. Over 30 days that is 500 × 30 = 15,000 credits. The arithmetic scales linearly, so doubling the list or checking twice a day doubles the credits.

| Plan of calls | Calls | Credits |
| --- | --- | --- |
| 500 products, once a day, 1 day | 500 | 500 |
| 500 products, once a day, 30 days | 15,000 | 15,000 |
| 500 products, once a day, 365 days | 182,500 | 182,500 |
| 500 products, twice a day, 30 days | 30,000 | 30,000 |

The 1,000 free credits every month cover two daily runs of 500 products. A month of daily checks, 15,000 credits, is more than the 10,000-credit Starter pack and fits inside the 50,000-credit Build pack with 35,000 left over. A full year at 182,500 credits fits inside the 200,000-credit Growth pack. Purchased credits last 12 months, there's no subscription, and [pricing](https://perceptlayer.com/pricing) shows what credits cost. The [credits docs](https://docs.perceptlayer.com/credits) explain how debits work; failed calls return `X-Credits-Used: 0`.

Rate limits are per account. Free accounts get 1 request a second, so 500 sequential calls take roughly 500 seconds. Paying accounts run at 5 requests a second at least, which brings the same loop to about 100 seconds. Details are in the [rate limits docs](https://docs.perceptlayer.com/rate-limits).

## What should you check before trusting a price?

Treat each stored price as an observation: this query, this country, this device, this moment. It isn't a fixed fact about the product, because sellers, variants and countries change what a search returns. Three habits make the stored history usable for comparison over time.

-   Log `search_parameters` with every row, so a change in `gl` or `device` isn't mistaken for a price move.
-   Compare on `product_id` and `source`, not on rank. Position changes without any price change.
-   Alert on large jumps instead of acting on them. A result can be a different variant, so check `title` when a price moves sharply.

Errors arrive as an HTTP status with a JSON body holding `code`, `message` and `request_id`. Handle `invalid_parameters` (422) by fixing the request, and `insufficient_credits` (402) by topping up, since nothing else is debited when the balance reaches zero. The [errors docs](https://docs.perceptlayer.com/errors) list every code.

If you're building an agent rather than a pipeline, the same endpoint is available as a tool through the MCP server; see the [AI agents docs](https://docs.perceptlayer.com/ai-agents). For sibling Google endpoints, the guides to [Google Hotels prices](https://perceptlayer.com/blog/google-hotels-api) and [Google Flights fares](https://perceptlayer.com/blog/google-flights-api) follow the same pattern. Next step: run the iPhone query in the [Google Shopping playground](https://perceptlayer.com/apis/google-shopping), then swap in your own first product.

## APIs in this post

-   [Google Shopping **1 credit per call** · 1 endpoint](https://perceptlayer.com/apis/google-shopping)

## Frequently asked questions

### Does the Google Shopping API return prices from several sellers?

Each item in `shopping_results` has a `source` field naming the seller and a `price` for that listing. In the recorded response, one result came from Walmart and another from Best Buy. Search for a product and read the results to compare sellers; the endpoint returns what Google Shopping shows for that query at call time.

### How much does one Google Shopping API call cost?

A successful call costs 1 credit, and a failed call costs nothing. Every response carries `X-Credits-Used` and `X-Credits-Remaining` headers, so you can track spend per call. Accounts get 1,000 free credits every month after verifying an email address, with no credit card. See [pricing](https://perceptlayer.com/pricing) for what credit packs cost.

### Can I get prices for a specific country?

Yes. Set `gl` to a two-character country code and `hl` to a language code, and use `location` or `uule` for a more specific place. Keep these the same across runs, because the same product can show different prices and sellers in different countries. The response echoes the values in `search_parameters`.

### How do I get the next page of results?

Pass `start` with the `next_start` value from the previous response's `pagination` object. The recorded response ran with `start` 0 and returned `next_start` 10. Page sizes aren't documented, so read `next_start` from each response instead of assuming a step. The [Google Search guide](https://perceptlayer.com/blog/google-search-api-json) shows a similar loop.

### What happens when I hit the rate limit?

You get a 429 `rate_limited` response with a `Retry-After` header giving the seconds to wait. Limits are per account and counted per minute: free accounts get 60 requests a minute, and paying accounts at least 300. Wait for `Retry-After`, then retry; a rate-limited call isn't billed.

google shopping price monitoring ecommerce product data json

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 2 Oct 2026 Perceptlayer 6 min read
    
    ## [AliExpress Product API: Search, Reviews and Shipping](https://perceptlayer.com/blog/aliexpress-api-product-search-reviews)
    
    Chain AliExpress search, product, product-reviews and product-shipping, with every required parameter, at 1 credit per call, and cost a 100-product review pull.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 22 Oct 2026 Perceptlayer 9 min read
    
    ## [Idealo API: Compare Product Prices Across Shops as JSON](https://perceptlayer.com/blog/idealo-api-price-comparison-json)
    
    Search idealo.de by keyword, then pass a product\_id to the offers endpoint. Endpoints, parameters, a real search response and the cost at 1 credit per call.
    
3.  [API guides](https://perceptlayer.com/blog/category/api-guides) 16 Oct 2026 Perceptlayer 7 min read
    
    ## [Kleinanzeigen API: Search German Classifieds as JSON](https://perceptlayer.com/blog/kleinanzeigen-api-search-json)
    
    Search Kleinanzeigen ads by query, city, category and price range with one GET call. Parameters, a real response and the cost: 1 credit per call.
