Instacart Scraper icon

Instacart Scraper

Scrape Instacart grocery catalogs with per-store prices. Run keywords across several stores at once to compare what each banner charges, discover every…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

Instacart Scraper at a glance

Instacart Scraper is a ready-to-run Apify actor from abotapi for collecting ecommerce data. Its documented output includes product, change, brand, price and price (number), which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.40 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Ecommerce
Pricing
$2.40 per 1,000 results (Free plan), from $1.50 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
25 options
Run success
97.2% of completed public runs in the last 30 days

Scrape Instacart grocery catalogs with per-store prices. Run keywords across several stores at once to compare what each banner charges, discover every store serving a US location, or paste Instacart links. Returns name, brand, size, price, regular price, unit price, stock and full store detail.

What Instacart Scraper can do

  • Prices from several stores in one run. One keyword is run at every store you name, so the output is a price comparison rather than one store's list.
  • Every price carries its store. Banner, service type and store id ride on every row; the branch's street address also rides along when stores are named in the Stores field, because a grocery price without its store is not a fact about anything.
  • Real unit prices, where published. Price per ounce, pound or count, plus a unit price ordering, so different pack sizes are actually comparable when the store quotes them.
  • Sale detection that means something. onSale is set from the regular price the store is striking through, not guessed from a badge.
  • Store discovery built in. Ask which stores serve a postal code before you decide what to scrape, with departments, coordinates and postal addresses.
  • Change monitoring that names what moved. Schedule it and get only new and changed rows, with the changed fields named, so a price change is one row rather than a fresh catalog.

Choose what to collect

These inputs let you configure Instacart Scraper - Grocery Prices, Products & Stores. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · requiredChoose 'search' to run keywords against one or more stores and get each store's own prices, 'store' to list every store serving your location, or 'url' to scrape pasted Instacart links (store pages, search links, and product links are all accepted).

Choices: search, store, url

queriesarrayOne or more keywords to search, for example 'organic milk' or 'greek yogurt'. Each keyword is searched separately at each store. A narrower keyword returns fewer matches, so start broad and narrow down.
retailersarrayStore names as they appear in an Instacart address, for example 'costco', 'safeway', 'kroger', 'publix'. Copy one from a store page address: instacart.com/store/STORE-NAME/storefront. Leave empty to search EVERY store serving your location, which can be a few hundred stores, so set Max products before you do that.
urlsarrayMix freely: search links such as https://www.instacart.com/store/costco/s?k=milk , product links such as https://www.instacart.com/store/costco/products/19208138 , store pages such as https://www.instacart.com/store/safeway/storefront , or bare product ids such as 19208138. Department links (/collections/...) are refused by the source for this actor and are skipped with a message. A cross-store link such as https://www.instacart.com/store/s?k=milk searches every store at your location. A page=2 link returns the same results as page 1 (the source has no page cursor); duplicates are never emitted twice.
includeDepartmentsbooleanAdd each store's own department list (produce, dairy, frozen and so on) with the department link, to every store record. Costs one extra request per store.
postalCodestringThe US ZIP code to shop from, for example 10001. This alone is enough to run a search. Defaults to 10001 (Manhattan).
streetAddressstringOptional US street address, for example 2300 Griffin Road. It is geocoded to pick the stores around that exact point. Precedence: Latitude/Longitude if both are set, then this address, then the postal code. If the address cannot be located the postal code is used instead.
Show 18 more inputs
More input fields
InputWhat it controls
latitudenumberOnly needed for a point more precise than the postal code's own centre, or to shop from a different area than the postal code you gave. Leave empty to use the postal code's coordinates automatically. Must be set together with Longitude.
longitudenumberOnly needed for a point more precise than the postal code's own centre, or to shop from a different area than the postal code you gave. Leave empty to use the postal code's coordinates automatically. Must be set together with Latitude.
sortBystringOrdering. This is the source's own ordering, sent with the search request, so the results come back already ranked. Across several stores the combined list is re-ordered the same way.

Choices: bestMatch, priceAsc, priceDesc, unitPriceAsc, unitPriceDesc

inStockOnlybooleanKeep only products the store currently reports as available.
onSaleOnlybooleanKeep only products the store is currently discounting, that is, products showing a regular price above the current price.
minPriceintegerOptional. Keep only products priced at or above this amount. Products the store quoted no price for are excluded when this is set.
maxPriceintegerOptional. Keep only products priced at or below this amount. Products the store quoted no price for are excluded when this is set.
fetchDetailsbooleanAdd the source's own product category, the written description and the canonical product name to each product, by loading its product page. Costs one extra request per product and is charged per product. Nutrition panels are NOT promised: the source publishes them for only some products.
maxItemsintegerMaximum number of records to return across the whole run. This is the run's only cap. Use 0 for unlimited, but note that leaving Stores empty searches every store serving your location.
resumeFromRunIdstringPaste a previous run ID or dataset ID to continue a large crawl without returning or charging for records already collected there. Use this after an interrupted run. For recurring monitoring of the same search, use Incremental mode below instead.
incrementalModebooleanTurn this on for recurring price monitoring. The first run returns everything as NEW. Later runs return only NEW, UPDATED and REAPPEARED records, so a daily run shows you the price moves and nothing else. UPDATED is decided by comparing price, sale price, unit price, availability, stock level, name, brand, size, image and the other product fields; scrapedAt, sourceUrl, searchQuery and boughtCountLabel are never compared, image links are compared without their rotating CDN query string, and categories are compared as a set (use Ignore fields to exclude more). Turn on 'Emit unchanged' or 'Emit expired' only when you also want those rows returned (and billed). State is kept separately for each keyword, store, location and detail setup; use State key to name or deliberately share a campaign.
stateKeystringOptional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key from the keywords, stores, location and settings, so two different searches never mix state.
emitUnchangedbooleanOff by default. Turn on to also return products whose price and details have not moved since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.
emitExpiredbooleanOff by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced after a run that fully scanned the tracked search, so never when Max products capped it, when Resume was used, or when a keyword had more results than the source serves in one request, or when a filter (In stock only, On sale only, Min/Max price) is on, or when a pasted link starts past page 1. This returns, and bills, extra synthetic rows.
ignoreFieldsForChangesarrayOptional. Top-level field names to leave out of UPDATED change detection, on top of the built-in handling. Always left out: scrapedAt, sourceUrl, searchQuery and boughtCountLabel; image links are compared without their rotating CDN query string, and categories are compared as a set, so a reshuffle is not a change. Price, sale price, availability and stock level changes drive UPDATED. Use this if another field turns out to be noisy in your setup.
mcpConnectorsarrayOptionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page per item; other connectors get a best effort write or digest. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).
notionParentPageUrlstringURL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

nameProduct
changeTypeChange
brandBrand
priceStringPrice
pricePrice (number)
fullPriceRegular price
unitPriceStringUnit price
onSaleOn sale
sizeSize
availableIn stock
stockLevelLabelStock level
categoryCategory
Show 28 more fields
retailerNameStore
serviceTypeService
storeAddressStore address
dietaryAttributesDietary
productIdProduct id
imageImage (image)
productUrlProduct link (link)
searchQueryKeyword
changedFieldsChanged fields
firstSeenAtFirst seen
lastSeenAtLast seen
retailerTypeType
addressAddress
latitudeLatitude
longitudeLongitude
categoriesCategories
departmentCountDepartments
shopIdStore id
retailerSlugStore name
logoLogo (image)
storefrontUrlStore link (link)
descriptionDescription
canonicalNameCanonical name
unitCountUnit count
detailsDetails
seoDescriptionPage summary
detailImageDetail image (image)
detailAvailabilityDetail availability

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "recordId": "100000|items_500000-20000001",
  "itemId": "items_500000-20000001",
  "productId": "20000001",
  "name": "Store Brand Whole Milk, 1 Gallon, 2-count",
  "brand": "store brand",
  "size": "each",
  "priceString": "$8.94",
  "price": 8.94,
  "onSale": false,
  "available": true,
  "stockLevel": "highlyInStock",
  "stockLevelLabel": "Many in stock",
  "retailerName": "Costco",
  "retailerSlug": "costco",
  "retailerId": "900000",
  "shopId": "100000",
  "storeLocationId": "500000",
  "serviceType": "delivery",
  "storeAddress": "500 Example Ave, San Francisco, CA 94105",
  "image": "https://d2lnr5mha7bycj.cloudfront.net/product-image/file/large_00000000.jpg",
  "productUrl": "https://www.instacart.com/store/costco/products/20000001",
  "sourceUrl": "https://www.instacart.com/store/costco/s?k=organic+whole+milk",
  "category": "Plain Milk",
  "canonicalName": "Store Brand Homogenized Milk, 2 gal",
  "unitCount": "2",
  "searchQuery": "organic whole milk",
  "scrapedAt": "2026-09-29T06:01:44+00:00"
}

Ways to use this data

  • Grocery price comparison shoppers: run one keyword at every nearby store to find the cheapest banner before placing a delivery or pickup order.
  • Recipe and meal-planning apps: check ingredient prices and stock across retailers for a shopping list.
  • Retail and pricing analysts: track how prices and unit prices move store by store over time.
  • Coupon and deal-alert tools: watch a keyword list and get notified only when something goes on or off sale.
  • Researchers and market analysts: build a grocery price index across US postal codes.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does Instacart Scraper return?

The documented output for Instacart Scraper includes product, change, brand, price, price (number), regular price, unit price and on sale. Availability of each field depends on the source page and the selected mode.

How much does Instacart Scraper cost?

It costs $2.40 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Why did I get fewer results than I expected?

The source serves one page of results per keyword per store and publishes no way to page past it. A broad keyword like "yogurt" is capped at that one page just as a narrow one is, so it can return proportionally fewer of the store's actual matches. Narrow the keyword (for example "greek yogurt" rather than "yogurt") to reach more of what a store carries, and check the run log: it names any keyword or store combination where more results existed than could be read.

Why did my run fail instead of returning an empty dataset?

If the source refuses every request, or every keyword and store target errors out before returning anything, the run fails with a clear message, since no real search was ever completed. A search that genuinely matches nothing, or a store that genuinely has nothing in stock, is reported as a quiet, successful, empty result instead, so "no products matched" is never confused with "nothing could be read".

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

Ready to collect with Instacart Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.