# Google Shopping Scraper — Prices, Sellers & Offers (`cheapapi/google-shopping-scraper`) Actor

Google Shopping scraper: products, prices, old prices, sellers & all store offers for price comparison, ratings, reviews, delivery. Any country.

- **URL**: https://apify.com/cheapapi/google-shopping-scraper.md
- **Developed by:** [CheapAPI](https://apify.com/cheapapi) (community)
- **Categories:** E-commerce, SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Shopping Scraper — Prices, Sellers & Offers

Scrape Google Shopping products, prices, discounts, ratings and **every store's offer for a product** (price comparison) in any country — clean JSON, CSV or Excel, no proxies or setup needed.

**Why this Actor**

- **From $2.00 per 1,000 products** (Gold plan and above; $2.40 on other plans), no start fee. Apify platform usage is billed separately.
- **Price comparison built in:** every store selling a product (up to 200) with price, shipping, total price, condition and availability.
- **30+ fields per product:** title, price, old price, seller, rating, reviews, delivery, number of stores, product ID, links, images.
- **Price monitoring built in:** schedule runs and get `previousPrice`, `priceChange` and `isNew`, or only the prices that changed (see Pricing).
- **Any of 249 countries**, any language, city-level or GPS location, price filters and sorting.

**Store links:** search rows link to the Google Shopping product page (`googleShoppingUrl`); the store's own page (`url`) is usually `null` there, because Google rarely links it in search results. For store links, use the **Seller offers** mode (or *Seller offers for the first N products* in search mode): every offer row has the store's `url`.

**Not included:** product reviews (individual review texts), historical price charts from Google, and sellers' stock quantities. Price history starts with your first monitored run.

### Compared with alternatives

Typical run: **1,000 products from Google Shopping searches in one run**, all Actor fees included (start fees too). Apify platform usage is not included in these numbers.

| Alternative (Apify Store) | Pricing | Free plan | Gold plan |
|---|---|---|---|
| Most-used Google Shopping Actor (~990 users) | $0.02 per result on Free, $0.005 on paid plans, + $0.008 start fee (per GB of memory, 1 GB counted) | $20.01 | $5.01 |
| Second most-used (~900 users) | $0.0035 per result, all plans | $3.50 | $3.50 |
| Tiered-price Actor (~430 users) | $0.011364 per product on Free, $0.005929 on Gold, + $0.035 / $0.0263 start fee | $11.40 | $5.96 |
| Lightweight search Actor (~24 users), its "light search" rows (a lighter row format) | $0.001 per row + $0.006 start fee | $1.01 | $1.01 |
| Per-page Actor (~160 users) | $0.02 per results page of about 40 products ($0.0194 on Gold), + $0.02 setup fee + $0.00001 per row | $0.53 | $0.52 |
| **This Actor** | $0.0024 per product ($0.0020 on Gold and above), no start fee, + Apify platform usage | **$2.40** | **$2.00** |

Seller offers (price comparison) for **100 products, 20 offers each**:

| Alternative (Apify Store) | Pricing | Free plan | Gold plan |
|---|---|---|---|
| EAN/SKU offer Actor (~560 users) | $0.02 per product row on Free, $0.015 on Gold | $2.00 | $1.50 |
| **This Actor** | $0.004 per product + $0.0005 per offer ($0.00032 on Gold), + Apify platform usage | **$1.40** | **$1.04** |

The tiered-price Actor is cheaper on Platinum ($3.97) and Diamond ($2.78) than on Gold; this Actor is still below that. **We are not the cheapest for plain search listings:** the lightweight and per-page Actors above cost less per 1,000 products. They are good choices if you only need basic listings; this Actor adds seller offers, product details and price monitoring in one place, with 30+ fields per product.

The totals compare the Actors' own fees. For this Actor, Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); check each alternative's Store listing for how it bills platform usage. Prices from public Apify Store listings, checked September 2026.

### What data you get

Every dataset row has a `rowType`: `product` (a search result), `offer` (one seller of a product) or `productDetails`.

**Products (`rowType: "product"`)**

| Field | Type | Example |
|---|---|---|
| `searchTerm` | string | `"wireless earbuds"` |
| `position` | integer | `2` |
| `title` | string | `"Apple AirPods Pro 3"` |
| `price` / `oldPrice` | number | `219.99` / `249` |
| `currency` | string | `"USD"` |
| `seller` | string | `"Best Buy"` |
| `rating` / `ratingMax` | number | `4.7` / `5` |
| `reviewsCount` | integer | `12000` |
| `delivery` / `deliveryPrice` | string / number | `"Free delivery"` / `0` |
| `storesCount` | integer | `12` |
| `productId`, `gid`, `offerDocId` | string | `"11504754468308736293"` |
| `googleShoppingUrl`, `url` | string | Google Shopping product page (always); store page (`url`) only when Google links it directly — usually `null` in search results, so use seller offers for store links |
| `image`, `images` | string, array | product photos |
| `isSponsored`, `resultType` | boolean, string | `false`, `"organic"` |
| `tags`, `description`, `specifications`, `specialOffer`, `storeRating` | various | when Google shows them |
| `pricePerMonthMultiplier` | number | `24` when Google shows an instalment price such as "$29/mo for 24 mo" (then `price` is the per-payment amount); `null` otherwise |
| `storeRating` / `storeRatingMax` / `storeReviewsCount` | number / number / integer | the store's rating, its scale and number of store reviews |
| `deliveryPriceText` | string | delivery price exactly as Google displays it (text) |
| `isBestMatch` | boolean | `true` when Google marks the product as best match |
| `carouselTitle` | string | name of the carousel a product came from (sponsored or extra carousels), `null` for regular results |
| `searchUrl` | string | the Google Shopping page the products were read from |

**Seller offers (`rowType: "offer"`)**: `productTitle`, `productId`, `gid`, `productImage`, `productUrl`, `productRating` / `productRatingMax` / `productReviewsCount` (the product's own rating), `productPosition` and `searchTerm` (when the offers come from a search), `position`, `seller`, `sellerDomain`, `title` (the seller's listing title), `price`, `oldPrice`, `shippingPrice`, `tax`, `totalPrice`, `currency`, `pricePerMonthMultiplier` and `paymentBreakdown` (instalment offers, as Google shows them), `condition`, `badge` (e.g. "SALE"), `availability`, `sellerRating` / `sellerRatingMax`, `sellerReviewsCount`, `isBuyOnGoogle` (sold through Google checkout), `offerDetails`, `url`.

**Product details (`rowType: "productDetails"`)**: `title`, `description`, `images`, `features`, `specifications` (group, name, value), `rating`, `reviewsCount`, `sellers` (store, price, old price, delivery, availability, rating), `sellersCount` (number of sellers listed), `sellerReviewsCount`, and the lowest `price` / `oldPrice` / `currency` with its `seller`.

All rows also have `country`, `language`, `location` and `scrapedAt`. Offer and details rows also have `input` (the product link or ID you entered, or the product title when the offers come from a search).

**Price monitoring fields** (only when *Track price changes* is on). Search rows track the price Google shows for the product, offer rows track each seller's `price`, and details rows track the lowest seller price.

| Field | Type | Example |
|---|---|---|
| `previousPrice` | number | `249.99` (the price saved in the last run, `null` for new items) |
| `priceChange` | number | `-30` (`price − previousPrice`) |
| `priceChangePct` | number | `-12` |
| `isNew` | boolean | `false` (`true` the first time this monitoring name sees the product or offer) |
| `priceStatus` | string | `"new"`, `"up"`, `"down"`, `"unchanged"`, `"changed"` (currency changed or first known price), `"unknown"` (no price shown this time) |

### How to use

1. Open the Actor and choose **What to scrape**: *Products from a search*, *Seller offers* or *Product details*.
2. Enter **search terms**, or for offers and details, **product links or IDs**. The `productId` column of a search run works as input.
3. Pick the **country** and **language**, and optionally the number of products per search.
4. Press **Start** and download the results as JSON, CSV, Excel or HTML, or use them through the API.

Ready-to-paste input:

```json
{
    "mode": "search",
    "searchTerms": ["wireless earbuds", "espresso machine"],
    "maxProductsPerSearch": 40,
    "country": "US",
    "language": "en",
    "sortBy": "priceLowToHigh",
    "minPrice": 20,
    "maxPrice": 300,
    "offersForTopProducts": 3
}
```

Daily price monitoring (schedule this input, only changes are delivered and charged):

```json
{
    "mode": "offers",
    "products": ["4485466949985702538", "1113158713975221117"],
    "country": "US",
    "language": "en",
    "monitorPrices": true,
    "onlyChangedPrices": true,
    "monitoringName": "my-phones-us",
    "minPriceChangePct": 1
}
```

Price comparison for known products:

```json
{
    "mode": "offers",
    "products": ["4485466949985702538", "https://www.google.com/search?ibp=oshop&q=iphone&prds=catalogid:1113158713975221117,pvo:3"],
    "maxOffersPerProduct": 20,
    "country": "GB",
    "language": "en"
}
```

**API: curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~google-shopping-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms":["wireless earbuds"],"country":"US","language":"en"}'
```

**API: JavaScript (`apify-client`)**

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

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/google-shopping-scraper').call({
    searchTerms: ['wireless earbuds'],
    country: 'US',
    language: 'en',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**API: Python (`apify-client`)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/google-shopping-scraper").call(run_input={
    "searchTerms": ["wireless earbuds"],
    "country": "US",
    "language": "en",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"], item["seller"])
```

### Use cases

- **Price monitoring and alerts:** schedule daily runs with *Only deliver new or changed prices* and get only the products and seller offers whose price moved, with `priceChange` and `priceChangePct`, and pay only for those rows.
- **Price comparison and repricing:** get every store selling a product with total prices, then find the cheapest seller or the Buy Box range.
- **Market and assortment research:** see which brands, stores and price points rank for a category search in each country.
- **MAP and reseller compliance:** spot sellers that advertise below your minimum advertised price.
- **Product catalog enrichment:** add specifications, images, features and ratings to your product database.
- **Shopping ads research:** include sponsored products to see who advertises on which searches.

### Advanced options

| Option | Default | Meaning |
|---|---|---|
| **Sort by** (`sortBy`) | `relevance` | `relevance`, `rating` (review score), `priceLowToHigh`, `priceHighToLow` |
| **Minimum / Maximum price** (`minPrice`, `maxPrice`) | none | Whole-number price range in the local currency |
| **Result pages to load** (`maxPages`) | automatic | 1–7 Google Shopping result pages per search |
| **Include sponsored products and ads** (`includeSponsored`) | `false` | Adds sponsored carousel products and shopping ads (`isSponsored: true`) |
| **Include product carousels** (`includeCarousels`) | `false` | Adds products from Google's extra carousels (deals, popular products) |
| **Extra Google URL parameters** (`extraUrlParameters`) | none | Raw Google Shopping URL parameters for any filter, e.g. `&tbs=mr:1,sales:1` |
| **Google Shopping search URLs** (`searchUrls`) | none | Paste search URLs with filters already applied in the browser |
| **Seller offers for the first N products** (`offersForTopProducts`) | `0` | In search mode, also collects all seller offers for the top N products of every search |
| **Offers per product** (`maxOffersPerProduct`) | `20` | 1–200 seller offers per product |
| **Include "Buy on Google" offers** (`includeBuyOnGoogle`) | `false` | Also checks offers sold through Google checkout (add-on price) |
| **Product variant filter** (`variantFilter`) | none | `pvf` value from a Google Shopping URL to target one exact variant |
| **Product variant specifications** (`productSpecifications`) | none | JSON object such as `{"Color": "Black"}` to match a variant. Filled in automatically for products from a search |
| **City or region** (`location`) | none | `City,Region,Country`, e.g. `Austin,Texas,United States`. Overrides country |
| **Coordinates** (`coordinates`) | none | `lat,lng` or `lat,lng,radius` in meters. Overrides city and country |
| **Google domain** (`googleDomain`) | automatic | e.g. `google.co.uk` |
| **Track price changes** (`monitorPrices`) | `false` | Saves the last price of every product and offer and adds `previousPrice`, `priceChange`, `priceChangePct`, `isNew`, `priceStatus` to rows |
| **Only deliver new or changed prices** (`onlyChangedPrices`) | `false` | Skips unchanged rows (not delivered, not charged). Adds a $0.004 price check per search or product lookup that returned data (the lookup minimum applies if it is higher). Turns on tracking automatically. The first run delivers everything |
| **Monitoring name** (`monitoringName`) | `default` | Each name keeps its own price history. Use one name per monitored list |
| **Minimum price change (%)** (`minPriceChangePct`) | `0` | Smaller moves count as unchanged. The last reported price is kept, so small moves that add up are still reported |
| **Processing speed** (`processingSpeed`) | `auto` | `auto` (fast for up to 50 requests, economy above), `fast` (about 1 min), `economy` (up to about 45 min). The price is the same for all three |
| **Maximum wait** (`maxWaitMinutes`) | `60` | Requests still unfinished after this time are reported in the run summary; each is charged only its lookup minimum (see Pricing), no rows |

### Output example

Example output. The rows below show the format that shows the format (values shortened; your results depend on the search, country and time of the run).

```json
{
    "rowType": "product",
    "searchTerm": "wireless earbuds",
    "position": 2,
    "resultType": "organic",
    "isSponsored": false,
    "title": "Apple AirPods Pro 3",
    "price": 219.99,
    "oldPrice": 249,
    "currency": "USD",
    "seller": "Best Buy",
    "rating": 4.7,
    "ratingMax": 5,
    "reviewsCount": 12000,
    "delivery": "Free delivery",
    "storesCount": 12,
    "productId": "11504754468308736293",
    "gid": "4728907421224624008",
    "offerDocId": "12672482923996492277",
    "googleShoppingUrl": "https://google.com/search?ibp=oshop&q=wireless+earbuds&prds=gpcid:4728907421224624008,headlineOfferDocid:12672482923996492277,catalogid:11504754468308736293,pvo:3,pvt:hg&hl=en&gl=US",
    "url": null,
    "image": "https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcRBe4UXglCc_cYBelj2Ob67YuHj4ex9R41dG_eBWGUnk7ZmEg63ZBndYTiDCv3sNvy_icidzgJWH-4G2sO2ADwWjjtwlv0e",
    "country": "US",
    "language": "en",
    "scrapedAt": "2026-09-28T16:02:18.200Z"
}
```

```json
{
    "rowType": "offer",
    "productId": "1113158713975221117",
    "productTitle": "Apple iPhone 8 Plus",
    "position": 2,
    "seller": "eBay",
    "sellerDomain": "www.ebay.com",
    "price": 200,
    "shippingPrice": null,
    "totalPrice": 200,
    "currency": "USD",
    "offerDetails": "Apple Iphone 8 Plus - 64gb - Gold (t-mobile) A1897 (gsm)",
    "availability": "in_stock",
    "isBuyOnGoogle": false,
    "url": "https://www.ebay.com/itm/355103005673?chn=ps&mkevt=1&mkcid=28&google_free_listing_action=view_item",
    "country": "GB",
    "language": "en",
    "scrapedAt": "2026-09-28T16:02:18.203Z"
}
```

With price monitoring on, rows also carry the monitoring fields, for example a seller offer that dropped in price:

```json
{
    "rowType": "offer",
    "productId": "1113158713975221117",
    "productTitle": "Apple iPhone 8 Plus",
    "seller": "Walmart - Wireless Source",
    "price": 119.99,
    "currency": "USD",
    "previousPrice": 124.99,
    "priceChange": -5,
    "priceChangePct": -4,
    "isNew": false,
    "priceStatus": "down",
    "scrapedAt": "2026-09-29T06:00:12.418Z"
}
```

A `RUN_SUMMARY` record in the key-value store lists counts, the processing speed used, any searches or products that returned nothing and, with monitoring on, how many prices were new, up, down or unchanged.

### Pricing

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

Pay per result, no start fee. Your plan's price is applied automatically. **Apify platform usage is billed separately by Apify** (at the default 256 MB a small run typically uses about $0.001–$0.005).

| Event | Free | Bronze | Silver | Gold, Platinum, Diamond |
|---|---|---|---|---|
| Product (from a search) | $0.0024 | $0.0024 | $0.0024 | $0.0020 |
| Product with seller offers (once per product) | $0.004 | $0.004 | $0.004 | $0.004 |
| Seller offer | $0.0005 | $0.00043 | $0.00039 | $0.00032 |
| Product details | $0.014 | $0.00405 | $0.00405 | $0.00405 |
| "Buy on Google" add-on (per started 10 offers, optional) | $0.003 | $0.003 | $0.003 | $0.003 |
| Price check (only with *Only deliver new or changed prices*, per search, product or details lookup that returned data) | $0.004 | $0.004 | $0.004 | $0.004 |
| Lookup minimum top-up (only when a lookup delivers less than its minimum, see below) | $0.0001 | $0.0001 | $0.0001 | $0.0001 |

**Why product details cost $0.014 on the Free plan but $0.00405 on paid plans:** Apify pays developers nothing for Free-plan usage, so on the Free plan this price only decides how much of your $0.25 monthly trial allowance each details record uses, and details use more because every record needs its own lookup; paid plans pay the regular $0.00405.

**Price monitoring pricing:** *Track price changes* is free. With *Only deliver new or changed prices*, unchanged rows are skipped and not charged, and you pay a $0.004 price check per search or product lookup that returned data (for products with more than 10 offers, the lookup minimum applies instead, see below).

**Lookup minimum.** Every lookup — one search, one product's seller offers or one product's details — costs us to collect even when it delivers nothing. Each lookup therefore has a minimum charge of **$0.0028**, plus **$0.0025 for each further unit** Google returned:

| Lookup | One unit is | Minimum for a typical lookup |
|---|---|---|
| Search | a started block of 40 results Google returned (incl. ads it returned that you filtered out) | $0.0028 (up to 40 results), $0.0053 (41–80), $0.0078 (81–120) |
| Seller offers | a started block of 10 offers Google returned; counted twice with *Buy on Google* offers | $0.0028 (up to 10 offers), $0.0053 (11–20), $0.0503 (191–200) |
| Product details | the product | $0.0028 |

If the other charges of a lookup (products, offers, details, price check) are already at or above its minimum — as in almost every normal run — nothing is added. If they are lower, the lookup is topped up to its minimum with `lookup-minimum` events of $0.0001. This happens when:

- a search or product returns **no results** (the lookup costs $0.0028 instead of $0);
- **Products per search** is 1, or the spending limit cut a search to 1 product (1 product + top-up = $0.0028);
- *Only deliver new or changed prices* finds **no change** for a product with more than 10 offers (price check $0.004 → $0.0053 for 11–20 offers);
- a request **failed or did not finish in time after it was sent** (charged the minimum, no rows).

The **maximum cost per run** always includes these top-ups: the Actor keeps enough of your limit for the minimum of every request it sends and never charges above the limit.

Worked examples:

- **1,000 products** from 25 searches cost **$2.40** (Free, Bronze or Silver) or **$2.00** (Gold and above). No top-ups: every search delivered 40 products.
- **All offers of 100 products**, 20 offers each (2,000 offers): 100 × $0.004 + 2,000 × $0.00032 = **$1.04** on Gold ($1.40 on Free).
- **Full details of 500 products** cost **$2.03** on a paid plan.
- **10 searches, 2 of them return no products:** 8 × 40 products × $0.0020 + 2 × $0.0028 minimum = **$0.6456** on Gold.
- **Daily monitoring of 200 products (5 searches × 40) with only changes delivered:** if 15 products changed price, that day costs 5 × $0.004 price checks + 15 × $0.0020 = **$0.05** on Gold. Unchanged products are free, and a day with no changes costs $0.02.
- **Daily offer monitoring of 50 products (up to 10 offers each) with only changes delivered:** if 3 products have 4 changed offers each, that day costs 50 × $0.004 + 3 × $0.004 + 12 × $0.00032 = **$0.22** on Gold. With 11–20 offers per product, each unchanged product costs its $0.0053 minimum instead of $0.004.

Set a **maximum cost per run** in the run options and the Actor stops before exceeding it.

### Integrations

- **Scheduling:** run daily or hourly from Apify Schedules to track prices over time.
- **Google Sheets, Excel, CSV:** export any run with one click, or use the Google Sheets integration.
- **Make, Zapier, n8n:** use the Apify apps to start runs and pass results to your workflows.
- **Webhooks:** receive a call when a run finishes and fetch the dataset automatically.
- **API and MCP:** use the REST API, the JavaScript or Python clients, or AI agents through Apify's MCP server.

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal to scrape Google Shopping?**
This Actor collects publicly visible product listings and prices, which are not personal data. You are responsible for using the data in line with applicable laws and Google's terms. If you are unsure, ask a lawyer.

**How fresh is the data?**
Every run collects live data from Google Shopping at the time of the run. `productDetails` rows also include `dataCollectedAt`.

**Why did I get fewer results than I asked for?**
Google shows fewer products for narrow searches or strict price filters, and many products have only a few sellers. With *Only deliver new or changed prices*, unchanged rows are left out on purpose. You pay for the rows you get; a lookup that returned nothing (or very little) costs only its lookup minimum, $0.0028 in most cases. The run summary lists searches or products that returned nothing.

**Why was I charged $0.0028 (or `lookup-minimum` events) for a search that returned nothing?**
Each search or product lookup has a small collection cost even when Google returns nothing, so it has a minimum charge: $0.0028, plus $0.0025 per further started block of 40 search results or 10 seller offers. When a lookup's products, offers, details and price check add up to less, `lookup-minimum` events of $0.0001 top it up to that minimum — for example 28 events ($0.0028) for an empty search, or 4 events ($0.0004) for a search that delivered 1 product at $0.0024. Lookups that deliver normally — at least 2 products per started block of 40 search results, all offers Google returned for a product, or a details record — are never topped up. The run summary shows the number of top-up events in `lookupMinimumTopUps`.

**Is Apify platform usage included?**
No. Apify bills platform usage (compute, storage) for this Actor separately. At the default 256 MB, a small run typically uses about $0.001–$0.005.

**How do I monitor prices over time?**
Turn on **Track price changes**, give the list a **Monitoring name** and create an Apify Schedule (for example daily) with the same input. Each run compares with the last saved prices for that name, country and language. Add **Only deliver new or changed prices** to receive and pay for only the rows whose price moved (plus a $0.004 price check per search or product looked up, or the lookup minimum when that is higher), and connect a webhook or Slack/email integration to be alerted. Tip: Google Shopping search results reshuffle between requests (in our September 2026 test, two searches for the same term 20 minutes apart returned five different top products, so every row counted as new). For reliable price monitoring, monitor fixed products — put their product IDs into **Seller offers** or **Product details** mode — and use search mode to discover them.

**How do I keep costs under control?**
Set **Maximum cost per run** in the run options. The Actor checks the limit before each request (keeping enough for each request's lookup minimum) and stops delivering before exceeding it. Lower **Products per search** or **Offers per product** to collect less. Apify platform usage is billed separately by Apify and is not part of this limit's Actor charges.

**Which export formats are available?**
JSON, CSV, Excel, XML, HTML table and RSS from the Console or the API, plus ready table views (*Products*, *Seller offers*, *Product details*, *Price changes*).

**How do I get the sellers of a product I found in a search?**
Either set **Seller offers for the first N products** in search mode, or copy the `productId` values into **Product links or IDs** and run the *Seller offers* mode. Links of opened Google Shopping products (with `catalogid:` or `/shopping/product/`), plain product IDs and `gid:`/`docid:` identifiers all work.

**Can I target a city, and are prices in local currency?**
Yes. Use **City or region** (for example `Chicago,Illinois,United States`) or **Coordinates**. Prices and the `currency` field follow the chosen country or location. No proxies or Google account are needed.

**How fast is it?**
Runs with up to 50 searches or products usually finish in about a minute. Larger runs use economy processing, which can take up to about 45 minutes, and are sent in batches of 100 so results appear in the dataset early.

**How do I get support or request a feature?**
Open an issue in the Actor's **Issues** tab on Apify. We read every issue in the Issues tab and fix reported problems. Please include the run ID.

### Limitations

- Google decides which fields it shows. Some products have no rating, old price or delivery information, and those fields are `null`.
- A product search returns at most about 120 products. For more, use several related searches or price ranges.
- Seller offers are limited to 200 per product, and not every product has a seller list on Google.
- Price filters accept whole numbers only.
- "Buy on Google" checkout offers exist only in a few countries.
- Results can vary slightly between runs, because Google personalizes and tests its Shopping layout.
- Price monitoring compares with the last saved price for each product or offer. Several listings from the same marketplace seller for one product are matched in price order, so a reshuffle between them can show as two small changes. Items not seen for 180 days are forgotten.

### Privacy

The Actor collects product and store information that Google Shopping shows publicly. It does not collect personal data about shoppers. Marketplace seller names are returned as Google displays them. If you process data about individual sellers, make sure you have a lawful basis under GDPR or similar laws.

# Actor input Schema

## `mode` (type: `string`):

<b>Products from a search</b>: one row per product Google Shopping shows for your search terms. <b>Seller offers</b>: one row per store selling a product (price, shipping, total price, condition). <b>Product details</b>: one row per product with description, images, specifications and its sellers.

## `searchTerms` (type: `array`):

What you would type into Google Shopping, one per line. Used by the <b>Products from a search</b> mode.

## `products` (type: `array`):

Used only in the <b>Seller offers</b> and <b>Product details</b> modes (ignored in search mode): Google Shopping product links (copy the address of an opened product) or product IDs, one per line, e.g. <code>4485466949985702538</code>. Tip: the <code>productId</code> column of a search run works directly. Also accepted: <code>gid:123…</code> and <code>docid:123…</code>.

## `maxProductsPerSearch` (type: `integer`):

Maximum products to collect for each search term (Google shows about 40 per page; up to 120). You pay per product delivered. Each search has a minimum charge of $0.0028 (+$0.0025 per further started block of 40 results Google returns): a search that delivers less (e.g. 0 products, or 1 product with this set to 1) is topped up to it (<code>lookup-minimum</code>, see Pricing).

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

Country to shop in — prices, stores and currency follow it.

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

Language code for Google Shopping, e.g. <code>en</code>, <code>de</code>, <code>fr</code>, <code>pt-BR</code>.

## `sortBy` (type: `string`):

Order of the products in the search results.

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

Only products priced at or above this amount (whole number, in the local currency of the chosen country).

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

Only products priced at or below this amount (whole number, in the local currency).

## `maxPages` (type: `integer`):

Optional. How many Google Shopping result pages to load per search (1–7). Normally not needed — “Products per search” controls the depth.

## `includeSponsored` (type: `boolean`):

Also return products from sponsored carousels and shopping ads (marked <code>isSponsored: true</code>). Each one counts as a product.

## `includeCarousels` (type: `boolean`):

Also return products from Google’s extra carousels on the results page (e.g. deals, popular products). Each one counts as a product.

## `searchUrls` (type: `array`):

Instead of search terms, paste Google Shopping search URLs (with any filters already applied in the browser). Search terms are read from the <code>q</code> parameter.

## `extraUrlParameters` (type: `string`):

Raw Google Shopping URL parameters for any filter Google offers, e.g. <code>\&tbs=mr:1,sales:1</code> (on sale). For experts.

## `offersForTopProducts` (type: `integer`):

Products from a search mode only: also collect all seller offers for the first N products of every search (0 = off). Offers are billed as in the Seller offers mode.

## `maxOffersPerProduct` (type: `integer`):

Maximum seller offers to collect per product (up to 200). You pay per offer delivered. Each product's offers lookup has a minimum charge of $0.0028 for up to 10 offers Google returns, +$0.0025 per further started block of 10 (each block counts twice with “Buy on Google” offers): a lookup that delivers less (no offers, or all prices unchanged) is topped up to it (<code>lookup-minimum</code>, see Pricing).

## `includeBuyOnGoogle` (type: `boolean`):

Also check offers sold directly through Google checkout. Adds an add-on charge per started block of 10 delivered offers and doubles the offers lookup minimum (see Pricing).

## `variantFilter` (type: `string`):

Optional Google product-variant filter value (the <code>pvf</code> value from a Google Shopping product URL) to get offers for one exact variant, e.g. a size or color.

## `productSpecifications` (type: `object`):

Optional. Variant details to match for products given as links or IDs, e.g. <code>{"Color": "Black", "Storage": "256 GB"}</code>. For products found by a search this is filled in automatically.

## `location` (type: `string`):

Shop from a specific place instead of the whole country, written as <code>City,Region,Country</code>, e.g. <code>Austin,Texas,United States</code>. Overrides Country.

## `coordinates` (type: `string`):

Shop from an exact point: <code>latitude,longitude</code> or <code>latitude,longitude,radius-in-meters</code> (radius 200–199999). Overrides City and Country.

## `googleDomain` (type: `string`):

Optional Google domain, e.g. <code>google.co.uk</code>, <code>google.de</code>. Default: chosen automatically.

## `monitorPrices` (type: `boolean`):

Remembers the last price of every product and seller offer (per monitoring name, country and language) and adds <code>previousPrice</code>, <code>priceChange</code>, <code>priceChangePct</code>, <code>isNew</code> and <code>priceStatus</code> to each row. Schedule the same input daily to monitor prices. Tracking alone has no extra charge.

## `onlyChangedPrices` (type: `boolean`):

Deliver only rows that are new or whose price changed since the last run. Unchanged rows are not delivered and <b>not charged</b>; each search or product lookup that returned data costs a $0.004 price check instead (plus a <code>lookup-minimum</code> top-up when a lookup with many unchanged results stays below its minimum charge, see Pricing). Turns on price tracking automatically. The first run delivers everything (all rows are new).

## `monitoringName` (type: `string`):

Each name keeps its own price history. Use one name per list you monitor (e.g. <code>headphones-us</code>) so separate schedules do not affect each other. Max 100 characters.

## `minPriceChangePct` (type: `number`):

Smaller price moves count as unchanged (0 = any change). The last reported price is kept, so small moves that add up to this threshold are still reported.

## `processingSpeed` (type: `string`):

How quickly results are collected. The price is the same; economy is meant for large batches.

## `maxWaitMinutes` (type: `integer`):

Requests not finished after this time are reported in the run summary. They were already sent and are billed to us, so each one is charged only its lookup minimum ($0.0028; $0.0053 for offers with “Buy on Google”), no rows.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "wireless earbuds"
  ],
  "products": [
    "1113158713975221117",
    "https://www.google.com/search?ibp=oshop&q=iphone&prds=catalogid:1113158713975221117,pvo:3"
  ],
  "maxProductsPerSearch": 40,
  "country": "US",
  "language": "en",
  "sortBy": "relevance",
  "includeSponsored": false,
  "includeCarousels": false,
  "offersForTopProducts": 0,
  "maxOffersPerProduct": 20,
  "includeBuyOnGoogle": false,
  "monitorPrices": false,
  "onlyChangedPrices": false,
  "monitoringName": "default",
  "minPriceChangePct": 0,
  "processingSpeed": "auto",
  "maxWaitMinutes": 60
}
```

# Actor output Schema

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

No description

## `offers` (type: `string`):

No description

## `details` (type: `string`):

No description

## `priceChanges` (type: `string`):

No description

## `runSummary` (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 = {
    "mode": "search",
    "searchTerms": [
        "wireless earbuds"
    ],
    "products": [
        "1113158713975221117"
    ],
    "maxProductsPerSearch": 40,
    "country": "US",
    "language": "en",
    "monitoringName": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/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 = {
    "mode": "search",
    "searchTerms": ["wireless earbuds"],
    "products": ["1113158713975221117"],
    "maxProductsPerSearch": 40,
    "country": "US",
    "language": "en",
    "monitoringName": "default",
}

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

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

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

```

## CLI example

```bash
echo '{
  "mode": "search",
  "searchTerms": [
    "wireless earbuds"
  ],
  "products": [
    "1113158713975221117"
  ],
  "maxProductsPerSearch": 40,
  "country": "US",
  "language": "en",
  "monitoringName": "default"
}' |
apify call cheapapi/google-shopping-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cheapapi/google-shopping-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qgHmBHqRYVJAtQfr4/builds/S12omwYf3jdtowoT7/openapi.json
