> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrapebadger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Shopping Offers by Barcode or Catalog ID

> Get multi-seller Google Shopping prices for a product looked up by its barcode (GTIN/UPC/EAN) or by its Google Shopping catalog ID.

# Shopping Offers by Barcode or Catalog ID

`/v1/google/shopping/offers` returns a product's Google Shopping **seller offers** — one entry per merchant `source`, each with its own `price` and merchant `link`. Identify the product one of two ways (exactly one is required):

* **`barcode`** — Google Shopping no longer matches raw GTIN/UPC/EAN codes, so the barcode is first **resolved to a product** via a Google web search, then the Shopping seller list is fetched.
* **`catalog_id`** — Google's own Shopping catalog identifier: what a Google Shopping product URL carries as `prds=catalogid:<id>`, and the `catalog_id` field on [Shopping Search](/google/shopping-search) tiles when Google exposes it there (for example `https://www.google.com/search?ibp=oshop&prds=catalogid:762120719996356571&gl=de&hl=de`). The seller list is read straight off Google's product page, every page of sellers fetched in parallel, so there is no resolve hop and no ambiguity about which product you get.

## Offers by Catalog ID

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://scrapebadger.com/v1/google/shopping/offers?catalog_id=762120719996356571&gl=de&hl=de" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  from scrapebadger import ScrapeBadger

  async with ScrapeBadger(api_key="YOUR_API_KEY") as client:
      result = await client.google.shopping.offers(catalog_id="762120719996356571", gl="de", hl="de")
      print(result["product_title"], result["total_offers"])
      for offer in result["offers"]:
          print(offer["source"], offer["price"]["extracted"], offer["link"])
  ```

  ```javascript Node.js theme={null}
  const result = await client.google.shopping.offers({
    catalog_id: "762120719996356571",
    gl: "de",
    hl: "de",
  });
  console.log(result.product_title, result.total_offers);
  ```
</CodeGroup>

```json theme={null}
{
  "catalog_id": "762120719996356571",
  "total_offers": 19,
  "product_title": "Fehn Mini-Spieluhr Schaf",
  "offers": [
    {
      "position": 1,
      "title": "Fehn Spieluhr Schaf Baby Love 18 cm natur",
      "source": "babymarkt.com de",
      "price": { "value": 12.6, "currency": "EUR", "extracted": "12,60 €" },
      "extracted_price": 12.6,
      "link": "https://www.babymarkt.com/de/p/fehn-spieluhr-schaf-baby-love-18-cm-105648/?variant=105648",
      "delivery": "Lieferung: 4,99 €",
      "extensions": ["Online auf Lager", "Lieferung: 4,99 €", "Rücknahme innerhalb von 14 Tagen"]
    }
  ]
}
```

`total_offers` is the number of sellers Google lists for the catalog entry; up to 60 are returned.

<Tip>
  The most reliable way to get a `catalog_id` is from a Google Shopping product URL (`prds=catalogid:<id>`). Shopping Search tiles carry it as `catalog_id` only when Google ships the identifier block on that SERP, so treat that field as optional.
</Tip>

## How Barcode Lookup Works

1. The barcode is validated (length + check digit). GTIN-8, UPC-A, EAN-13, and GTIN-14 are accepted.
2. A Google **web search** resolves the barcode to a product (the matched product name is returned as `resolved_query` / `product_title`).
3. A Google **Shopping** fetch for that product returns the per-merchant offers.

Because this performs **two Google fetches**, each call costs **14 credits**.

## Query Parameters

<ParamField query="barcode" type="string">
  Product barcode to look up. Accepts GTIN-8, UPC-A (12 digits), EAN-13, or GTIN-14. The check digit is validated — a malformed or checksum-failing barcode returns `422`. Exactly one of `barcode` / `catalog_id` is required.

  Example: `0711719541028`
</ParamField>

<ParamField query="catalog_id" type="string">
  Google Shopping catalog ID — `prds=catalogid:<id>` in a Google Shopping product URL (or the `catalog_id` on a Shopping Search tile when present). Exactly one of `barcode` / `catalog_id` is required.

  Example: `762120719996356571`
</ParamField>

<ParamField query="gl" type="string">
  Country to run the search and Shopping fetch in, as an ISO-3166 alpha-2 code. Controls which merchants and currency you see.

  Examples: `us`, `au`, `gb`, `de`
</ParamField>

<ParamField query="hl" type="string" default="en">
  Language code for the search and results.

  Examples: `en`, `de`, `fr`
</ParamField>

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://scrapebadger.com/v1/google/shopping/offers?barcode=0711719541028" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  from scrapebadger import ScrapeBadger

  async with ScrapeBadger(api_key="YOUR_API_KEY") as client:
      result = await client.google.shopping.offers(barcode="0711719541028", gl="us")
      print(result["product_title"])  # "Sony PlayStation 5 Console"
      for offer in result["offers"]:
          print(offer["source"], offer["price"]["extracted"])
  ```

  ```javascript Node.js theme={null}
  import { ScrapeBadger } from "scrapebadger";

  const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" });

  const result = await client.google.shopping.offers({ barcode: "0711719541028", gl: "us" });
  console.log(result.product_title); // "Sony PlayStation 5 Console"
  for (const offer of result.offers) {
    console.log(offer.source, offer.price.extracted);
  }
  ```
</CodeGroup>

Pass `gl` to scope to a regional marketplace — for example, an Australian Woolworths grocery barcode:

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://scrapebadger.com/v1/google/shopping/offers?barcode=9300633572457&gl=au" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  from scrapebadger import ScrapeBadger

  async with ScrapeBadger(api_key="YOUR_API_KEY") as client:
      result = await client.google.shopping.offers(barcode="9300633572457", gl="au")
  ```

  ```javascript Node.js theme={null}
  const result = await client.google.shopping.offers({
    barcode: "9300633572457",
    gl: "au",
  });
  ```
</CodeGroup>

## Response Shape

```json theme={null}
{
  "barcode": "0711719541028",
  "resolved_query": "Sony PlayStation 5 Console",
  "product_title": "Sony PlayStation 5 Console",
  "offers": [
    {
      "title": "PlayStation 5 Console (Slim)",
      "source": "Walmart",
      "price": { "value": 499.0, "currency": "USD", "extracted": "$499.00" },
      "link": "https://www.walmart.com/ip/PlayStation-5-Console/...",
      "rating": 4.8
    },
    {
      "title": "Sony PlayStation 5 Slim Disc Console",
      "source": "Best Buy",
      "price": { "value": 499.99, "currency": "USD", "extracted": "$499.99" },
      "link": "https://www.bestbuy.com/site/...",
      "rating": 4.7
    }
  ]
}
```

| Field | Description |
| - | - |
| `barcode` | The barcode you passed in, echoed back (barcode mode). |
| `catalog_id` | The catalog ID you passed in (catalog mode). |
| `total_offers` | Total sellers Google lists for the catalog entry (catalog mode). |
| `resolved_query` | The product query the barcode resolved to via Google web search. |
| `product_title` | The matched product's title. |
| `offers` | List of per-merchant Shopping offers. |
| `offers[].title` | The product title as listed by that merchant. |
| `offers[].source` | The merchant / seller name (e.g. `Walmart`, `Best Buy`). |
| `offers[].price.value` | Numeric price. |
| `offers[].price.currency` | ISO currency code. |
| `offers[].price.extracted` | The price as displayed, including symbol. |
| `offers[].link` | Link to the merchant's listing. |
| `offers[].delivery` | Shipping line as Google shows it (catalog mode). |
| `offers[].extensions` | Availability / shipping / returns lines (catalog mode). |
| `offers[].rating` | Product rating on that merchant, if shown. |

## Pricing

Each call costs **14 credits**, whichever identifier you pass.

## Errors

| Status | Meaning |
| - | - |
| `400` | Neither or both of `barcode` / `catalog_id` were passed. |
| `422` | The `barcode` is malformed or fails its check-digit validation. |
| `404` | The barcode could not be resolved to a product (no Google web-search match), or the catalog ID has no sellers. |

## Why This Exists

Google Shopping indexes by product, not by barcode — a GTIN/UPC/EAN typed directly into Shopping yields no matches. Resolving the barcode through a normal Google web search first finds the product page, and only then does a Shopping fetch return the seller offers. This endpoint packages that two-step flow into a single call so you can go straight from a barcode to live multi-seller prices.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.