{
  "data": {
    "id": "p859CrahOaABt6Kkq",
    "actId": "MMwNfJSA1eG2IqVrJ",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-10-24T08:50:09.498Z",
    "finishedAt": "2026-10-24T08:50:25.655Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 16015,
      "runTimeSecs": 16.015,
      "computeUnits": 0.017794444444444446,
      "imageSizeBytes": 332111360
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Google Shopping Price Comparison & Deal Finder\",\n  \"description\": \"Search Google Shopping, look up products by ID, or browse deals and categories. Returns real product IDs, viewer URLs, seller offers with shipping and totals, price ranges and 12-month price history where Google exposes it.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"Mode\",\n      \"type\": \"string\",\n      \"description\": \"What to collect: keyword search, product lookup by ID/viewer URL, deals, or a department category.\",\n      \"editor\": \"select\",\n      \"default\": \"search\",\n      \"prefill\": \"search\",\n      \"enum\": [\n        \"search\",\n        \"product\",\n        \"deals\",\n        \"category\"\n      ],\n      \"enumTitles\": [\n        \"Keyword search\",\n        \"Product lookup (ID or URL)\",\n        \"Deals\",\n        \"Category browse\"\n      ]\n    },\n    \"queries\": {\n      \"title\": \"Search Queries\",\n      \"type\": \"array\",\n      \"description\": \"Product keywords for search/deals mode. Ignored in product mode; optional in category mode.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"prefill\": [\n        \"iPhone 15 Pro Max\"\n      ]\n    },\n    \"productIds\": {\n      \"title\": \"Product IDs or Viewer URLs\",\n      \"type\": \"array\",\n      \"description\": \"Google Shopping catalog IDs, product IDs, product viewer URLs, or legacy /shopping/product/<id> URLs. Used in product mode.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"category\": {\n      \"title\": \"Category\",\n      \"type\": \"string\",\n      \"description\": \"Google Shopping department for category mode.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"electronics\",\n        \"computers\",\n        \"cell-phones\",\n        \"audio\",\n        \"cameras\",\n        \"video-games\",\n        \"tv-home-theater\",\n        \"appliances\",\n        \"home-garden\",\n        \"clothing\",\n        \"shoes\",\n        \"beauty\",\n        \"sports-outdoors\",\n        \"toys-games\",\n        \"jewelry\"\n      ],\n      \"enumTitles\": [\n        \"Electronics\",\n        \"Computers\",\n        \"Cell Phones\",\n        \"Audio\",\n        \"Cameras\",\n        \"Video Games\",\n        \"TV & Home Theater\",\n        \"Appliances\",\n        \"Home & Garden\",\n        \"Clothing\",\n        \"Shoes\",\n        \"Beauty\",\n        \"Sports & Outdoors\",\n        \"Toys & Games\",\n        \"Jewelry\"\n      ]\n    },\n    \"countryCode\": {\n      \"title\": \"Country\",\n      \"type\": \"string\",\n      \"description\": \"Country used for the Google domain, UULE location and price hint. The actual currency is always detected from the response, never relabelled.\",\n      \"editor\": \"select\",\n      \"default\": \"us\",\n      \"prefill\": \"us\",\n      \"enum\": [\n        \"us\",\n        \"uk\",\n        \"ca\",\n        \"au\",\n        \"de\",\n        \"fr\",\n        \"es\",\n        \"it\",\n        \"br\",\n        \"mx\",\n        \"in\",\n        \"jp\",\n        \"kr\",\n        \"nl\",\n        \"be\",\n        \"at\",\n        \"ch\",\n        \"se\",\n        \"no\",\n        \"dk\",\n        \"fi\",\n        \"pl\",\n        \"cz\",\n        \"pt\",\n        \"ie\",\n        \"nz\",\n        \"za\",\n        \"sg\",\n        \"hk\",\n        \"tw\",\n        \"ph\",\n        \"th\",\n        \"id\",\n        \"my\",\n        \"vn\",\n        \"ar\",\n        \"cl\",\n        \"co\",\n        \"pe\",\n        \"tr\",\n        \"ru\",\n        \"ua\",\n        \"il\",\n        \"ae\",\n        \"sa\",\n        \"eg\",\n        \"ng\",\n        \"ke\"\n      ],\n      \"enumTitles\": [\n        \"United States\",\n        \"United Kingdom\",\n        \"Canada\",\n        \"Australia\",\n        \"Germany\",\n        \"France\",\n        \"Spain\",\n        \"Italy\",\n        \"Brazil\",\n        \"Mexico\",\n        \"India\",\n        \"Japan\",\n        \"South Korea\",\n        \"Netherlands\",\n        \"Belgium\",\n        \"Austria\",\n        \"Switzerland\",\n        \"Sweden\",\n        \"Norway\",\n        \"Denmark\",\n        \"Finland\",\n        \"Poland\",\n        \"Czech Republic\",\n        \"Portugal\",\n        \"Ireland\",\n        \"New Zealand\",\n        \"South Africa\",\n        \"Singapore\",\n        \"Hong Kong\",\n        \"Taiwan\",\n        \"Philippines\",\n        \"Thailand\",\n        \"Indonesia\",\n        \"Malaysia\",\n        \"Vietnam\",\n        \"Argentina\",\n        \"Chile\",\n        \"Colombia\",\n        \"Peru\",\n        \"Turkey\",\n        \"Russia\",\n        \"Ukraine\",\n        \"Israel\",\n        \"UAE\",\n        \"Saudi Arabia\",\n        \"Egypt\",\n        \"Nigeria\",\n        \"Kenya\"\n      ]\n    },\n    \"languageCode\": {\n      \"title\": \"Language\",\n      \"type\": \"string\",\n      \"description\": \"Interface and result language (hl parameter).\",\n      \"editor\": \"select\",\n      \"default\": \"en\",\n      \"prefill\": \"en\",\n      \"enum\": [\n        \"en\",\n        \"es\",\n        \"fr\",\n        \"de\",\n        \"it\",\n        \"pt\",\n        \"nl\",\n        \"pl\",\n        \"tr\",\n        \"ru\",\n        \"ja\",\n        \"ko\",\n        \"zh\",\n        \"ar\",\n        \"hi\",\n        \"th\",\n        \"vi\",\n        \"id\",\n        \"ms\",\n        \"sv\",\n        \"da\",\n        \"no\",\n        \"fi\",\n        \"cs\",\n        \"el\",\n        \"he\",\n        \"uk\"\n      ],\n      \"enumTitles\": [\n        \"English\",\n        \"Spanish\",\n        \"French\",\n        \"German\",\n        \"Italian\",\n        \"Portuguese\",\n        \"Dutch\",\n        \"Polish\",\n        \"Turkish\",\n        \"Russian\",\n        \"Japanese\",\n        \"Korean\",\n        \"Chinese\",\n        \"Arabic\",\n        \"Hindi\",\n        \"Thai\",\n        \"Vietnamese\",\n        \"Indonesian\",\n        \"Malay\",\n        \"Swedish\",\n        \"Danish\",\n        \"Norwegian\",\n        \"Finnish\",\n        \"Czech\",\n        \"Greek\",\n        \"Hebrew\",\n        \"Ukrainian\"\n      ]\n    },\n    \"sortBy\": {\n      \"title\": \"Sort By\",\n      \"type\": \"string\",\n      \"description\": \"Client-side sort of the collected rows. Google ignores server-side sort on this page.\",\n      \"editor\": \"select\",\n      \"default\": \"\",\n      \"enum\": [\n        \"\",\n        \"review_score\",\n        \"price_low\",\n        \"price_high\"\n      ],\n      \"enumTitles\": [\n        \"Relevance (default)\",\n        \"Rating high to low\",\n        \"Price low to high\",\n        \"Price high to low\"\n      ]\n    },\n    \"condition\": {\n      \"title\": \"Condition\",\n      \"type\": \"string\",\n      \"description\": \"Condition hint sent to Google and verified when the result card shows a condition.\",\n      \"editor\": \"select\",\n      \"default\": \"\",\n      \"enum\": [\n        \"\",\n        \"new\",\n        \"used\",\n        \"refurbished\"\n      ],\n      \"enumTitles\": [\n        \"Any\",\n        \"New\",\n        \"Used\",\n        \"Refurbished\"\n      ]\n    },\n    \"minPrice\": {\n      \"title\": \"Minimum Price\",\n      \"type\": \"integer\",\n      \"description\": \"Minimum price in the detected local currency. Applied through a shoprs filter and verified on every output row.\",\n      \"minimum\": 0\n    },\n    \"maxPrice\": {\n      \"title\": \"Maximum Price\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum price in the detected local currency. Applied through a shoprs filter and verified on every output row.\",\n      \"minimum\": 0\n    },\n    \"onSale\": {\n      \"title\": \"On Sale Only\",\n      \"type\": \"boolean\",\n      \"description\": \"Ask Google for discounted products and keep rows with an observed original price or discount.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"freeShipping\": {\n      \"title\": \"Free Shipping Only\",\n      \"type\": \"boolean\",\n      \"description\": \"Ask Google for free-shipping products and keep rows whose delivery text says free.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"minRating\": {\n      \"title\": \"Minimum Rating\",\n      \"type\": \"string\",\n      \"description\": \"Minimum product rating (0-5). Applied through a shoprs rating chip and verified on every output row.\",\n      \"editor\": \"select\",\n      \"default\": \"0\",\n      \"enum\": [\n        \"0\",\n        \"1\",\n        \"2\",\n        \"3\",\n        \"4\",\n        \"5\"\n      ],\n      \"enumTitles\": [\n        \"Any\",\n        \"1 and up\",\n        \"2 and up\",\n        \"3 and up\",\n        \"4 and up\",\n        \"5\"\n      ]\n    },\n    \"store\": {\n      \"title\": \"Store\",\n      \"type\": \"string\",\n      \"description\": \"Optional store name to bias and verify, e.g. Best Buy or Amazon.\",\n      \"editor\": \"textfield\"\n    },\n    \"maxResultsPerQuery\": {\n      \"title\": \"Max Results\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum records per query (search/deals/category) or products (product mode).\",\n      \"minimum\": 1,\n      \"maximum\": 200,\n      \"default\": 20,\n      \"prefill\": 1\n    },\n    \"includePriceHistory\": {\n      \"title\": \"Include 12-Month Price History\",\n      \"type\": \"boolean\",\n      \"description\": \"Include per-seller daily price history when Google exposes it (product mode and search detail enrichment).\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeProductDetails\": {\n      \"title\": \"Enrich Search Results\",\n      \"type\": \"boolean\",\n      \"description\": \"Fetch the product viewer for each search result to add brand, description, images, specifications and offers. Costs one extra request per result.\",\n      \"default\": false,\n      \"prefill\": false\n    }\n  }\n}",
    "readme": "# Google Shopping Price Comparison & Deal Finder\n\nCollect real Google Shopping data for price comparison and deal monitoring. Search by keyword, open a known product by its Google Shopping ID or viewer URL, browse a department, or pull current deals across 48 countries.\n\nSearch records use the actual product ID (`data-pid`) and a viewer link built from the catalog or product ID Google returns. Product-mode records carry the numeric ID used in the lookup and a working viewer link. Product records add seller offers with shipping and totals, a price range, specifications, images, variants, and the 12-month per-seller price history when Google exposes it.\n\n## Modes\n\n| Mode | What it does | Main input |\n|---|---|---|\n| **search** | Keyword search across Google Shopping results | `queries` |\n| **product** | Opens the product viewer for one or more products | `productIds` |\n| **deals** | Searches Google's deals view | `queries` (optional; defaults to `deals`) |\n| **category** | Browses one of 15 Google Shopping departments | `category` |\n\n## What you get\n\n**Every record**\n\n- `query`, `position`, `recordType`, `scrapedAt`\n- `title`, `price` (display) and `priceValue` (number)\n- `originalPrice`, `originalPriceValue`, `discountPercent` when discounted\n- `currency` — the currency Google actually served, never relabelled from the requested country\n- `merchant`, `merchantUrl`, `sellerDomain`\n- `rating`, `reviewCount`, `ratingValue`, `reviewCountValue`\n- `delivery`, `shipping`, `availability`, `condition`, `returns`\n- `imageUrl`, `imageUrls`\n- `isSponsored` (true only when a sponsored label is visible)\n- `productId` — real `data-pid` on search/deals/category rows; in product mode it is the ID used in the viewer lookup (a catalog ID when the input is a viewer URL). `catalogId` is the real `data-cid` when Google exposes it.\n- `productUrl` — a real Google Shopping viewer URL\n- `searchUrl`, `hasMoreOffers`, `badge`\n\n**Product records and enriched search results**\n\n- `brand`, `description`, `images`, `specifications`, `variants`\n- `offerCount` and `offers` — seller, seller ID, direct seller URL, domain, price, currency, original price, discount, shipping, delivery, total, availability, returns, store rating and review count, badge, best-price flag\n- `lowestPrice`, `highestPrice`, `priceRange`, `typicalPriceRange`\n- `priceHistory` — per-seller daily points with ISO dates\n- `discussions` — forum links about the product (not review text)\n- `dealFlags`\n\nEmpty fields are omitted at every depth.\n\n## Inputs\n\n| Field | Default | Description |\n|---|---|---|\n|---|---|\n| `mode` | `search` | `search` (default), `product`, `deals` or `category` |\n| `queries` | – | Keywords for search/deals. Optional in category mode |\n| `productIds` | – | Catalog IDs, product IDs, viewer URLs or legacy product URLs for product mode |\n| `category` | – | One of 15 departments (Electronics, Computers, Cell Phones, ...) |\n| `countryCode` | `us` | 48 countries; sets the Google domain and location hint |\n| `languageCode` | `en` | Result language |\n| `sortBy` | – | Relevance, rating, price low-to-high or high-to-low; applied to the collected rows |\n| `condition` | – | Any, new, used or refurbished |\n| `minPrice` / `maxPrice` | – | Price range in the requested market's currency; rows outside the numeric bounds are dropped. If Google serves another currency, a filtered run can return no rows. |\n| `onSale` | `false` | Keep products with an observed original price or discount |\n| `freeShipping` | `false` | Keep products whose delivery text says free |\n| `minRating` | `0` | 0–5; keeps products at or above the rating |\n| `store` | – | Optional store name to bias and verify |\n| `maxResultsPerQuery` | `20` | 1–200 records per query (or products in product mode) |\n| `includePriceHistory` | `true` | Include the 12-month history when Google exposes it |\n| `includeProductDetails` | `false` | Open the product viewer for each search result (one extra request per result) |\n\n## Examples\n\nSearch for one product and include details and history:\n\n```json\n{\n  \"mode\": \"search\",\n  \"queries\": [\"iPhone 15 Pro Max\"],\n  \"maxResultsPerQuery\": 5,\n  \"countryCode\": \"us\",\n  \"includeProductDetails\": true,\n  \"includePriceHistory\": true\n}\n```\n\nLook up products by ID or viewer URL:\n\n```json\n{\n  \"mode\": \"product\",\n  \"productIds\": [\"10694224367759637585\", \"https://www.google.com/search?q=x&ibp=oshop&prds=productid:2457150560515047758,pvt:a\"],\n  \"countryCode\": \"ca\",\n  \"includePriceHistory\": true\n}\n```\n\nPrice-filtered, free-shipping deals:\n\n```json\n{\n  \"mode\": \"deals\",\n  \"queries\": [\"wireless earbuds\"],\n  \"minPrice\": 20,\n  \"maxPrice\": 100,\n  \"freeShipping\": true,\n  \"sortBy\": \"price_low\",\n  \"countryCode\": \"uk\"\n}\n```\n\nBrowse a department:\n\n```json\n{\n  \"mode\": \"category\",\n  \"category\": \"electronics\",\n  \"maxResultsPerQuery\": 40,\n  \"countryCode\": \"de\"\n}\n```\n\n## Coverage and honest limits\n\n- **Up to five offers per product.** Google's product viewer renders at most five offers over the public HTTP path (some products show fewer); `offerCount` often reports many more (209 in sampling). The remaining offers are not available without a browser identity.\n- **About 127 products per query.** Search pages start at 0, 10, 50 and 90; later starts return no products. Split a broad query into narrower queries to collect more.\n- **No product review text.** Google does not expose product review bodies on this path. Ratings and review counts from search cards and store ratings on offers are included; `discussions` contains forum links only.\n- **Localization is best effort.** A country plus location hint usually returns the right market, but Google can serve another exit's currency. The actor retries once, then reports the actual `currency` and logs the mismatch. It never relabels one currency as another.\n- **Filtered runs can be empty on a currency mismatch.** Price bounds use the requested market's currency (for example USD for `countryCode: us`). If Google serves another currency, a max-price or on-sale filter can exclude every row; the run then reports the served currency and fails with \"No records scraped\" instead of relabelling.\n- **Sorting is client-side.** Google's server-side sort chip is not honored on this page. The actor sorts the rows it actually collected.\n- **Filters are verified after collection.** Price bounds, rating, store, sale and free-shipping checks are re-applied to every row. A condition is checked when the card shows one; many cards omit it.\n- **Display price can differ from the numeric offer price.** A seller card can show a list price in `price` while `priceValue` carries the best price Google reports (one sampled EarFun offer displayed `$89.99` with `priceValue` 51.29). Use `priceValue`, `shippingValue` and `totalPrice` for comparisons.\n- **Sponsored detection is not a classifier.** `isSponsored` is true only when Google visibly labels a card as sponsored. Organic ads can appear without that label.\n- **Some fields are source-dependent.** Brand, description, price history and typical price are present only when Google exposes them for that product. They are omitted rather than guessed.\n\n## Practical use\n\n- **Price monitoring:** run product mode on a fixed list of IDs and compare `priceValue`, `totalPrice` and `priceHistory` over time.\n- **Deal scanning:** use deals mode with `onSale`, a price range and `sortBy: price_low`.\n- **Market research:** search a category with `sortBy: review_score` and compare merchants, availability and shipping.\n- **Catalog enrichment:** search with `includeProductDetails` to attach brand, images, specs and offers to keyword results.\n\n## FAQ\n\n**Do I need cookies, a login or a proxy setup?**\nNo. The actor reads public Google Shopping pages and handles its own access. There are no user credentials, cookies or proxy fields.\n\n**Can I get every seller offer?**\nNo. Up to five offers per product is a hard limit of the public product viewer; the total count is returned so you know how many exist.\n\n**Why is a field missing on some records?**\nGoogle does not show every field on every card or product. Missing values are omitted; the actor does not fill them with guesses or sentinels.\n\n**Why does the currency differ from the country I chose?**\nGoogle's market routing is not guaranteed. The actor detects the served currency, retries once with the location hint, and reports the actual result rather than assuming.\n\n**Can I sort by price?**\nYes — the actor sorts the collected rows by price or rating. The order is deterministic but reflects the rows collected, not Google's full index.\n\n**Does this return product review text?**\nNo. Review text is not available on this path.\n\n**Is this affiliated with Google?**\nNo. It is an independent third-party tool that reads publicly available Google Shopping pages.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "google-shopping-price-comparison-and-deal-finder",
      "title": "Google Shopping Price Comparison & Deal Finder",
      "description": "Search Google Shopping by keyword or product ID and get real product IDs, viewer URLs, seller offers with shipping and totals, price ranges, specs, images, and 12-month price history across 48 countries.",
      "version": "1.0",
      "buildTag": "latest",
      "meta": {
        "templateId": "python-start"
      },
      "input": {
        "title": "Google Shopping Price Comparison & Deal Finder",
        "description": "Search Google Shopping, look up products by ID, or browse deals and categories. Returns real product IDs, viewer URLs, seller offers with shipping and totals, price ranges and 12-month price history where Google exposes it.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "Mode",
            "type": "string",
            "description": "What to collect: keyword search, product lookup by ID/viewer URL, deals, or a department category.",
            "editor": "select",
            "default": "search",
            "prefill": "search",
            "enum": [
              "search",
              "product",
              "deals",
              "category"
            ],
            "enumTitles": [
              "Keyword search",
              "Product lookup (ID or URL)",
              "Deals",
              "Category browse"
            ]
          },
          "queries": {
            "title": "Search Queries",
            "type": "array",
            "description": "Product keywords for search/deals mode. Ignored in product mode; optional in category mode.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "prefill": [
              "iPhone 15 Pro Max"
            ]
          },
          "productIds": {
            "title": "Product IDs or Viewer URLs",
            "type": "array",
            "description": "Google Shopping catalog IDs, product IDs, product viewer URLs, or legacy /shopping/product/<id> URLs. Used in product mode.",
            "editor": "stringList",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Category",
            "type": "string",
            "description": "Google Shopping department for category mode.",
            "editor": "select",
            "enum": [
              "electronics",
              "computers",
              "cell-phones",
              "audio",
              "cameras",
              "video-games",
              "tv-home-theater",
              "appliances",
              "home-garden",
              "clothing",
              "shoes",
              "beauty",
              "sports-outdoors",
              "toys-games",
              "jewelry"
            ],
            "enumTitles": [
              "Electronics",
              "Computers",
              "Cell Phones",
              "Audio",
              "Cameras",
              "Video Games",
              "TV & Home Theater",
              "Appliances",
              "Home & Garden",
              "Clothing",
              "Shoes",
              "Beauty",
              "Sports & Outdoors",
              "Toys & Games",
              "Jewelry"
            ]
          },
          "countryCode": {
            "title": "Country",
            "type": "string",
            "description": "Country used for the Google domain, UULE location and price hint. The actual currency is always detected from the response, never relabelled.",
            "editor": "select",
            "default": "us",
            "prefill": "us",
            "enum": [
              "us",
              "uk",
              "ca",
              "au",
              "de",
              "fr",
              "es",
              "it",
              "br",
              "mx",
              "in",
              "jp",
              "kr",
              "nl",
              "be",
              "at",
              "ch",
              "se",
              "no",
              "dk",
              "fi",
              "pl",
              "cz",
              "pt",
              "ie",
              "nz",
              "za",
              "sg",
              "hk",
              "tw",
              "ph",
              "th",
              "id",
              "my",
              "vn",
              "ar",
              "cl",
              "co",
              "pe",
              "tr",
              "ru",
              "ua",
              "il",
              "ae",
              "sa",
              "eg",
              "ng",
              "ke"
            ],
            "enumTitles": [
              "United States",
              "United Kingdom",
              "Canada",
              "Australia",
              "Germany",
              "France",
              "Spain",
              "Italy",
              "Brazil",
              "Mexico",
              "India",
              "Japan",
              "South Korea",
              "Netherlands",
              "Belgium",
              "Austria",
              "Switzerland",
              "Sweden",
              "Norway",
              "Denmark",
              "Finland",
              "Poland",
              "Czech Republic",
              "Portugal",
              "Ireland",
              "New Zealand",
              "South Africa",
              "Singapore",
              "Hong Kong",
              "Taiwan",
              "Philippines",
              "Thailand",
              "Indonesia",
              "Malaysia",
              "Vietnam",
              "Argentina",
              "Chile",
              "Colombia",
              "Peru",
              "Turkey",
              "Russia",
              "Ukraine",
              "Israel",
              "UAE",
              "Saudi Arabia",
              "Egypt",
              "Nigeria",
              "Kenya"
            ]
          },
          "languageCode": {
            "title": "Language",
            "type": "string",
            "description": "Interface and result language (hl parameter).",
            "editor": "select",
            "default": "en",
            "prefill": "en",
            "enum": [
              "en",
              "es",
              "fr",
              "de",
              "it",
              "pt",
              "nl",
              "pl",
              "tr",
              "ru",
              "ja",
              "ko",
              "zh",
              "ar",
              "hi",
              "th",
              "vi",
              "id",
              "ms",
              "sv",
              "da",
              "no",
              "fi",
              "cs",
              "el",
              "he",
              "uk"
            ],
            "enumTitles": [
              "English",
              "Spanish",
              "French",
              "German",
              "Italian",
              "Portuguese",
              "Dutch",
              "Polish",
              "Turkish",
              "Russian",
              "Japanese",
              "Korean",
              "Chinese",
              "Arabic",
              "Hindi",
              "Thai",
              "Vietnamese",
              "Indonesian",
              "Malay",
              "Swedish",
              "Danish",
              "Norwegian",
              "Finnish",
              "Czech",
              "Greek",
              "Hebrew",
              "Ukrainian"
            ]
          },
          "sortBy": {
            "title": "Sort By",
            "type": "string",
            "description": "Client-side sort of the collected rows. Google ignores server-side sort on this page.",
            "editor": "select",
            "default": "",
            "enum": [
              "",
              "review_score",
              "price_low",
              "price_high"
            ],
            "enumTitles": [
              "Relevance (default)",
              "Rating high to low",
              "Price low to high",
              "Price high to low"
            ]
          },
          "condition": {
            "title": "Condition",
            "type": "string",
            "description": "Condition hint sent to Google and verified when the result card shows a condition.",
            "editor": "select",
            "default": "",
            "enum": [
              "",
              "new",
              "used",
              "refurbished"
            ],
            "enumTitles": [
              "Any",
              "New",
              "Used",
              "Refurbished"
            ]
          },
          "minPrice": {
            "title": "Minimum Price",
            "type": "integer",
            "description": "Minimum price in the detected local currency. Applied through a shoprs filter and verified on every output row.",
            "minimum": 0
          },
          "maxPrice": {
            "title": "Maximum Price",
            "type": "integer",
            "description": "Maximum price in the detected local currency. Applied through a shoprs filter and verified on every output row.",
            "minimum": 0
          },
          "onSale": {
            "title": "On Sale Only",
            "type": "boolean",
            "description": "Ask Google for discounted products and keep rows with an observed original price or discount.",
            "default": false,
            "prefill": false
          },
          "freeShipping": {
            "title": "Free Shipping Only",
            "type": "boolean",
            "description": "Ask Google for free-shipping products and keep rows whose delivery text says free.",
            "default": false,
            "prefill": false
          },
          "minRating": {
            "title": "Minimum Rating",
            "type": "string",
            "description": "Minimum product rating (0-5). Applied through a shoprs rating chip and verified on every output row.",
            "editor": "select",
            "default": "0",
            "enum": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5"
            ],
            "enumTitles": [
              "Any",
              "1 and up",
              "2 and up",
              "3 and up",
              "4 and up",
              "5"
            ]
          },
          "store": {
            "title": "Store",
            "type": "string",
            "description": "Optional store name to bias and verify, e.g. Best Buy or Amazon.",
            "editor": "textfield"
          },
          "maxResultsPerQuery": {
            "title": "Max Results",
            "type": "integer",
            "description": "Maximum records per query (search/deals/category) or products (product mode).",
            "minimum": 1,
            "maximum": 200,
            "default": 20,
            "prefill": 1
          },
          "includePriceHistory": {
            "title": "Include 12-Month Price History",
            "type": "boolean",
            "description": "Include per-seller daily price history when Google exposes it (product mode and search detail enrichment).",
            "default": true,
            "prefill": false
          },
          "includeProductDetails": {
            "title": "Enrich Search Results",
            "type": "boolean",
            "description": "Fetch the product viewer for each search result to add brand, description, images, specifications and offers. Costs one extra request per result.",
            "default": false,
            "prefill": false
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Google Shopping Price Comparison & Deal Finder Output",
        "description": "Product listings and product-viewer records with real product IDs, viewer URLs, seller offers, shipping and totals, price ranges, specifications and 12-month price history where Google exposes it.",
        "type": "object",
        "properties": {
          "products": {
            "type": "string",
            "title": "Shopping Products",
            "description": "Dataset containing search results, deals, category results and product records.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# Google Shopping Price Comparison & Deal Finder\n\nCollect real Google Shopping data for price comparison and deal monitoring. Search by keyword, open a known product by its Google Shopping ID or viewer URL, browse a department, or pull current deals across 48 countries.\n\nSearch records use the actual product ID (`data-pid`) and a viewer link built from the catalog or product ID Google returns. Product-mode records carry the numeric ID used in the lookup and a working viewer link. Product records add seller offers with shipping and totals, a price range, specifications, images, variants, and the 12-month per-seller price history when Google exposes it.\n\n## Modes\n\n| Mode | What it does | Main input |\n|---|---|---|\n| **search** | Keyword search across Google Shopping results | `queries` |\n| **product** | Opens the product viewer for one or more products | `productIds` |\n| **deals** | Searches Google's deals view | `queries` (optional; defaults to `deals`) |\n| **category** | Browses one of 15 Google Shopping departments | `category` |\n\n## What you get\n\n**Every record**\n\n- `query`, `position`, `recordType`, `scrapedAt`\n- `title`, `price` (display) and `priceValue` (number)\n- `originalPrice`, `originalPriceValue`, `discountPercent` when discounted\n- `currency` — the currency Google actually served, never relabelled from the requested country\n- `merchant`, `merchantUrl`, `sellerDomain`\n- `rating`, `reviewCount`, `ratingValue`, `reviewCountValue`\n- `delivery`, `shipping`, `availability`, `condition`, `returns`\n- `imageUrl`, `imageUrls`\n- `isSponsored` (true only when a sponsored label is visible)\n- `productId` — real `data-pid` on search/deals/category rows; in product mode it is the ID used in the viewer lookup (a catalog ID when the input is a viewer URL). `catalogId` is the real `data-cid` when Google exposes it.\n- `productUrl` — a real Google Shopping viewer URL\n- `searchUrl`, `hasMoreOffers`, `badge`\n\n**Product records and enriched search results**\n\n- `brand`, `description`, `images`, `specifications`, `variants`\n- `offerCount` and `offers` — seller, seller ID, direct seller URL, domain, price, currency, original price, discount, shipping, delivery, total, availability, returns, store rating and review count, badge, best-price flag\n- `lowestPrice`, `highestPrice`, `priceRange`, `typicalPriceRange`\n- `priceHistory` — per-seller daily points with ISO dates\n- `discussions` — forum links about the product (not review text)\n- `dealFlags`\n\nEmpty fields are omitted at every depth.\n\n## Inputs\n\n| Field | Default | Description |\n|---|---|---|\n|---|---|\n| `mode` | `search` | `search` (default), `product`, `deals` or `category` |\n| `queries` | – | Keywords for search/deals. Optional in category mode |\n| `productIds` | – | Catalog IDs, product IDs, viewer URLs or legacy product URLs for product mode |\n| `category` | – | One of 15 departments (Electronics, Computers, Cell Phones, ...) |\n| `countryCode` | `us` | 48 countries; sets the Google domain and location hint |\n| `languageCode` | `en` | Result language |\n| `sortBy` | – | Relevance, rating, price low-to-high or high-to-low; applied to the collected rows |\n| `condition` | – | Any, new, used or refurbished |\n| `minPrice` / `maxPrice` | – | Price range in the requested market's currency; rows outside the numeric bounds are dropped. If Google serves another currency, a filtered run can return no rows. |\n| `onSale` | `false` | Keep products with an observed original price or discount |\n| `freeShipping` | `false` | Keep products whose delivery text says free |\n| `minRating` | `0` | 0–5; keeps products at or above the rating |\n| `store` | – | Optional store name to bias and verify |\n| `maxResultsPerQuery` | `20` | 1–200 records per query (or products in product mode) |\n| `includePriceHistory` | `true` | Include the 12-month history when Google exposes it |\n| `includeProductDetails` | `false` | Open the product viewer for each search result (one extra request per result) |\n\n## Examples\n\nSearch for one product and include details and history:\n\n```json\n{\n  \"mode\": \"search\",\n  \"queries\": [\"iPhone 15 Pro Max\"],\n  \"maxResultsPerQuery\": 5,\n  \"countryCode\": \"us\",\n  \"includeProductDetails\": true,\n  \"includePriceHistory\": true\n}\n```\n\nLook up products by ID or viewer URL:\n\n```json\n{\n  \"mode\": \"product\",\n  \"productIds\": [\"10694224367759637585\", \"https://www.google.com/search?q=x&ibp=oshop&prds=productid:2457150560515047758,pvt:a\"],\n  \"countryCode\": \"ca\",\n  \"includePriceHistory\": true\n}\n```\n\nPrice-filtered, free-shipping deals:\n\n```json\n{\n  \"mode\": \"deals\",\n  \"queries\": [\"wireless earbuds\"],\n  \"minPrice\": 20,\n  \"maxPrice\": 100,\n  \"freeShipping\": true,\n  \"sortBy\": \"price_low\",\n  \"countryCode\": \"uk\"\n}\n```\n\nBrowse a department:\n\n```json\n{\n  \"mode\": \"category\",\n  \"category\": \"electronics\",\n  \"maxResultsPerQuery\": 40,\n  \"countryCode\": \"de\"\n}\n```\n\n## Coverage and honest limits\n\n- **Up to five offers per product.** Google's product viewer renders at most five offers over the public HTTP path (some products show fewer); `offerCount` often reports many more (209 in sampling). The remaining offers are not available without a browser identity.\n- **About 127 products per query.** Search pages start at 0, 10, 50 and 90; later starts return no products. Split a broad query into narrower queries to collect more.\n- **No product review text.** Google does not expose product review bodies on this path. Ratings and review counts from search cards and store ratings on offers are included; `discussions` contains forum links only.\n- **Localization is best effort.** A country plus location hint usually returns the right market, but Google can serve another exit's currency. The actor retries once, then reports the actual `currency` and logs the mismatch. It never relabels one currency as another.\n- **Filtered runs can be empty on a currency mismatch.** Price bounds use the requested market's currency (for example USD for `countryCode: us`). If Google serves another currency, a max-price or on-sale filter can exclude every row; the run then reports the served currency and fails with \"No records scraped\" instead of relabelling.\n- **Sorting is client-side.** Google's server-side sort chip is not honored on this page. The actor sorts the rows it actually collected.\n- **Filters are verified after collection.** Price bounds, rating, store, sale and free-shipping checks are re-applied to every row. A condition is checked when the card shows one; many cards omit it.\n- **Display price can differ from the numeric offer price.** A seller card can show a list price in `price` while `priceValue` carries the best price Google reports (one sampled EarFun offer displayed `$89.99` with `priceValue` 51.29). Use `priceValue`, `shippingValue` and `totalPrice` for comparisons.\n- **Sponsored detection is not a classifier.** `isSponsored` is true only when Google visibly labels a card as sponsored. Organic ads can appear without that label.\n- **Some fields are source-dependent.** Brand, description, price history and typical price are present only when Google exposes them for that product. They are omitted rather than guessed.\n\n## Practical use\n\n- **Price monitoring:** run product mode on a fixed list of IDs and compare `priceValue`, `totalPrice` and `priceHistory` over time.\n- **Deal scanning:** use deals mode with `onSale`, a price range and `sortBy: price_low`.\n- **Market research:** search a category with `sortBy: review_score` and compare merchants, availability and shipping.\n- **Catalog enrichment:** search with `includeProductDetails` to attach brand, images, specs and offers to keyword results.\n\n## FAQ\n\n**Do I need cookies, a login or a proxy setup?**\nNo. The actor reads public Google Shopping pages and handles its own access. There are no user credentials, cookies or proxy fields.\n\n**Can I get every seller offer?**\nNo. Up to five offers per product is a hard limit of the public product viewer; the total count is returned so you know how many exist.\n\n**Why is a field missing on some records?**\nGoogle does not show every field on every card or product. Missing values are omitted; the actor does not fill them with guesses or sentinels.\n\n**Why does the currency differ from the country I chose?**\nGoogle's market routing is not guaranteed. The actor detects the served currency, retries once with the location hint, and reports the actual result rather than assuming.\n\n**Can I sort by price?**\nYes — the actor sorts the collected rows by price or rating. The order is deterministic but reflects the rows collected, not Google's full index.\n\n**Does this return product review text?**\nNo. Review text is not available on this path.\n\n**Is this affiliated with Google?**\nNo. It is an independent third-party tool that reads publicly available Google Shopping pages.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Google Shopping Products, Offers and Price History",
          "fields": {
            "type": "object",
            "properties": {
              "query": {
                "type": "string",
                "description": "Search query or category/deal query that produced the record."
              },
              "position": {
                "type": "integer",
                "description": "1-based position in the collected result set."
              },
              "recordType": {
                "type": "string",
                "description": "searchResult or product."
              },
              "title": {
                "type": "string",
                "description": "Product title."
              },
              "brand": {
                "type": "string",
                "description": "Brand from the product viewer."
              },
              "description": {
                "type": "string",
                "description": "Product description from the viewer."
              },
              "price": {
                "type": "string",
                "description": "Current price as displayed, including currency symbol or code."
              },
              "priceValue": {
                "type": "number",
                "description": "Numeric current price."
              },
              "originalPrice": {
                "type": "string",
                "description": "Original or list price as displayed, when discounted."
              },
              "originalPriceValue": {
                "type": "number",
                "description": "Numeric original price."
              },
              "discountPercent": {
                "type": "number",
                "description": "Observed discount percentage."
              },
              "currency": {
                "type": "string",
                "description": "Actual detected currency code. Never relabelled from the requested country."
              },
              "merchant": {
                "type": "string",
                "description": "Seller or merchant name."
              },
              "merchantUrl": {
                "type": "string",
                "description": "Direct seller URL when available; otherwise the Google /goto redirect. Never guessed."
              },
              "sellerDomain": {
                "type": "string",
                "description": "Seller domain when Google exposes it."
              },
              "rating": {
                "type": "string",
                "description": "Product rating as displayed on the search card."
              },
              "reviewCount": {
                "type": "string",
                "description": "Product review count as displayed on the search card."
              },
              "ratingValue": {
                "type": "number",
                "description": "Numeric product rating."
              },
              "reviewCountValue": {
                "type": "integer",
                "description": "Numeric product review count."
              },
              "imageUrl": {
                "type": "string",
                "description": "Primary product image URL."
              },
              "imageUrls": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Product image URLs from the viewer."
              },
              "delivery": {
                "type": "string",
                "description": "Delivery text."
              },
              "shipping": {
                "type": "string",
                "description": "Shipping text (e.g. Free)."
              },
              "shippingValue": {
                "type": "number",
                "description": "Numeric shipping cost when known."
              },
              "availability": {
                "type": "string",
                "description": "Availability text."
              },
              "condition": {
                "type": "string",
                "description": "Condition when Google shows one."
              },
              "returns": {
                "type": "string",
                "description": "Returns policy text."
              },
              "isSponsored": {
                "type": "boolean",
                "description": "True only when an explicit sponsored label was observed. Not a reliable ad classifier."
              },
              "productId": {
                "type": "string",
                "description": "Real Google Shopping product ID from data-pid."
              },
              "catalogId": {
                "type": "string",
                "description": "Real Google Shopping catalog ID from data-cid; used to build viewer URLs."
              },
              "productUrl": {
                "type": "string",
                "description": "Real Google Shopping product viewer URL."
              },
              "searchUrl": {
                "type": "string",
                "description": "URL that produced the record."
              },
              "hasMoreOffers": {
                "type": "boolean",
                "description": "True when Google reports more seller offers than the five on the viewer page."
              },
              "badge": {
                "type": "string",
                "description": "Observed badge such as Best price or Low price."
              },
              "offerCount": {
                "type": "integer",
                "description": "Total offer count reported by Google; only the first five offers are available over HTTP."
              },
              "offers": {
                "type": "array",
                "description": "First five seller offers from the product viewer.",
                "items": {
                  "type": "object",
                  "properties": {
                    "seller": {
                      "type": "string"
                    },
                    "sellerId": {
                      "type": "string"
                    },
                    "sellerUrl": {
                      "type": "string"
                    },
                    "sellerDomain": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "price": {
                      "type": "string"
                    },
                    "priceValue": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "originalPrice": {
                      "type": "string"
                    },
                    "originalPriceValue": {
                      "type": "number"
                    },
                    "discountPercent": {
                      "type": "number"
                    },
                    "shipping": {
                      "type": "string"
                    },
                    "delivery": {
                      "type": "string"
                    },
                    "shippingValue": {
                      "type": "number"
                    },
                    "totalPrice": {
                      "type": "number"
                    },
                    "totalPriceDisplay": {
                      "type": "string"
                    },
                    "availability": {
                      "type": "string"
                    },
                    "returns": {
                      "type": "string"
                    },
                    "storeRating": {
                      "type": "number"
                    },
                    "storeReviewCount": {
                      "type": "integer"
                    },
                    "badge": {
                      "type": "string"
                    },
                    "isBestPrice": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "lowestPrice": {
                "type": "number",
                "description": "Lowest price among the offers on the page."
              },
              "highestPrice": {
                "type": "number",
                "description": "Highest price among the offers on the page."
              },
              "priceRange": {
                "type": "object",
                "description": "Low/high price range across page offers.",
                "properties": {
                  "low": {
                    "type": "number"
                  },
                  "high": {
                    "type": "number"
                  },
                  "currency": {
                    "type": "string"
                  }
                }
              },
              "typicalPriceRange": {
                "type": "object",
                "description": "Typical price range reported by Google, when shown.",
                "properties": {
                  "low": {
                    "type": "number"
                  },
                  "high": {
                    "type": "number"
                  },
                  "display": {
                    "type": "string"
                  },
                  "currency": {
                    "type": "string"
                  }
                }
              },
              "priceHistory": {
                "type": "array",
                "description": "Per-seller daily price history for the last 12 months, when Google exposes it.",
                "items": {
                  "type": "object",
                  "properties": {
                    "seller": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string"
                          },
                          "price": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "specifications": {
                "type": "array",
                "description": "Product specifications from the viewer.",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              },
              "variants": {
                "type": "array",
                "description": "Product variants exposed by the viewer.",
                "items": {
                  "type": "object",
                  "properties": {
                    "title": {
                      "type": "string"
                    },
                    "price": {
                      "type": "string"
                    },
                    "priceValue": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "imageUrl": {
                      "type": "string"
                    },
                    "productUrl": {
                      "type": "string"
                    }
                  }
                }
              },
              "discussions": {
                "type": "array",
                "description": "Forum/discussion links about the product (not product review text).",
                "items": {
                  "type": "object",
                  "properties": {
                    "title": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string"
                    }
                  }
                }
              },
              "dealFlags": {
                "type": "object",
                "description": "Observed deal signals.",
                "properties": {
                  "onSale": {
                    "type": "boolean"
                  },
                  "bestPrice": {
                    "type": "boolean"
                  }
                }
              },
              "scrapedAt": {
                "type": "string",
                "description": "ISO 8601 collection timestamp."
              }
            }
          },
          "views": {
            "overview": {
              "title": "Products Overview",
              "transformation": {
                "fields": [
                  "query",
                  "position",
                  "title",
                  "price",
                  "currency",
                  "merchant",
                  "rating",
                  "reviewCount",
                  "recordType"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "query": {
                    "label": "Query",
                    "format": "text"
                  },
                  "position": {
                    "label": "#",
                    "format": "number"
                  },
                  "title": {
                    "label": "Product",
                    "format": "text"
                  },
                  "price": {
                    "label": "Price",
                    "format": "text"
                  },
                  "currency": {
                    "label": "Currency",
                    "format": "text"
                  },
                  "merchant": {
                    "label": "Merchant",
                    "format": "text"
                  },
                  "rating": {
                    "label": "Rating",
                    "format": "text"
                  },
                  "reviewCount": {
                    "label": "Reviews",
                    "format": "text"
                  },
                  "recordType": {
                    "label": "Type",
                    "format": "text"
                  }
                }
              }
            },
            "offers": {
              "title": "Offers and Price History",
              "transformation": {
                "fields": [
                  "title",
                  "offerCount",
                  "lowestPrice",
                  "highestPrice",
                  "typicalPriceRange",
                  "offers",
                  "priceHistory",
                  "productUrl"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "title": {
                    "label": "Product",
                    "format": "text"
                  },
                  "offerCount": {
                    "label": "Offers",
                    "format": "number"
                  },
                  "lowestPrice": {
                    "label": "Lowest",
                    "format": "number"
                  },
                  "highestPrice": {
                    "label": "Highest",
                    "format": "number"
                  },
                  "typicalPriceRange": {
                    "label": "Typical",
                    "format": "text"
                  },
                  "offers": {
                    "label": "Page Offers",
                    "format": "text"
                  },
                  "priceHistory": {
                    "label": "History",
                    "format": "text"
                  },
                  "productUrl": {
                    "label": "Viewer",
                    "format": "link"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "1.0.2",
    "imageDigest": "b202877beb13be5276ff246337d4077b805ba56593e204f0ab9afa0537ccdace",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.017794444444444446
    }
  }
}