Instacart Scraper - Grocery Products and Retailers
Pricing
from $2.20 / 1,000 results
Instacart Scraper - Grocery Products and Retailers
Extract Instacart grocery products, retailers, collections, guest prices, and delivery estimates in the United States and Canada. Pay per delivered row plus a start fee; export JSON, CSV, or Excel.
Pricing
from $2.20 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
5
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Instacart Scraper
Extract Instacart grocery products, retailers, collections, and delivery estimates in the United States and Canada as exportable rows.
- Product names, identifiers, guest prices, availability, and ratings where shown.
- Nearby retailers, storefront products, collection links, and keyword searches.
- Location-specific shopping context and optional delivery estimates.
- JSON, CSV, Excel, and API access.
- Pay for delivered rows: $3 per 1,000 rows on the Free plan, plus a start fee.
What does Instacart Scraper do?
Instacart Scraper collects public shopping data from instacart.com and instacart.ca. Use it for assortment research, price monitoring, or retailer discovery. It is independent of Instacart, not an official Instacart product or API.
- Retailers:
nearMe,discoverRetailers, andhubreturn shop rows. - Products:
storefront,collection,category,product, andenrichreturn product rows. - Navigation:
discoverCollectionsreturns collection rows;startUrlsfollows supported page links. - Search:
searchreturns products, or suggestion rows when no products are found. - Delivery:
etarequests delivery estimates;includeEtaadds estimates to nearby-retailer searches. It is off by default. Separate ETA rows count and cost the same as other rows. - Enrichment:
enrichDetailsis on by default, adding available ratings to existing product rows, up toenrichLimit.
What data can you extract from Instacart?
itemType identifies the row. Examples below illustrate the format, not current prices or guaranteed coverage. Shared fields include country, source, and scrapedAt.
Product rows (product)
| Field | Description | Example |
|---|---|---|
productId | Product identifier | 123456 |
name | Product name | Bananas |
size | Package size | 1 lb |
brandName | Brand when supplied | Example Brand |
priceString | Displayed guest price | $1.29 |
available | Availability when supplied | true |
rating | Rating on a five-point scale | 4.5 |
ratingsCount | Number of ratings | 12 |
retailerSlug | Retailer identifier used in links | costco |
retailerLocationId | Retailer location identifier | 1234 |
postalCode | Shopping location, not merchant address | 10001 |
url | Product link | https://www.instacart.com/products/123456-bananas |
Shop rows (shop)
| Field | Description | Example |
|---|---|---|
shopId | Shop identifier | 123 |
retailerId | Retailer identifier | 456 |
name | Retailer name | Costco |
retailerSlug | Retailer link identifier | costco |
serviceType | Available service | delivery |
categories | Categories supplied for the shop | ["grocery"] |
Collection rows (collection)
| Field | Description | Example |
|---|---|---|
collectionSlug | Collection identifier | produce |
name | Collection name, when available | Produce |
retailerSlug | Retailer owning the collection | costco |
url | Collection link | https://www.instacart.com/store/costco/collections/produce |
Delivery rows (eta)
| Field | Description | Example |
|---|---|---|
shopId | Shop identifier, when supplied | 123 |
retailerLocationId | Location associated with the estimate | 1234 |
etaMinutes | Estimated delivery time in minutes | 45 |
etaDisplay | Displayed delivery estimate | 45 min |
Suggestion rows (suggestion)
| Field | Description | Example |
|---|---|---|
searchTerm | Suggested search phrase | organic milk |
query | Original search phrase | milk |
isNatural | Source's natural-suggestion flag | true |
Rows also contain merchant fields: phones, emails, address, geo, person, org, and web. These are not guaranteed contact leads. leadSource, leadReveal, and leadAbsences describe their origin and missing values. For example, 未验证 means not verified. Delivery coordinates are not merchant coordinates, and marketplace links are not merchant websites. Instacart's platform support number is excluded from merchant phones.
How to scrape Instacart
- Open Instacart Scraper in Apify Console.
- Fill a target, such as
query, and a shopping location. - Set
maxResultsto3for a small first run. - Click Start and wait for completion.
- Download the dataset or read it through the API.
Empty input starts an example search for stores near New York City, capped at 3 rows. With country: "ca" and no target, the example uses Toronto. These examples use normal event pricing. With mode: "auto", the Actor selects a mode from the targets you fill. Explicit location-only modes keep your requested row limit rather than using the example cap.
Nearby shops: nearMe
Enter postalCode or city for nearby shops. City presets include nyc, sf, seattle, toronto, vancouver, and montreal.
Retailer discovery: discoverRetailers
Choose this mode explicitly for retailer discovery around the selected location.
Storefront: storefront
Enter retailerSlug for products from a retailer's storefront.
Collection: collection
Enter both retailerSlug and collectionSlug. maxPages limits collection pagination.
Collection discovery: discoverCollections
Choose this mode with retailerSlug to get collection links, not product rows.
Product: product
Enter productId or productUrl. Include retailerSlug unless the product link identifies its retailer.
Batch enrichment: enrich
Enter productIds and retailerSlug, or product links with retailer context. Each product is a separate row. In this mode, a positive enrichLimit also caps the product list; 0 uses the row limit instead.
Search: search
Enter query; add retailerSlug to search within a store. Without it, search spans retailers at the location.
Hub: hub
Enter hubSlug, such as alcohol, for shops associated with that hub.
Category: category
Enter the numeric categoryId from a category link; categorySlug is optional.
Delivery estimates: eta
Choose this mode and a location. Returned shop and ETA rows share the row limit; estimates may be unavailable.
Page links: startUrls
Supply supported storefront, collection, product, hub, category, or search links on either Instacart domain.
What to fill in
| Field | What to enter | Default |
|---|---|---|
mode | Automatic selection or an explicit mode | auto |
country | us or ca | us |
locale | Alternative country selector; keep consistent with country | us |
city | City preset or US/Canadian city name | Empty; form sample nyc |
postalCode | Delivery ZIP or postal code | From location when omitted |
latitude | Optional location latitude | Empty |
longitude | Optional location longitude | Empty |
language | Optional language value; leave empty for normal use | Empty |
proxyCountry | Search country override; normally leave empty | Matches market |
retailerSlug | Retailer identifier, such as costco | Empty |
shopId | Optional known shop identifier | Resolved when needed |
zoneId | Optional delivery zone identifier | Empty |
collectionSlug | Collection identifier | Empty |
hubSlug | Hub identifier | Empty |
categoryId | Numeric category identifier | Empty |
categorySlug | Optional category link suffix | Empty |
productId | One product identifier | Empty |
productUrl | One Instacart product link | Empty |
productIds | Product identifiers for enrichment | Empty list |
startUrls | Instacart page links | Empty list |
query | Search phrase | Empty |
maxResults | Rows per input, from 1 to 500 | 70; form sample 3 |
maxPages | Collection pages, from 1 to 50 | 10 |
enrichDetails | Add available ratings to product rows | true |
enrichLimit | Products to enrich, from 0 to 50 | 10 |
includeEta | Include nearby-shop delivery estimates | false |
Examples for each mode follow. Replace illustrative product and category IDs with identifiers from your target pages.
Nearby shops
{"mode":"nearMe","city":"nyc","maxResults":3}
Retailer discovery
{"mode":"discoverRetailers","country":"ca","city":"toronto","maxResults":3}
Storefront
{"mode":"storefront","retailerSlug":"costco","postalCode":"10001","maxResults":3}
Collection
{"mode":"collection","retailerSlug":"costco","collectionSlug":"produce","maxPages":1,"maxResults":3}
Collection discovery
{"mode":"discoverCollections","retailerSlug":"costco","maxResults":3}
Product
{"mode":"product","productId":"123456","retailerSlug":"costco","maxResults":1}
Batch enrichment
{"mode":"enrich","productIds":["123456"],"retailerSlug":"costco","maxResults":1}
Search
{"mode":"search","query":"milk","retailerSlug":"costco","city":"nyc","maxResults":3}
Hub
{"mode":"hub","hubSlug":"alcohol","city":"nyc","maxResults":3}
Category
{"mode":"category","categoryId":"1234","maxResults":3}
Delivery estimates
{"mode":"eta","postalCode":"10001","maxResults":3}
Page links
{"mode":"startUrls","startUrls":["https://www.instacart.com/store/costco/storefront"],"maxResults":3}
maxItems and limit are aliases for maxResults. keyword maps to query; zip maps to postalCode. Close field-name misspellings are corrected; other unknown fields are ignored with a note. Input rejected by the resolver stops before collection with an INVALID_INPUT: message naming the field and correction. Missing retailer context also fails before collection, with a retailerSlug is required message. No rows are charged for that failure; the start fee is separate. Successfully resolved input is recorded in INPUT_REPORT, including corrections, ignored fields, and example-run selection. Input rejected before resolution completes may have no report.
Output example
Illustrative product row, with empty merchant contact fields shown rather than invented contact details:
{"itemType": "product","productId": "123456","name": "Bananas","size": "1 lb","priceString": "$1.29","available": true,"retailerSlug": "costco","country": "us","postalCode": "10001","url": "https://www.instacart.com/products/123456-bananas?retailerSlug=costco","phones": [],"emails": [],"org": {"name": "Costco", "id": null},"leadSource": "detail","leadReveal": "visible"}
Export the dataset as JSON, CSV, Excel, XML, RSS, or an HTML table. RUN_SUMMARY describes a completed run, while ERROR_SUMMARY is available for collection failures that produce an error record.
Why use this Instacart scraper?
- Row-based costs: only delivered rows incur the row charge; a start fee also applies.
- Partial output: rows already written stay available after a stop. Collection deadlines can return partial rows, but a manual abort before delivery may leave no rows.
- Explainable input: corrections appear in
INPUT_REPORT; invalid targets identify the problem. - Missing values stay missing: prices, ratings, and contacts are not invented.
- Several inputs: use
startUrlsorproductIdsfor batches. - No proxy setup: you do not need to set up proxies.
How much does it cost to scrape Instacart?
The Actor uses pay-per-event pricing. A start event costs $0.005 per allocated GB, with a minimum of one event. The default 1024 MB allocation therefore costs $0.005 at start on every plan. Platform usage is included in these prices.
| Apify plan | Start at 1024 MB | Price per row | Price per 1,000 rows |
|---|---|---|---|
| Free | $0.005 | $0.003 | $3.00 |
| Starter | $0.005 | $0.003 | $3.00 |
| Scale | $0.005 | $0.0026 | $2.60 |
| Business | $0.005 | $0.0022 | $2.20 |
| Platinum | $0.005 | $0.002 | $2.00 |
| Diamond | $0.005 | $0.0016 | $1.60 |
maxResults applies to each start URL or batch product ID. A scalar search, collection, storefront, or location counts as one input. The default is 70; larger allowances are collected in parts of 70. All row types share that input's allowance. Free Apify plan runs are capped at 200 rows, with a developer-set allowance of 10 runs. The whole run stops at Maximum cost per run (maxTotalChargeUsd in the API).
Example: one start at 1024 MB and 10 delivered rows cost $0.005 + 10 × $0.003 = $0.035 on the Free plan. Fewer delivered rows mean a smaller row charge, not a refund of the start fee.
What happens when the run timeout is too short
When the estimated wait exceeds the available run time and automatic resumption is accepted, the run pauses instead of treating that wait as failure. It shows ABORTED with a message such as "Queued on the collection backend; this run will resume automatically when results are ready (about 60s)." The estimate varies.
When results are ready, the same run resumes, reports "Resumed: delivering N rows.", writes to the same dataset, and finishes as SUCCEEDED if collection succeeds. Previously delivered rows are skipped rather than delivered or charged twice. You do not need to restart it manually.
This can happen at most 3 times per run. Keep the default timeout of 3600 seconds to reduce pauses. Genuine collection failures can still fail the run.
The synchronous endpoints run-sync and run-sync-get-dataset-items wait at most 300 seconds and can return an empty dataset while the run is paused. For longer work, start asynchronously and read the dataset after SUCCEEDED, or use a succeeded-event webhook.
Use with AI agents and the API
Apify MCP server
Use this remote server with Claude, ChatGPT, Cursor, VS Code, or another compatible MCP client:
https://mcp.apify.com?tools=lentic_clockss/instacart-scraper
Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns its run and dataset IDs; read rows with get-dataset-items. Clients without remote support can run npx @apify/actors-mcp-server --tools lentic_clockss/instacart-scraper with APIFY_TOKEN set.
Example prompt: "Search Instacart for milk at Costco near postal code 10001 and return up to 3 rows."
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/instacart-scraper").call(run_input={"query": "milk", "retailerSlug": "costco", "postalCode": "10001", "maxResults": 3})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/instacart-scraper').call({query: 'milk', retailerSlug: 'costco', postalCode: '10001', maxResults: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For asynchronous HTTP calls, send input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~instacart-scraper/runs with Authorization: Bearer <YOUR_APIFY_TOKEN>. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use the Integrations tab for Google Sheets, Make, Zapier, n8n, Slack, Airtable, or webhooks. Apify Schedules can run recurring searches with the same location and retailer.
FAQ
Is it legal to scrape Instacart?
This Actor targets public shopping data. You are responsible for applicable terms and data-protection law; processing personal data requires a lawful basis. Public visibility is not unrestricted permission to reuse data.
Why did my run end as ABORTED?
Check its status message. An automatic-resume message means the same run is waiting to continue. A manual abort is different and does not guarantee later delivery.
How many results can I get?
maxResults accepts 1–500 rows per input, subject to available data, pagination, free-plan limits, and the run's cost ceiling. It is a maximum, not a promised count.
Why are some fields empty?
Instacart may omit prices, ratings, delivery times, or merchant contacts. Missing ratings are not zero-star ratings. Inspect leadAbsences for missing contact information.
Which countries are supported?
The input supports us and ca. Availability depends on location and retailer. A city preset can select its country automatically. French output and search-phrase translation are not promised.
Do you collect Instacart+ prices or place orders?
No. Member-login prices, cart actions, and checkout are outside this Actor's scope.
Can I schedule recurring price checks?
Yes. Keep postalCode, retailerSlug, and the target consistent when comparing runs. Prices are snapshots, not checkout quotes.
Why did search return suggestions instead of products?
Search can return itemType: "suggestion" when it finds no product rows. Check itemType before treating a row as a priced product.
Limitations
- Only United States and Canadian shopping contexts are supported.
- Storefronts, collections, prices, and delivery estimates vary by location and can be unavailable.
- A successful US product example does not establish Canadian merchant-contact coverage.
- Merchant phones, emails, addresses, and named contacts are not guaranteed.
- Product and enrichment inputs need retailer context; a bare product ID is insufficient.
- Manual stops before dataset delivery may produce no output. A run returning no usable rows can fail rather than claim an empty catalog is complete.
Related scrapers
More food delivery and grocery scrapers from the same publisher:
- Grab Scraper
- iFood Scraper
- PedidosYa Scraper
- Uber Eats Scraper
- Deliveroo Scraper
- Foodora Scraper
- Foodpanda Scraper
- DoorDash Scraper
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.