# Google Shopping Scraper - Prices, Merchants, Ratings (`webdata_labs/google-shopping-scraper`) Actor

\[💵 $2.50 / 1K] Scrape Google Shopping search results: price, original price, discount, merchant, rating, reviews, delivery and Google's product ID. 26 countries, no start fee. Every row is ranked against its own query, so you see the cheapest offer without a second pass.

- **URL**: https://apify.com/webdata\_labs/google-shopping-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Google Shopping Scraper

**Scrape Google Shopping search results into a price-ranked table: price, original price, discount, merchant, rating, reviews and delivery, for 26 countries.**

Google Shopping is the widest price comparison surface on the web, and it is the one you cannot export. The grid loads through obfuscated markup, half the tiles are promo cards, prices arrive as locale-formatted strings, and there is no product ID you can join on. So teams end up eyeballing the page, or paying per row for a scraper that hands back the same unranked strings the page showed. This Actor returns clean typed rows with Google's own product ID on every one, and it ranks each product against the rest of its own query before you ever open the file, so "is this cheap" is answered in the data instead of in a spreadsheet you build afterwards.

### ✅ What you get / ❌ what this isn't

| ✅ What you get | ❌ What this isn't |
|---|---|
| `priceValue` as a real number plus the ISO `currency` for the storefront | Not a locale-formatted string like `1.234,50 €` you have to parse yourself |
| `priceRank`, `medianPriceValue`, `priceVsMedianPercent` and `isLowestPrice` per query | Not a flat list you have to sort and compare on your own |
| `productId` and `variantId`, Google's own identifiers | Not anonymous rows you cannot dedupe or track week over week |
| `originalPrice` and `discountPercent` on every discounted row | Not a single price field that hides whether it is a sale |
| Filters applied before rows are written, so you are billed only for matches | Not billing for every tile scanned regardless of your filters |
| Only tiles that carry a real price and merchant | Not padded with promo cards, "related searches" and empty carousel tiles |
| No start fee, ever | Not a per-run charge on top of the per-result price |

### 🔎 Why use this Actor

- **Price ranked in the row.** Every product carries its rank among the results for the same query, the median price of that query, and how far above or below the median it sits. One number tells you whether a listing is a deal.
- **Same-currency comparison only.** Ranking groups rows by ISO currency, so a multi-country project never ranks a euro price against a dollar one.
- **Class-independent parsing.** Google reshuffles its CSS class names without notice. Every field here hangs off a structural or accessibility hook that exists because the page has to work for screen readers, not off a class name that expires.
- **Locale-correct numbers.** German `11.666` is 11666 reviews, not 11.666. `1,4 Tsd.` is 1400. `59,99 €` is 59.99 EUR. All of it is unit tested against real captured pages.
- **The currency comes from the storefront.** A bare `$` on google.com.au is AUD, not USD, so the currency code is taken from the country you searched instead of guessed from the symbol.
- **You pay for matches, not for scans.** Google's own Shopping filters stopped working from the URL, so filtering runs on parsed rows here. Because rows are dropped before they reach the dataset, a narrow filter makes your run cheaper rather than more expensive.
- **A challenge is never reported as "no results".** Google answers a suspect request with an HTTP 200 that has no products in it. That page is retried on a fresh proxy session instead of being written out as an empty result.

### 👥 Who it's for

E-commerce sellers, brand managers and repricing teams who need to know what a product actually sells for across merchants, plus anyone building a price-comparison feed.

- Track your own SKUs against every merchant Google lists them under, weekly.
- Find which merchant is undercutting you and by how much, using `priceRank` and `priceVsMedianPercent`.
- Build a deals feed by scraping with `onSaleOnly` and sorting by `discount`.
- Pull a market price band before setting your own price on a new product line.
- Feed `productId` into your warehouse as a stable join key across runs.

### Example tasks

Each of these is a ready-made configuration you can open, copy and run:

- [Compare Google Shopping prices for any product keyword](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-price-comparison) - the plain price comparison, sorted cheapest first.
- [Find the cheapest Google Shopping offer for a product](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-cheapest-price-finder) - one product, every offer, ranked.
- [Build a feed of discounted Google Shopping products](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-deals-and-discounts) - discounted products only, biggest saving first.
- [Scrape Google Shopping prices for electronics](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-electronics-prices) - electronics, filtered to well-reviewed products.
- [Scrape UK Google Shopping prices in GBP](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-uk-prices) - the UK storefront.
- [Google Shopping Preise für Deutschland scrapen](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-preise-deutschland) - the German storefront, in EUR.
- [Monitor competitor prices on Google Shopping weekly](https://apify.com/webdata_labs/google-shopping-scraper/examples/google-shopping-competitor-price-monitoring) - your SKUs at the merchants you name, built to schedule.

### ⚙️ How to scrape Google Shopping prices

1. Enter one or more product keywords in **Search queries**. Each one is scraped and priced independently.
2. Pick a **Country**. The prices, merchants and currency all follow that storefront.
3. Set **Max products per query**. Google itself runs out at roughly 120 products per query, so leaving it at 0 gets you everything Google will serve.
4. Optionally narrow with **Minimum/Maximum price**, **Minimum rating**, **Minimum review count**, **Discounted products only**, **Free delivery only** or **Only these merchants**.
5. Choose **Sort results by**. Sorting is applied to the output, and `position` still holds Google's own relevance rank.
6. Click **Start**. Results appear on the run's Output tab and export to JSON, CSV, Excel, XML or Parquet.

#### Track prices on a schedule

Save your input as a Task, then add a Schedule to it (daily or weekly). Each run writes a fresh dataset stamped with `scrapedAt`. Because `productId` is stable, joining last week's dataset to this week's on `productId` gives you a price history per product with no extra work, including which merchant moved.

### 📥 Input

```json
{
  "searchQueries": ["wireless earbuds", "noise cancelling headphones"],
  "country": "us",
  "maxResultsPerQuery": 60,
  "sort": "price_low",
  "minPrice": 40,
  "maxPrice": 250,
  "minRating": 4,
  "minReviewCount": 100,
  "onSaleOnly": false,
  "freeShippingOnly": false,
  "merchants": []
}
````

- `searchQueries` - product keywords, up to 50 per run. Each query is paged, deduped and price-ranked on its own.
- `country` - one of 26 Google Shopping storefronts, from `us` and `gb` to `de`, `br`, `jp` and `tr`. Sets the domain, the default language and the reported currency.
- `language` - optional two-letter code. Defaults to the country's own language.
- `maxResultsPerQuery` - matching products per query. `0` means no cap. Default `60`.
- `sort` - `relevance`, `price_low`, `price_high`, `rating`, `reviews` or `discount`. Default `relevance`.
- `minPrice` / `maxPrice` - optional price bracket, in the storefront's currency.
- `minRating` - optional star floor, 0 to 5. Unrated products are excluded when this is set.
- `minReviewCount` - optional review floor.
- `onSaleOnly` - optional. Only products with a struck-through price or a percent-off badge.
- `freeShippingOnly` - optional. Only products whose delivery chip says delivery is free.
- `merchants` - optional list of merchant name fragments, matched case and accent insensitive.

### 📤 Output

| title | price | priceValue | originalPrice | discountPercent | merchant | priceRank | priceVsMedianPercent | rating | reviewCount |
|---|---|---|---|---|---|---|---|---|---|
| JBL Vibe Beam 2 True Wireless Noise Cancelling Earbuds | $41.99 | 41.99 | $65 | 35 | Best Buy | 1 | -65 | 4.2 | 1400 |
| Bose QuietComfort Earbuds | $149.00 | 149 | $179 | 16 | Lenovo | 16 | 25 | 4.2 | 4600 |
| Google Pixel Buds Pro 2 | $199.99 | 199.99 | null | null | Google Store | 21 | 67 | 4.4 | 3300 |

Every row also carries `productId` and `variantId` (Google's own identifiers), `productUrl` (the Google product page for the run's locale), `currency`, `originalPriceValue`, `onSale`, `multipleMerchants` (whether Google lists other sellers for the same product), `delivery` and `freeDelivery`, `returnsPolicy`, `nearby` (local stock), `badges` (the remaining chips Google showed, such as `SALE` or `In shop`), `imageUrl`, `medianPriceValue`, `isLowestPrice`, `comparedProducts`, `position` (Google's relevance rank), `page`, `query`, `country`, `language` and `scrapedAt`.

### 💵 How much does it cost?

**$2.50 per 1,000 products** on the free tier, dropping with your Apify plan, and **no start fee**. You pay per product row written to the dataset, which means per product that passed your filters - the tiles that get scanned and rejected are free, and so are the promo and carousel cards that never become rows. A default 60-product run costs about $0.15. Scraping one query to Google's ceiling of roughly 120 products costs about $0.30.

### 🔁 Run it on the Apify platform

Schedule this Actor daily or weekly from the Apify Scheduler, call it from the REST API or the JavaScript and Python clients, and export results as JSON, CSV, Excel, XML or Parquet. Webhooks fire on run completion so you can push new prices straight into your own pipeline, and the built-in integrations connect it to Google Sheets, Make, Zapier, Slack and any HTTP endpoint without glue code.

### ⚠️ Limits and caveats

- **Google serves about 120 products per query, and no more.** Its Shopping grid stops returning new tiles a little past a result index of 60, and this Actor reaches that ceiling in three requests. If you need more coverage, split the topic into several narrower queries rather than raising the cap.
- **Filters are applied after extraction, not by Google.** Google's legacy Shopping filter parameters are accepted with a 200 and then ignored on its current surface, verified 2026-07-26. So a narrow filter cannot reach deeper inventory than those ~120 products; it selects from within them.
- **`imageUrl` is populated for roughly half the rows.** Google inlines the first screenful of images as base64 data instead of URLs. Rather than bloat every row with embedded image data, the field is left null there. `productUrl` always works.
- **`delivery` and `returnsPolicy` are classified for English, German, French, Spanish, Italian, Dutch, Portuguese and Polish.** For other storefronts those chips still arrive verbatim in `badges`, just not split into their own fields.
- **`merchant` is the merchant Google chose to show, not the cheapest.** When `multipleMerchants` is true, other sellers list the same product; open `productUrl` for the full offer list.
- **A price is a moment, not a fact.** Google caches merchant feeds, so a price can lag the merchant's own site by hours. `scrapedAt` records when the row was taken.
- **Sponsored tiles are not marked separately.** Google did not label them as ads in the pages captured for this Actor, so no `isSponsored` field is claimed.

### 🧩 Related Actors

- **Google Search Results Scraper** - pull the organic SERP for the same keywords when you need the ranking context around a product, not just the offers.
- **eBay Listings Scraper** - compare Google Shopping's retail prices against live eBay asking prices for the same item.
- **Mercari Sold Comps Scraper** - anchor the same product against what people actually paid on the secondhand market.
- **Website Contact Extractor** - turn the merchant names from a run into contactable suppliers.
- **Lead List Deduplicator** - merge several runs into one clean file before handing it to a client.

### ❓ FAQ

**Am I charged for products that my filters reject?** No. Filtering happens before rows are written, and billing is per written row. A narrow filter makes a run cheaper.

**Can I get more than 120 products for one keyword?** Not from Google. Its Shopping grid stops serving new tiles past that point. Splitting one broad keyword into several specific ones is the way to widen coverage.

**Which countries are supported?** 26 storefronts: US, UK, Canada, Australia, Ireland, India, Germany, Austria, Switzerland, France, Belgium, Netherlands, Spain, Italy, Portugal, Poland, Sweden, Denmark, Norway, Brazil, Mexico, Japan, Singapore, New Zealand, South Africa and Turkey. Each one sets its own currency.

**Does it return the seller's own product URL?** It returns `productUrl`, the Google product page, which lists every merchant offer for that product. Google does not put merchant links in the grid HTML, so a direct merchant URL is not available from a search page.

**How do I track a price over time?** Schedule the Actor and join runs on `productId`, which is Google's own stable identifier. `scrapedAt` on every row gives you the timestamp.

**Why is `rating` sometimes empty?** Not every product on Google Shopping has reviews. An empty rating means Google showed none, and it is reported as null rather than as a zero.

### 🛠️ Support

Something wrong or missing? Open an issue on the Actor's Issues tab with the run URL, the input you used and what you expected instead. Parser fixes for Google layout changes are the priority.

### ⭐ Rate this Actor

If this saved you an afternoon, please leave a review on the Reviews tab. Review count is the main trust signal buyers have on the Apify Store, and reviews are what decide which fields and countries get built next. If something is broken, please open an issue first so it can be fixed - that is faster for you than a low rating, and it keeps the Actor useful for everyone.

# Actor input Schema

## `searchQueries` (type: `array`):

Product keywords to search Google Shopping for. Each query is paged through independently, priced against its own results, and tagged with the query it came from.

## `country` (type: `string`):

Which Google Shopping storefront to search. Prices, merchants and the reported currency all follow the country you pick.

## `language` (type: `string`):

Two-letter language code for the results page. Leave empty to use the default language of the country you chose.

## `maxResultsPerQuery` (type: `integer`):

How many matching products to return per query. Set 0 for no limit. Google itself stops at roughly 120 products per query, so a higher number just ends early. You are billed per returned product.

## `sort` (type: `string`):

How the returned rows are ordered. Sorting is applied after extraction, so every row still carries Google's own relevance rank in the `position` field.

## `minPrice` (type: `integer`):

Drop products priced below this, in the currency of the country you chose. Useful for cutting accessory and knock-off noise out of a search.

## `maxPrice` (type: `integer`):

Drop products priced above this, in the currency of the country you chose. Useful for holding a search to one price bracket.

## `onSaleOnly` (type: `boolean`):

Only return products Google shows with a struck-through original price or a percent-off badge.

## `freeShippingOnly` (type: `boolean`):

Only return products whose delivery chip says delivery is free.

## `minRating` (type: `integer`):

Only return products rated at least this many stars out of 5. Unrated products are excluded when this is set.

## `minReviewCount` (type: `integer`):

Only return products with at least this many reviews. Filters out listings with too little feedback to trust.

## `merchants` (type: `array`):

Only return products sold by merchants whose name contains one of these strings, case and accent insensitive. Leave empty for all merchants.

## Actor input object example

```json
{
  "searchQueries": [
    "wireless earbuds"
  ],
  "country": "us",
  "maxResultsPerQuery": 60,
  "sort": "relevance",
  "onSaleOnly": false,
  "freeShippingOnly": false
}
```

# Actor output Schema

## `products` (type: `string`):

No description

## `priceComparison` (type: `string`):

No description

## `deals` (type: `string`):

No description

## `allFields` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "wireless earbuds"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/google-shopping-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchQueries": ["wireless earbuds"] }

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/google-shopping-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "wireless earbuds"
  ]
}' |
apify call webdata_labs/google-shopping-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=webdata_labs/google-shopping-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Shopping Scraper - Prices, Merchants, Ratings",
        "description": "[💵 $2.50 / 1K] Scrape Google Shopping search results: price, original price, discount, merchant, rating, reviews, delivery and Google's product ID. 26 countries, no start fee. Every row is ranked against its own query, so you see the cheapest offer without a second pass.",
        "version": "0.1",
        "x-build-id": "6HtVO7yuOgXrf8d1J"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/webdata_labs~google-shopping-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-webdata_labs-google-shopping-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/webdata_labs~google-shopping-scraper/runs": {
            "post": {
                "operationId": "runs-sync-webdata_labs-google-shopping-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/webdata_labs~google-shopping-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-webdata_labs-google-shopping-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "searchQueries"
                ],
                "properties": {
                    "searchQueries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Product keywords to search Google Shopping for. Each query is paged through independently, priced against its own results, and tagged with the query it came from.",
                        "default": [
                            "wireless earbuds"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "us",
                            "gb",
                            "ca",
                            "au",
                            "ie",
                            "in",
                            "de",
                            "at",
                            "ch",
                            "fr",
                            "be",
                            "nl",
                            "es",
                            "it",
                            "pt",
                            "pl",
                            "se",
                            "dk",
                            "no",
                            "br",
                            "mx",
                            "jp",
                            "sg",
                            "nz",
                            "za",
                            "tr"
                        ],
                        "type": "string",
                        "description": "Which Google Shopping storefront to search. Prices, merchants and the reported currency all follow the country you pick.",
                        "default": "us"
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Two-letter language code for the results page. Leave empty to use the default language of the country you chose."
                    },
                    "maxResultsPerQuery": {
                        "title": "Max products per query",
                        "minimum": 0,
                        "type": "integer",
                        "description": "How many matching products to return per query. Set 0 for no limit. Google itself stops at roughly 120 products per query, so a higher number just ends early. You are billed per returned product.",
                        "default": 60
                    },
                    "sort": {
                        "title": "Sort results by",
                        "enum": [
                            "relevance",
                            "price_low",
                            "price_high",
                            "rating",
                            "reviews",
                            "discount"
                        ],
                        "type": "string",
                        "description": "How the returned rows are ordered. Sorting is applied after extraction, so every row still carries Google's own relevance rank in the `position` field.",
                        "default": "relevance"
                    },
                    "minPrice": {
                        "title": "Minimum price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Drop products priced below this, in the currency of the country you chose. Useful for cutting accessory and knock-off noise out of a search."
                    },
                    "maxPrice": {
                        "title": "Maximum price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Drop products priced above this, in the currency of the country you chose. Useful for holding a search to one price bracket."
                    },
                    "onSaleOnly": {
                        "title": "Discounted products only",
                        "type": "boolean",
                        "description": "Only return products Google shows with a struck-through original price or a percent-off badge.",
                        "default": false
                    },
                    "freeShippingOnly": {
                        "title": "Free delivery only",
                        "type": "boolean",
                        "description": "Only return products whose delivery chip says delivery is free.",
                        "default": false
                    },
                    "minRating": {
                        "title": "Minimum rating",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Only return products rated at least this many stars out of 5. Unrated products are excluded when this is set."
                    },
                    "minReviewCount": {
                        "title": "Minimum review count",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only return products with at least this many reviews. Filters out listings with too little feedback to trust."
                    },
                    "merchants": {
                        "title": "Only these merchants",
                        "type": "array",
                        "description": "Only return products sold by merchants whose name contains one of these strings, case and accent insensitive. Leave empty for all merchants.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
