# US Grocery Price Comparator (`hypebridge/us-grocery-price-comparator`) Actor

Compare grocery staple prices across 11 major US chains (Walmart, Target, Kroger & affiliates), normalized to unit prices ($/fl oz, $/oz, $/lb, $/count). Features store-brand equivalence, promo vs. regular price separation, private-label margin metrics, and a Whole-Basket Optimizer.

- **URL**: https://apify.com/hypebridge/us-grocery-price-comparator.md
- **Developed by:** [Hypebridge](https://apify.com/hypebridge) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.0133 / comparison row

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

Learn more: https://docs.apify.com/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

### What does US Grocery Price Comparator do?

**US Grocery Price Comparator** compares grocery staple prices across 11 US supermarket chains (Walmart, Target, Kroger, Fred Meyer, Ralphs, Harris Teeter, King Soopers, Fry's, Mariano's, Smith's and QFC) **at the stores nearest your ZIP code**. It matches equivalent products (Great Value ≈ Good & Gather ≈ Kroger), converts every price to a unit price ($/fl oz, $/oz, $/lb, $/count, $/gal), separates sale prices from shelf prices, and works out the cheapest way to fill a whole basket.

### Compare local grocery prices by ZIP code

Most price comparisons use one national online price. This Actor prices every store from **one ZIP code you choose**, so every number comes from a real store in the same neighbourhood.

- **One input, every store:** set `zipCode` and Walmart, Target and each Kroger-family banner resolve to the nearest store to that ZIP.
- **See exactly which store you are comparing:** each row carries `storeLocations` with the store ID, name, address and distance behind every price.
- **Prices really change by ZIP:** Walmart whole milk, 1 gallon, was $2.72 near Cincinnati (45202) and $3.83 near Portland, OR (97201).
- **No wrong-region prices:** a banner with no store within 25 miles of your ZIP (for example Fred Meyer in Ohio, or Ralphs outside Southern California) is skipped and shown as `null` in `storeLocations`. It is never filled in from another region.
- **Pick a ZIP that has your chains.** Kroger-family banners are regional: Fred Meyer and QFC in the Pacific Northwest, Ralphs in Southern California, King Soopers in Colorado, Fry's in Arizona, Smith's in the Mountain West, Mariano's in Chicagoland, Harris Teeter in the Mid-Atlantic and Carolinas. Walmart and Target cover nearly every ZIP.

### Why compare grocery prices?

- **Shoppers and families**: find the cheapest store for your weekly basket, or whether splitting the trip saves money.
- **Price and inflation tracking**: run the same basket on a schedule (USDA Thrifty Food Plan or a CPI-style core basket) for any metro area.
- **Retail and CPG analysts**: measure how much cheaper a store brand is than the national brand at the same store, and how prices spread across chains in a market.

### What data can it extract?

| Field | Type | Description |
|-------|------|-------------|
| `query` | String | The staple you searched for |
| `tier` | String | `store_brand`, `national_brand` or `organic` |
| `zipCode` | String | ZIP code every store was priced for |
| `storeLocations` | Object | Per store: `storeId`, `name`, address, city, state, ZIP (and `distanceMiles` for Walmart and Target). `null` = no store near the ZIP |
| `walmart`, `target`, `kroger`, … | Object | Matched product with `title`, `brand`, `stickerPrice`, `regularPrice`, `promoPrice`, `isOnSale`, `discountPercent`, `unitPrice`, `unit`, `inStock`, `url`, `imageUrl`, `sku`; `upc` for Kroger banners |
| `cheapestUnitStore` / `cheapestUnitPrice` | String / Number | Cheapest store per unit and its price |
| `priceSpreadPercent` | Number | How much more the most expensive store costs |
| `privateLabelSavingsPercent` | Number | How much cheaper the house brand is than the national brand |
| `status` | String | `OK` (2+ stores matched), `PARTIAL`, `NO_MATCH` or `CHILD_FAILED` |
| `market`, `currency`, `priceBasis` | String | Always `US`, `USD` and `local_store_zip` |

A whole-basket summary is saved as `BASKET_SUMMARY` in the Key-Value Store: total per store, item coverage, the **single-store winner**, and the **split-basket optimum** with the exact dollars saved by shopping at several stores.

### How to compare grocery prices near you

1. [Create a free Apify account](https://apify.com) if you don't have one.
2. Open **US Grocery Price Comparator** and click **Try for free**.
3. Enter your **ZIP code**.
4. Add grocery items (for example `whole milk 1 gallon`) or pick a **Preset Staple Basket**.
5. Choose the **stores** to compare and click **Start**. Download results from the **Dataset** tab (JSON, CSV, Excel, HTML) and the basket report from the **Key-Value Store**.

### How much will it cost?

Pay-per-event pricing:

| Event | Cost | When it is charged |
|-------|------|--------------------|
| `comparison-row` | **$0.02** ($0.0133 on the Gold plan) | Only when a row compares 2 or more stores (`status: "OK"`). `PARTIAL`, `NO_MATCH` and `CHILD_FAILED` rows are free |
| Actor start | $0.01 ($0.005 on Gold) | Once per run |

Looking up Walmart and Target prices also runs the [Walmart Product & Local Store Scraper](https://apify.com/hypebridge/walmart-product-scraper) and [Target Product & Local Store Scraper](https://apify.com/hypebridge/target-product-scraper) on your account, one run per item per store. At free-plan rates and 8 candidates per store that is about **$0.10 per item for Walmart and $0.07 for Target**, less on paid plans. A 15-item basket across Walmart and Target is roughly $2.50 in lookups. **Kroger-family banners cost $0 in lookups.** `maxChildSpendUsd` caps lookup spend; items past the cap are skipped.

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `zipCode` | String | `"45202"` | 5-digit US ZIP code. Every store is priced at the nearest store to it. Replaces the old `krogerZipCode` and `fredMeyerZipCode`, which are now ignored |
| `queries` | Array | `[]` | Grocery items to compare, up to 50 per run |
| `presetBasket` | String | `"none"` | `usda_thrifty_15`, `cpi_core_25`, `keto_10` or `baking_essentials_8`; merged with `queries` |
| `stores` | Array | `["walmart","target","kroger"]` | Any of `walmart`, `target`, `kroger`, `fred_meyer`, `ralphs`, `harris_teeter`, `king_soopers`, `frys`, `marianos`, `smiths`, `qfc` |
| `candidatesPerStore` | Integer | `8` | Search results inspected per store (3–12). Higher finds more store-brand matches |
| `matchMode` | String | `"all_tiers"` | `all_tiers`, `private_label_equivalent` or `exact_brand_only` |
| `maxChildSpendUsd` | Number | `5.0` | Cap on Walmart/Target lookup spend for the run (max 20) |

#### Example input

```json
{
  "zipCode": "97201",
  "queries": ["whole milk 1 gallon", "large white eggs 12 ct"],
  "stores": ["walmart", "target", "fred_meyer"],
  "candidatesPerStore": 8
}
```

#### More examples

A full USDA basket for a Denver household, Kroger-family banners only (no lookup cost):

```json
{
  "zipCode": "80203",
  "presetBasket": "usda_thrifty_15",
  "stores": ["king_soopers", "kroger"]
}
```

Store-brand versus national-brand check for one item in Phoenix:

```json
{
  "zipCode": "85004",
  "queries": ["salted butter 16 oz"],
  "stores": ["walmart", "target", "frys"],
  "matchMode": "private_label_equivalent",
  "maxChildSpendUsd": 1
}
```

### Output

Saved to the **Dataset** tab, one row per item and comparison tier. Download as JSON, CSV, Excel or HTML.

#### Sample output

```json
{
  "query": "whole milk 1 gallon",
  "tier": "store_brand",
  "market": "US",
  "currency": "USD",
  "priceBasis": "local_store_zip",
  "zipCode": "45202",
  "storeLocations": {
    "walmart": { "name": "Ft Wright Supercenter", "city": "Ft Wright", "state": "KY", "distanceMiles": 4.94 },
    "target": { "name": "UC Calhoun St", "city": "Cincinnati", "state": "OH", "distanceMiles": 1.55 },
    "kroger": { "name": "Kroger - Kroger On the Rhine", "city": "Cincinnati", "state": "OH" }
  },
  "walmart": { "title": "Great Value Whole Vitamin D Milk, Gallon", "stickerPrice": 2.72, "unit": "gal", "unitPrice": 2.72, "matchType": "PRIVATE_LABEL_EQUIVALENT" },
  "target": { "title": "Vitamin D Whole Milk - 1gal - Good & Gather", "stickerPrice": 2.89, "unit": "gal", "unitPrice": 2.89, "matchType": "PRIVATE_LABEL_EQUIVALENT" },
  "kroger": { "title": "Kroger Vitamin D Whole Milk Gallon", "stickerPrice": 3.29, "unit": "gal", "unitPrice": 3.29, "matchType": "PRIVATE_LABEL_EQUIVALENT" },
  "cheapestUnitStore": "walmart",
  "cheapestUnitPrice": 2.72,
  "priceSpreadPercent": 20.96,
  "status": "OK"
}
```

### Tips

- Use a ZIP where your chains operate. If a banner comes back `null` in `storeLocations`, it has no store within 25 miles of that ZIP.
- Run the same ZIP and basket on a schedule to track local grocery inflation over time.
- `inStock` is `null` when a store does not report stock; those items are still compared and shown as unknown. Items a store reports as out of stock are excluded.
- `auditRejections` explains every skipped candidate. `UNPRICED:PRICE_STORE_MISMATCH` means Target only had a price from a different store than your local one, so it was left out rather than shown.
- Walmart and Target listings do not include UPCs, so `upc` is only filled for Kroger-family banners.
- Sale prices are shown in `promoPrice` and `discountPercent`; they are empty when the matched product is not on sale.
- Start with 3–5 items to check cost before running a 25-item basket.

### Limitations

- One ZIP code per run; run the Actor once per city to compare cities.
- US stores only, in US dollars and US units.
- Prices are current online shelf prices for the resolved store; in-store promotions that are not listed online are not included.
- The nearest store is chosen automatically. Walmart's nearest store is a Supercenter, which can be a few miles farther than the closest smaller Walmart.
- Matching uses the top search results per store (`candidatesPerStore`), so a product ranked lower than that can be missed.

### FAQ

#### Are the prices local to my ZIP code?

Yes. Walmart, Target and Kroger-family prices come from the nearest store to your `zipCode`, and `storeLocations` tells you which store. Prices are the store's current online shelf price for that location.

#### Why is a store missing from my results?

Kroger-family banners are regional. If a banner has no store within 25 miles of your ZIP, it is skipped and `null` in `storeLocations`. Try a ZIP in that banner's region.

#### Can I compare stores in different cities?

One run uses one ZIP. To compare cities, run the Actor once per ZIP.

#### Is scraping grocery prices legal?

This Actor only extracts publicly available product and price data. Always check each site's Terms of Service and make sure you have a legitimate purpose.

#### Does it support stores outside the US?

No. It is US-only (USD, US customary units). Items naming non-US retailers or currencies, such as Tesco or EUR, are skipped with a warning.

### Support

- Bugs or feature requests: **Issues** tab
- Programmatic access: **API** tab

> **Disclaimer**: Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

# Actor input Schema

## `queries` (type: `array`):

Grocery staples to compare across supermarkets (e.g., 'whole milk 1 gallon', 'large white eggs 12 ct'). Max 50 items per run. Can be combined with or replaced by a Preset Staple Basket.

## `presetBasket` (type: `string`):

Optional pre-configured grocery basket for instant benchmarking or CPI/inflation tracking. Merged with any custom Grocery items above (up to 50 total).

## `stores` (type: `array`):

Supermarket chains to compare (11 supported banners). Every store is priced at the nearest store to your ZIP code. A banner with no store within ~25 miles of the ZIP is skipped (null in storeLocations) rather than priced from another region.

## `zipCode` (type: `string`):

5-digit US ZIP code. Walmart, Target and every Kroger banner are priced at the nearest store to this ZIP, so all prices come from the same neighbourhood. Kroger banners only exist in some regions (e.g. Fred Meyer in the Pacific Northwest); one with no store near the ZIP is skipped. Default: 45202 (Cincinnati, OH), where Walmart, Target and Kroger all have stores.

## `candidatesPerStore` (type: `integer`):

Number of search results inspected per store. Higher numbers improve store-brand matching accuracy.

## `matchMode` (type: `string`):

Choose matching strategy: all available tiers (store brand + national brand + organic), equivalent store private labels only, or exact national brands only.

## `krogerClientId` (type: `string`):

Optional custom Kroger OAuth2 client_id from developer.kroger.com. Falls back to default environment credentials.

## `krogerClientSecret` (type: `string`):

Optional custom Kroger OAuth2 client_secret from developer.kroger.com.

## `maxChildSpendUsd` (type: `number`):

Hard budget cap on pass-through Walmart/Target scraper charges for this run (about $0.10 per Walmart query and $0.07 per Target query at 8 candidates, free-tier rates). Queries beyond the cap are skipped. Kroger banners cost $0.

## Actor input object example

```json
{
  "queries": [
    "whole milk 1 gallon",
    "large white eggs 12 ct",
    "salted butter 16 oz"
  ],
  "presetBasket": "none",
  "stores": [
    "walmart",
    "target",
    "kroger"
  ],
  "zipCode": "45202",
  "candidatesPerStore": 8,
  "matchMode": "all_tiers",
  "maxChildSpendUsd": 5
}
```

# Actor output Schema

## `dataset` (type: `string`):

Complete dataset containing full item-level comparison rows, promo/regular prices, UPC/SKU metadata, and normalized unit math.

## `overview` (type: `string`):

Tabular comparison view highlighting cheapest store, unit price, savings, and price spread.

## `basketSummary` (type: `string`):

Aggregated basket cost per store, item coverage %, single-store winner, optimal split-basket trip savings, plus the ZIP code and the store each price came from.

# 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 = {
    "queries": [
        "whole milk 1 gallon",
        "large white eggs 12 ct",
        "salted butter 16 oz"
    ],
    "zipCode": "45202"
};

// Run the Actor and wait for it to finish
const run = await client.actor("hypebridge/us-grocery-price-comparator").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 = {
    "queries": [
        "whole milk 1 gallon",
        "large white eggs 12 ct",
        "salted butter 16 oz",
    ],
    "zipCode": "45202",
}

# Run the Actor and wait for it to finish
run = client.actor("hypebridge/us-grocery-price-comparator").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 '{
  "queries": [
    "whole milk 1 gallon",
    "large white eggs 12 ct",
    "salted butter 16 oz"
  ],
  "zipCode": "45202"
}' |
apify call hypebridge/us-grocery-price-comparator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hypebridge/us-grocery-price-comparator"
        }
    }
}
```

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/nUEb7Ln84LTvzTfEe/builds/0T7HNFrj3QxJ116F8/openapi.json
