# US Grocery Deals - Weekly Ad Prices by ZIP Code (`gratifying_graph/us-grocery-deals`) Actor

Current weekly ad deals from US grocery chains (Kroger, Safeway, Albertsons, Publix, H-E-B, ALDI, Target, Meijer and more) for any ZIP code. Search by product, compare prices across chains and ZIPs, track deals on a schedule.

- **URL**: https://apify.com/gratifying\_graph/us-grocery-deals.md
- **Developed by:** [Jimmy A](https://apify.com/gratifying_graph) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 deal results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## US Grocery Deals - Weekly Ad Prices from Every Major Chain by ZIP Code

Current **weekly ad deals from US grocery chains** for any ZIP code, normalized into one clean schema. Search by product, filter by chain, and compare prices across Kroger, Safeway, Albertsons, Publix, H-E-B, ALDI, Lidl, Meijer, Target, Stop & Shop, Wegman's, Fred Meyer, Food 4 Less, Sprouts and many regional chains - in a single run.

This actor reads the same public weekly ad data that shoppers see on the flyer aggregators. It is HTTP-first: no browser, no proxies, no login. Weekly ads are local, so you pass one or more ZIP codes and get the ads that actually run in each area.

### What you get

One record per deal:

```json
{
  "dealId": 1040416178,
  "query": "milk",
  "zipCode": "10001",
  "name": "SKIM PLUS MILK",
  "merchant": "Bravo Supermarket",
  "merchantId": 2806,
  "currentPrice": 5.99,
  "originalPrice": null,
  "currency": "USD",
  "priceText": null,
  "saleStory": null,
  "category": "Food, Beverages & Tobacco > Beverages",
  "brandIds": ["5411"],
  "flyerId": 8133904,
  "validFrom": "2026-09-18T04:00:00+00:00",
  "validTo": "2026-09-25T03:59:59+00:00",
  "imageUrl": "https://f.wishabi.net/page_items/433752774/1789389980/extra_large.jpg",
  "itemType": "flyer",
  "source": "Flipp public search (weekly ad data published by merchants)",
  "fetchedAt": "2026-09-23T19:08:30.659Z"
}
```

`currentPrice` and `originalPrice` are numeric where the ad gives a clean price. `priceText` keeps the raw per-unit text (e.g. `/lb`) and `saleStory` keeps the promo line (e.g. `BOGO`, `2 for $5`, loyalty offers) so nothing is lost. `validFrom`/`validTo` are the ad's run dates.

### Coverage

Tested in 12 metros in September 2026 (including New York, Boston, Atlanta, Chicago, Cincinnati, Dallas, Houston, Phoenix, Seattle, San Francisco and Los Angeles). Milk returned 11-47 deals per ZIP from 6-16 chains. Chicken returned 25-99 deals from 8-21 chains. Narrower terms return fewer. National chains (Target, ALDI, Dollar General, Kroger banners, Albertsons banners) plus the regional and independent grocers that publish weekly ads.

### Browse whole weekly ads (flyers mode)

Set `mode` to `flyers` to get every item of every weekly ad near each ZIP code, instead of searching by product. Filter by ad category (`categories`, default `["Groceries"]`), by chain (`merchants`), and optionally by words in the item name or brand (`queries`).

```json
{ "mode": "flyers", "zipCodes": ["10001", "60614"], "categories": ["Groceries"], "maxItems": 100 }
```

Categories come from Flipp: Groceries, Pharmacy, Home & Garden, General Merchandise, Pets, Electronics, Specialty, Sporting Goods, Automotive, Fashion. In a September 2026 test, 10001 (New York) had 33 grocery ads and 60614 (Chicago) had 38. An ad holds roughly 50-100 priced items, so a full metro sweep runs to thousands of items. Each ZIP stops at `maxItems` (default 200, about $0.40 at $0.002 per item).

Flyers-mode rows add `mode: "flyers"`, `brand`, `discount` (as Flipp publishes it), `flyerName` and `flyerCategories`. They have no `priceText` or `saleStory`, because the ad source does not carry them.

### Filters

- **zipCodes** (required): one or more 5-digit US ZIP codes, e.g. `10001`. ZIP+4 is accepted and trimmed. Each ZIP is searched for every term, so you can compare the same product across cities in one run.
- **queries** (required): one or more product terms (`milk`, `eggs`, `chicken`, `diapers`). One search per term per ZIP.
- **merchants**: only keep these chains (case-insensitive substring, punctuation ignored, so `Wegmans` matches `Wegman's`). Empty = all chains.
- **maxItemsPerQuery**: cap deals per search term per ZIP. The source returns at most 150 items per term.
- **onlyWithPrice**: skip image-only promos that carry no parseable price (default true).

### Use cases

- **Price comparison apps**: cheapest eggs across every chain near a shopper this week
- **Deal alerts**: run on a schedule, diff against last week, notify on a target price
- **Meal-planning and budgeting tools**: pull this week's deals for a shopping list by ZIP
- **Market and CPG research**: track promo depth and frequency by brand, chain, and metro over time
- **AI agents**: ask "what milk deals are near 60614 this week" through the standby API endpoint

### API / Standby mode for AI agents

Call the actor as a synchronous HTTP endpoint:

```
GET /?zip=60614&q=milk&merchant=Jewel
```

Browse mode works the same way:

```
GET /?zip=10001&mode=flyers&category=Groceries&maxItems=50
```

Returns `{ count, deals: [...] }` immediately. Works as a tool for agent frameworks that support Apify actors.

Base URL: `https://gratifying-graph--us-grocery-deals.apify.actor`. Add your Apify API token as `?token=YOUR_TOKEN` or an `Authorization: Bearer YOUR_TOKEN` header. Invalid input returns HTTP 400 and is not charged.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Actor start | $0.0005 |
| Per deal record | $0.002 |
| API call (standby) | $0.02 |

A daily check of three products in one ZIP returns roughly 50-170 deals, about $3-10/month. Many products or many ZIP codes scale linearly - tell us your use case if you need a snapshot tier.

### FAQ

**Where does the data come from?**
The public flyer search backend used by US weekly ad aggregators - the same ads the chains publish for shoppers each week. The actor reads logged-out, public, non-personal data only.

**Are these in-store shelf prices?**
No. These are advertised weekly ad prices for the stated validity window. Regular shelf prices are not part of weekly ad data.

**Why do I need a ZIP code?**
Weekly ads are regional. A deal in Chicago may not run in Dallas, and the same chain ships different ads by area.

**Why reject some ZIP codes?**
The source returns a generic fallback set for a malformed or unassigned ZIP instead of an error. The actor rejects malformed ZIPs and unassigned ranges (below 00501) before charging. A real ZIP with no weekly ads returns 0 deals.

**Why do some deals show a bundle price?**
Multi-buy offers like `2/$5` or `BOGO` keep the bundle total in `currentPrice`. The multiplier is in `priceText`. Check it before comparing unit prices.

**What does onlyWithPrice skip?**
Ad clippings with no price. Most have no product name either.

**Canada?**
Use the sibling actor [Canada Grocery Deals](https://apify.com/gratifying_graph/canada-grocery-deals) - same schema, postal codes, EN + FR.

**CSV export?**
Every Apify dataset exports as CSV, JSON, Excel, or via API.

### Feedback

Found a bug or need a field? Open an issue on the Issues tab. The actor is checked twice a day and issues get a fast fix.

If this actor saves you time, a short review on the Store page helps other people find it.

# Actor input Schema

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

search: find deals for your search terms (default). flyers: every item of every weekly ad near each ZIP code, filtered by ad category.

## `zipCodes` (type: `array`):

One or more US ZIP codes (e.g. 10001). Weekly ads are local, so deals differ by area. Each ZIP is searched for every term.

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

Products to search for (e.g. eggs, chicken, diapers). One search per term per ZIP. Required in search mode. In flyers mode, optional: only items whose name or brand contains a term are kept.

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

Only include these chains (case-insensitive substring, punctuation ignored, so Wegmans matches Wegman's). Empty = all chains. Works in both modes.

## `categories` (type: `array`):

Flyers mode only. Keep weekly ads in these Flipp categories: Groceries, Pharmacy, Home & Garden, General Merchandise, Pets, Electronics, Specialty, Sporting Goods, Automotive, Fashion. Empty = all categories.

## `maxItemsPerQuery` (type: `integer`):

Cap on the number of deals returned per search term per ZIP. The source returns at most 150 per term.

## `maxItems` (type: `integer`):

Flyers mode only. Stops after this many items per ZIP code. A full metro grocery sweep is thousands of items, so raise it on purpose.

## `onlyWithPrice` (type: `boolean`):

Skip ad items without a parseable price (e.g. image-only promos).

## Actor input object example

```json
{
  "mode": "search",
  "zipCodes": [
    "10001"
  ],
  "queries": [
    "milk",
    "eggs"
  ],
  "merchants": [],
  "categories": [
    "Groceries"
  ],
  "maxItemsPerQuery": 150,
  "maxItems": 200,
  "onlyWithPrice": true
}
```

# Actor output Schema

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

All deal records from this run (dataset items).

# 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 = {
    "zipCodes": [
        "10001"
    ],
    "queries": [
        "milk",
        "eggs"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gratifying_graph/us-grocery-deals").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 = {
    "zipCodes": ["10001"],
    "queries": [
        "milk",
        "eggs",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("gratifying_graph/us-grocery-deals").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 '{
  "zipCodes": [
    "10001"
  ],
  "queries": [
    "milk",
    "eggs"
  ]
}' |
apify call gratifying_graph/us-grocery-deals --silent --output-dataset

```

## MCP server setup

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

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/6q3WYqKCHGFmXU8NB/builds/Zh3C9CkUmFv6uk6cm/openapi.json
