How to Scrape Instacart Grocery Prices Across 70+ Retailers

If you want to scrape Instacart for grocery price monitoring, cross-retailer comparison, or CPG market research, this guide walks you through the entire process. You will learn what data you can extract from Instacart product pages, retailer storefronts, and cross-retailer search, and how to turn it into a grocery price feed spanning dozens of US chains at once.
Why Scrape Instacart Data?
Instacart is not a grocery store — it is the aggregation layer sitting on top of the US grocery industry. More than 70 retailers list their catalogs there: Costco, Safeway, Walmart, Target, Kroger, Publix, Sprouts, Wegmans, Whole Foods, and dozens of regional chains. Each one exposes product names, brands, sizes, images, prices, sale prices, and availability behind a single consistent URL structure.
That aggregation is the whole point. Scraping Kroger, Publix, and Costco individually means writing and maintaining three separate scrapers against three unrelated frontends, each with its own anti-bot posture. Scraping Instacart means writing one — and getting all three, plus 70 more, in the same schema. For anyone doing grocery price intelligence, that is a step change in how much of the market you can cover per unit of engineering effort.
Businesses and researchers scrape Instacart data for a range of purposes:
- Cross-retailer price comparison — see what the same SKU costs at Costco vs. Safeway vs. Target in one dataset, without normalizing three different schemas
- CPG brand monitoring — track how your products are priced, sized, and merchandised across every retailer that carries them
- Promotion and discount tracking — the
fullPriceStringfield exposes the pre-discount price, so you can measure real promo depth rather than inferring it - Availability and out-of-stock monitoring — catch stockouts across a retailer network before they show up in sales data
- Private-label analysis — compare Kirkland Signature, Great Value, and Good & Gather against national brands on price per size
- Dietary and attribute research — Instacart tags products with dietary attributes, making it straightforward to size categories like gluten-free, organic, or keto
Manual collection is hopeless here. A single retailer storefront carries thousands of SKUs, prices move weekly with promo cycles, and there are 70+ retailers. Automation is the only realistic approach.
What Data You Can Extract from Instacart
The Grocery Product Scraper for Instacart returns one record per product, with an identical shape regardless of whether the product came from a product page, a storefront, or a search result. Here are the key fields:
| Field | Description | Example |
|---|---|---|
| Product ID | Instacart's product identifier | 20630136 |
| Retailer slug | Which retailer this price belongs to (null on unscoped search results) | walmart |
| Name | Product name as listed | Great Value 2% Reduced Fat Milk |
| Brand | Brand name | Great Value |
| Size | Pack size or unit | 128 oz |
| Category | Instacart's category for the product | Plain Milk |
| Price | Current numeric price | 3.48 |
| Price string | Price exactly as displayed | $3.48 |
| Full price string | Pre-discount price when the item is on sale | $11.94 |
| Currency | ISO currency code | USD |
| Availability | Stock state | InStock |
| Dietary attributes | Tags such as organic, gluten-free, vegan | ["Organic"] |
| Image | Product image URL | d2lnr5mha7bycj.cloudfront.net/... |
| Source | Where the record came from | pdp / storefront / search |
| Postal code | Location context for the price | 94105 |
| Scraped at | ISO timestamp of extraction | 2026-05-23T06:26:03.293Z |
The source field is more useful than it looks. Because storefront and search records are cheaper to collect but shallower than product pages, knowing the provenance of each row lets you decide which records to trust for which analysis — and which ones to re-scrape at full depth.
Common Use Cases for Instacart Data
Cross-Retailer Price Comparison
This is the flagship use case, and it is one Instacart is uniquely suited to. Run a cross-retailer search for a product term and you get the same item priced across several chains in one pass, already normalized into a single schema. Doing that from the retailers' own sites would mean maintaining a parser per chain and reconciling incompatible product identifiers.
CPG Brand and Distribution Monitoring
If you are a brand, Instacart tells you where you are actually on shelf. Sweep the storefronts of every retailer that should carry your SKUs and check which ones return your products, at what price, in what size, and with what availability. Gaps in the results are distribution gaps.
Promotion Depth Tracking
price and fullPriceString together give you real promo depth rather than a guess. Scraping on a schedule turns that into a promo calendar — which retailers discount which categories, how deep, and how often. For a category manager, that is the single most actionable grocery dataset there is.
Private-Label vs. National Brand Analysis
Retailer private labels — Kirkland Signature, Great Value, Good & Gather, 365 — are the fastest-moving segment in US grocery. Because brand and size come back as separate fields, computing price-per-unit and comparing private label against national brands within a category is straightforward.
Stockout and Availability Monitoring
The availability field, scraped daily across a retailer network, surfaces stockouts as they happen. For suppliers this is early warning that something has gone wrong in the supply chain, weeks before it shows up in sell-through reporting.
Dietary and Category Sizing
Instacart tags products with dietary attributes. Sweep a category, group by attribute, and you have a defensible estimate of how much shelf space organic, gluten-free, or plant-based products actually occupy in a given chain.
Challenges of Scraping Instacart Manually
Before jumping into the tutorial, it is worth understanding why building your own Instacart scraper is harder than it looks:
- The data lives in Apollo state, not HTML — Instacart is a React application that embeds its product data in a serialized Apollo client cache plus JSON-LD blocks. Naïve CSS-selector scraping returns almost nothing useful
- Three different page shapes — product detail pages, retailer storefronts, and cross-retailer search each serialize their payload differently and need separate parsers that emit a common schema
- Location-dependent pricing — Instacart prices and availability vary by ZIP, so a price without its location context is meaningless. Any serious pipeline has to record the market alongside every row
- Retailer-scoped product identity — the same physical product has different Instacart records per retailer. Deduplicating across chains requires matching on brand plus size, not on ID
- Inconsistent field values — Instacart's own payloads mix conventions in the availability field (
InStock,inStock,highlyInStock), and retailer association is absent on some search results, so both have to be normalized downstream - Page-size limits — storefronts surface roughly 32 featured items and cross-retailer search returns about 14 per query on the first server-rendered page. Building broad coverage means orchestrating many small requests rather than paginating one big one
- Maintenance burden — Instacart ships frontend changes continuously, and each one can move the shape of the embedded state
For most use cases, a pre-built and maintained scraper is dramatically more practical than building one in-house.
Step-by-Step: How to Scrape Instacart
Here is how to scrape Instacart grocery data using the Grocery Product Scraper for Instacart on Apify.
Step 1 — Choose Your Input Mode
Every input field is optional and they can be combined freely in a single run. There are five ways to point the scraper at products:
retailerSlugs— the simplest broad sweep. Pass["costco", "safeway", "target"]and the scraper walks each storefront and enqueues its featured products as full product pagessearchQueries— free-text terms run against Instacart's cross-retailer search, returning the same product across multiple chains. This is the input to use for price comparisonstartUrls— any mix of Instacart URLs: product pages (/products/...), storefronts (/store/{retailer}), or search (/store/s?k=...)productIds— fetch specific products directly by ID, optionally scoped to a retailer withdefaultRetailerSlug. This is the input for tracking a known SKU list over timeseedFromHome— set totrueto pull every retailer storefront linked from Instacart's homepage. Use this for exploratory sweeps when you do not yet know which retailers you care about
Step 2 — Configure the Scraper Input
Head to the Grocery Product Scraper for Instacart on Apify and configure your run:
- Pick your input mode — retailer slugs, search queries, start URLs, or product IDs
- Set
maxItemsto cap the number of products (default50; set0for unlimited) - Set
postalCodeto the market you are studying — this is recorded on every record so your dataset always carries its location context - Optionally enable a US proxy under
proxyConfigurationfor more accurate location defaults
Example input for a cross-retailer price comparison:
{
"retailerSlugs": ["costco", "safeway", "target"],
"searchQueries": ["milk", "eggs", "olive oil"],
"maxItems": 500,
"postalCode": "10001",
"proxyConfiguration": { "useApifyProxy": false }
}
And for tracking a known SKU list at one retailer:
{
"productIds": ["7079", "20630136"],
"defaultRetailerSlug": "safeway",
"maxItems": 0
}
One important caveat on ZIP codes. The postalCode field is recorded against every item so your data is always self-describing, but the scraper does not currently inject it into requests — Instacart serves its default market (94105, San Francisco) unless your traffic originates elsewhere. If you need prices for a specific metro, route the run through a proxy in that region and set postalCode to match. Treat the field as a label on your data, not as a location switch.
Step 3 — Run the Scraper
Once started, the scraper will:
- Resolve each input into concrete Instacart requests and classify them as product page, storefront, or search
- Fetch every page over plain HTTP with a Cheerio-based crawler — no headless browser, so runs are fast and cheap
- Parse the embedded Apollo client state and JSON-LD blocks to recover the full product payload
- Enqueue featured products from each storefront as full product pages for deeper data
- Emit one record per product in a single consistent schema, tagged with its
sourceandpostalCode - Stop cleanly at your
maxItemscap
Step 4 — Export Your Results
When the run finishes, export your data in the format you need:
- JSON — ideal for developers building price-comparison or monitoring pipelines
- CSV / Excel — perfect for pivot-table analysis of price by retailer and category
- XML / HTML / RSS — useful for feeds and reporting workflows
- API — pull results programmatically via the Apify API for scheduled runs
Ready to try it? Run the Instacart scraper on Apify and get your first dataset in minutes.
Example Output (Real Data Preview)

Here is a product-page record, with source set to pdp:
{
"id": "items_88059-20630136",
"productId": "20630136",
"retailerSlug": "walmart",
"url": "https://www.instacart.com/products/20630136-great-value-2-reduced-fat-milk-1-gal?retailerSlug=walmart",
"name": "Great Value 2% Reduced Fat Milk",
"brand": "Great Value",
"size": "128 oz",
"image": "https://d2lnr5mha7bycj.cloudfront.net/product-image/file/large_5c855497.jpeg",
"category": "Plain Milk",
"description": null,
"price": 3.48,
"priceString": "$3.48",
"fullPriceString": null,
"priceCurrency": "USD",
"availability": "InStock",
"dietaryAttributes": [],
"source": "pdp",
"postalCode": "94105",
"scrapedAt": "2026-05-23T06:26:03.293Z"
}
And a storefront record for a discounted Costco item, where fullPriceString exposes the pre-discount price:
{
"id": "items_74-20110703",
"productId": "20110703",
"retailerSlug": "costco",
"name": "Kirkland Signature Mini Chocolate Chip Cookies, 60-count",
"brand": "kirkland signature",
"size": "each",
"price": 9.94,
"priceString": "$9.94",
"fullPriceString": "$11.94",
"priceCurrency": "USD",
"availability": "inStock",
"dietaryAttributes": [],
"source": "storefront",
"postalCode": "94105",
"scrapedAt": "2026-05-23T06:26:04.891Z"
}
Key things to notice:
priceis numeric,priceStringpreserves the display value — you get a clean field for math without losing the original for auditingfullPriceStringis the promo signal — when it is populated, the item is discounted, and the gap between it andpriceis the real promo depthretailerSlugis what makes comparison a group-by — it is populated whenever the record is scoped to a retailer (product pages opened with?retailerSlug=, and everything from a storefront sweep). Cross-retailer search results can come back with itnull, because those items are not tied to one chain — so scope your comparison runs throughretailerSlugsor retailer-scoped URLs rather than bare searchsourcetells you the provenance — product-page records are the deepest; storefront and search records are shallower but far cheaper to collectavailabilityis not a clean enum — Instacart returns several spellings and gradations, includingInStock,inStock, andhighlyInStock. Lowercase and bucket these before filtering rather than matching exact stringspostalCodeandscrapedAtmake rows self-describing — a grocery price without a market and a timestamp is not worth storing
Try the Instacart scraper now — no coding required.
Automating Instacart Data Collection
Grocery pricing is a moving target, so this is a scraper that earns its keep on a schedule.
Scheduled Runs
Grocery promo cycles are weekly, and most chains reset on the same weekday. A daily run captures every price change with a day's resolution, which is enough to reconstruct the promo calendar for any category you track. For fast-moving fresh categories, or during major holiday promo periods, twice-daily runs are worth the marginal cost.
The compounding value here is the archive. Instacart shows you today's price; a scheduled scrape gives you the last two years of them.
API Integration
Use the Apify API to trigger runs programmatically and retrieve results:
- Feed prices into a category-management or revenue-growth-management dashboard
- Alert when a competitor discounts below your floor in a tracked category
- Sync cross-retailer price data into a BI warehouse for elasticity modelling
- Connect to Zapier, Make, Google Sheets, or Slack for no-code workflows
Node.js Example
For a complete working example showing how to call this scraper from Node.js — including a combined retailer-storefront sweep and cross-retailer search — see the GitHub repository.
Webhooks
Configure webhooks to fire when a run completes, so downstream processing starts as soon as new pricing lands rather than on a polling timer.
Using Instacart Data for Business Intelligence
Price Index by Retailer
Scrape a fixed basket of SKUs across every retailer weekly and compute a price index per chain. This is the grocery industry's own core metric, and building it yourself takes one scheduled run and a group-by.
Promo Depth and Cadence
Group discounted rows — those with a populated fullPriceString — by retailer, category, and week. The result is a map of who promotes what, how deeply, and how often. Brands use this to plan trade spend; retailers use it to benchmark against competitors.
Price Per Unit Normalization
size and price together let you compute price per ounce or per count, which is the only fair way to compare a Costco bulk pack against a Safeway single. Private-label price gaps only become visible after this normalization.
Assortment Overlap Between Chains
Compare the product sets returned for the same category across retailers to see how much assortment overlap exists. Low overlap means each chain is differentiating on selection; high overlap means the category competes purely on price.
Availability as a Supply-Chain Signal
Track availability over time per SKU per retailer. A product going out of stock at several chains at once is a supply signal, not a merchandising one — and it usually leads reported sales data by weeks.
Does Instacart Provide an API?
Instacart does run developer programs, but none of them is a general-purpose data source.
What's Available
- Instacart Connect — the enterprise platform retailers use to power their own e-commerce and fulfillment on Instacart's infrastructure. It requires a commercial agreement and is scoped to your own business's data
- Instacart Developer Platform — the partner-facing API for shoppable recipes and product links, aimed at publishers and app developers rather than analysts
- Neither program exposes an open, self-serve product-catalog endpoint you can query across retailers
What the APIs Miss
The gap is structural. Instacart's programs are built for participants in its commerce ecosystem — retailers running storefronts, brands buying ads, publishers linking to carts. They are not built for someone who wants to observe the market from outside, and access is gated behind partnership approval either way.
The cross-retailer price comparison that makes Instacart interesting as a dataset is precisely what no partner API will hand you, because it means seeing other retailers' prices. That data is nonetheless public on the site, visible to any shopper without logging in. The Grocery Product Scraper for Instacart reads it the way a shopper would and returns it as structured records.
Why Use an Instacart Scraper Instead of Building One
Building a custom Instacart scraper sounds straightforward until you actually start:
- Apollo state parsing — the product data is in a serialized GraphQL client cache, and recovering a clean record from it requires understanding Instacart's internal data model, not just its HTML
- Three parsers, one schema — product pages, storefronts, and search all serialize differently and must be normalized into a single output shape or the dataset is unusable
- Cross-retailer identity — matching the same product across chains needs brand-plus-size logic, because product IDs are retailer-scoped
- Location handling — prices are ZIP-dependent, so every row needs a market recorded against it or the dataset silently mixes incomparable numbers
- Request orchestration — with ~32 items per storefront and ~14 per search page, breadth comes from many small requests, which means queue management rather than simple pagination
- Frontend churn — Instacart ships changes continuously, and each one is a maintenance ticket for a homegrown scraper
- Opportunity cost — every hour spent reverse-engineering Apollo state is an hour not spent on the pricing analysis the scraper exists to support
Unless you have requirements no existing tool can meet, a maintained scraper lets you focus on the analysis instead of the plumbing.
Pricing — Pay Only for Results
The Grocery Product Scraper for Instacart uses Apify's Pay-Per-Event pricing model. You pay per product that lands in your dataset — failed pages and retries are free.
| Event | When it's charged | Price per event | Per 1,000 products |
|---|---|---|---|
product | Each product written to the dataset, whether from a product page, storefront, or search | $0.005 | $5.00 |
Actor start | Once per run, per GB of memory | $0.00005 | negligible |
Quick cost estimates:
- A 500-product cross-retailer comparison run → $2.50
- 1,000 products swept across three retailer storefronts → $5.00
- A daily 200-SKU price tracker → $1.00/day, about $30/month
Because pricing is flat per product regardless of source, the cheapest way to build breadth is storefront and search sweeps, and the cheapest way to build depth is a targeted productIds list you re-scrape on a schedule. Most production setups do both: a wide monthly sweep to discover SKUs, and a narrow daily run to track the ones that matter.
New Apify accounts include free monthly usage credits, so you can validate the output before spending anything.
Try the Instacart Scraper
The Grocery Product Scraper for Instacart extracts structured grocery data across 70+ US retailers — product IDs, retailer, name, brand, size, category, image, price, pre-discount price, currency, availability, dietary attributes, source type, and postal-code context.
What you get:
- 70+ US grocery retailers in one schema — Costco, Safeway, Walmart, Target, Kroger, Publix, Sprouts, Wegmans, Whole Foods, and more
- Five input modes — retailer slugs, search queries, start URLs, product IDs, or a homepage sweep — combinable in a single run
- Cross-retailer search that returns the same product priced across multiple chains in one pass
- Promo depth via the pre-discount
fullPriceStringfield - Fast plain-HTTP extraction with no browser overhead
- Pay-Per-Event pricing:
$5.00 / 1,000products — you only pay for results - Scheduled runs, webhooks, and API access for ongoing intelligence
- No coding, no proxy management, no scraper maintenance
Start scraping Instacart now — your first run takes less than 5 minutes to set up.
If you are building a retail price-intelligence pipeline, combine Instacart data with Walmart for direct retail pricing, Just Eat for the food-delivery side of the same basket, or work through the e-commerce scraping guide for the broader pipeline picture.
Legal and Ethical Considerations
Web scraping occupies a well-established legal space, but responsible practice matters:
- Public data only — the scraper extracts publicly visible product information that anyone can see by visiting instacart.com. No login or authentication is required
- No personal data — grocery product listings contain no personal information. This is catalog and pricing data, not consumer data
- Respect rate limits — the scraper paces its requests rather than hammering Instacart's servers, and uses lightweight HTTP requests instead of rendering full browsers
- No misuse — use the data for legitimate purposes like price research, category analysis, and availability monitoring. Do not use it to misrepresent retailer pricing to consumers
- Compliance — if you operate in a regulated jurisdiction, ensure your storage and processing practices comply with local requirements
Instacart product listings are public commerce data — they exist to be found by shoppers and indexed by search engines. Using them for price research and market intelligence is consistent with how the platform is designed to work.
Disclaimer: This scraper is an independent tool and is not affiliated with, endorsed by, or sponsored by Instacart or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.
Frequently Asked Questions
Is scraping Instacart legal?
Scraping publicly available data from Instacart is generally legal. Product pages, retailer storefronts, and search results are visible to anyone who visits instacart.com without logging in. You should use the data responsibly, comply with applicable privacy regulations, and avoid overloading Instacart's servers with excessive requests.
Does Instacart have a public API?
No. Instacart's developer programs — Instacart Connect and the Instacart Developer Platform — are partner offerings that require a commercial agreement, and they are built for retailers, brands, and integration partners rather than for market research. There is no open product-catalog API, which makes scraping the public site the practical alternative.
Which retailers can I scrape through Instacart?
Instacart aggregates 70+ US grocery retailers including Costco, Safeway, Walmart, Target, Kroger, Publix, Sprouts, Wegmans, and Whole Foods. The scraper accepts retailer slugs directly, so you can sweep several storefronts in a single run, or use cross-retailer search to pull the same product from multiple chains at once.
What data can be extracted from Instacart?
You can extract product IDs, retailer slug, product name, brand, size, category, image, description, current price, the pre-discount full price, currency, availability, dietary attributes, the source type (product page, storefront, or search), the postal-code context, and a scrape timestamp.
Do Instacart prices vary by ZIP code?
Yes. Instacart pricing and availability are location-dependent, and the same product can differ between markets. Every record carries a postalCode field so you always know which location context produced the price. Note that the scraper records this value rather than injecting it into requests, so results reflect Instacart's default market (94105, San Francisco) unless you route through a proxy in your target region.
How many products can I get per storefront or search?
A retailer storefront surfaces roughly 32 featured items, and a cross-retailer search returns about 14 items on the first server-rendered page. Breadth comes from combining many retailer slugs and search queries in one run rather than from deep pagination on a single page.
How much does the Instacart scraper cost?
The actor uses Apify's Pay-Per-Event pricing at $0.005 per product ($5.00 per 1,000 products), plus a negligible per-run start event. You only pay for products that actually land in your dataset.
About the Author
This guide was written by Piotr, a software engineer with hands-on experience building and maintaining web scrapers at scale. He develops and maintains a suite of data extraction tools on the Apify platform, helping businesses automate their data collection workflows.
Need help with your scraping project?
Book a free discovery call and let's scope your project together.
Book a Call