Gopuff Scraper - US Quick-Commerce Prices & Assortment
Pricing
from $1.50 / 1,000 product records
Gopuff Scraper - US Quick-Commerce Prices & Assortment
Scrape Gopuff, the US quick-commerce delivery store, by location or product: prices, promotions, stock and availability per fulfillment location across thousands of everyday products. Availability monitoring (NEW, UPDATED, REAPPEARED, EXPIRED), detail enrichment, incremental runs, MCP export.
Pricing
from $1.50 / 1,000 product records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
Gopuff Scraper: US Quick-Commerce Prices, Promotions & Assortment
Gopuff Scraper turns Gopuff, the US quick-commerce delivery store, into a structured pricing and catalog feed. Walk a fulfillment location's full catalog or look up individual products by link or id, and get price, Fam-member price, unit price, promotions, stock and availability for thousands of everyday products. Track a catalog over time with built-in change detection, or run it once for a snapshot, then export to JSON, CSV or Excel, pull results through the API, or push a summary into Notion, Linear or Airtable.
Why This Scraper?
- Per-location truth. Gopuff prices and assortment differ by fulfillment location. This actor resolves each ZIP code, city name or lat,lng pair you give it to the storefront's own location and walks that location's own catalog, prices and deals.
- Promotions captured whole. Multi-buy offers ("2 for $5"), coupon-backed deals, unit prices, Fam-member pricing, badges and sponsored tiles are part of every record, not just the list price.
- Two ways in. Walk a location's collections to enumerate the catalog, or switch to product mode and paste product links or numeric ids for a direct, enriched lookup.
- Detail enrichment on demand. Turn on a per-record option to pull description, brand, SKU and a full-size image into catalog records, and pay the surcharge only when you use it.
- Change tracking built in. Label every record NEW, UPDATED, REAPPEARED or EXPIRED across scheduled runs, so a monitoring campaign returns only what changed.
- Resume without duplicate cost. Point a new run at an interrupted run or dataset and already-collected records are skipped rather than paid for twice.
- Structured failures. A blocked read fails loudly with a clear message instead of quietly returning an empty dataset.
Use Cases
- Grocery price monitoring: track per-location prices, Fam pricing and promotions on the products you care about, on a recurring schedule.
- Competitive intelligence: compare quick-commerce pricing and assortment across ZIP codes or cities.
- Deal and coupon tracking: catch multi-buy offers and coupon-backed promotions as they appear and disappear.
- Inventory and availability alerts: watch stock counts and availability on a set of products and get only the records that changed.
- Catalog research: enumerate every collection a location carries, with size, brand and category detail.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
kind | "product" |
productId | "900001" |
sku | "900001" (product mode and detail-enriched catalog records) |
url | Gopuff link to the product |
title | "Example Trail Mix, Share Size, 4 oz" |
brand | "Example Snacks" (detail-enriched records) |
categoryId / categoryName | "sampleCategoryId" / "Snacks" (catalog mode) |
locationId | "100001" (catalog mode: the resolved fulfillment location) |
price / currency | 4.99 / "USD" |
famPrice | 4.49 (the Fam-member price, when the tile carries one) |
pricePerUnitUsd / famPricePerUnitUsd / unit | 1.25 / 1.12 / "oz" |
hasPromotion / promotions | true / multi-buy or coupon offers, with text and a coupon id |
priceCallout | "Limited time" (a shelf callout, when present) |
badges | ["Staff Pick"] |
sizeLabel | "4oz" |
availability / quantityAvailable | "in_stock" / 12 |
snapEligible / famOnly / sponsored | true (each flag appears only when it applies) |
imageUrl | the product's tile image |
description / detailCategory | detail-enriched records only |
detailPrice / detailAvailability / detailImageUrl | from the product's own document (detail enrichment or product mode) |
priceScope | "sessionDefault" (product mode: the detail document's own pricing location) |
changeType / changedFields / firstSeenAt / lastSeenAt | incremental mode only |
How to Use
- Pick a mode: Catalog by location (the default) walks a fulfillment location's collections; Product links or ids reads one or more products directly.
- For catalog mode, add one or more locations (ZIP codes, city names, or lat,lng pairs) and, optionally, collection links to narrow the walk. For product mode, list product links or numeric ids.
- Switch on Enrich from product documents if you want description, brand and SKU on catalog records, and set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Catalog by location, default navigation walk:
{"mode": "categories","locations": ["78701"],"maxItems": 40}
One collection only, in-stock items with full detail:
{"mode": "categories","locations": ["Austin, TX"],"categoryInputs": ["https://www.gopuff.com/c/candy/txERmYDy"],"inStockOnly": true,"fetchDetails": true}
Product mode, direct lookup:
{"mode": "products","productInputs": ["https://www.gopuff.com/p/banana---1ct/p198176"]}
Recurring monitoring with change detection:
{"mode": "categories","locations": ["78701"],"incrementalMode": true,"stateKey": "austin-candy-weekly","emitExpired": true}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/gopuff-prices-assortment-scraper").call(run_input={"mode": "categories", "locations": ["78701"], "maxItems": 40})for product in client.dataset(run["defaultDatasetId"]).iterate_items():print(product["title"], product["price"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/gopuff-prices-assortment-scraper').call({mode: 'categories', locations: ['78701'], maxItems: 40,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max items and Max pages shape a catalog walk
Catalog mode walks each location's collections page by page and stops once Max items is reached, so a capped run returns a partial slice of the catalog rather than every product. Max pages per collection bounds how deep any single collection is walked (0 walks every page the collection has, up to a ceiling of 100 pages); a very large collection with a low page cap can end before Max items does. With several locations, they are walked in order and draw on one shared Max items budget, so a low cap can be used up by the first location; raise Max items (or run one location per run) to cover every location.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips records it already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for recurring runs over the same scope. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that scanned its whole scope to the end, and only withemitExpired).stateKeynames or shares the stored state; leave it empty and the actor derives one from the mode, locations, collections and filters. With incremental mode off, output is exactly as before.
Send results into your apps (MCP connectors)
Optionally pipe results into Notion, Linear, Airtable or Apify via MCP connectors, in the Integrations section of the input. Each connector receives a condensed summary per product; the complete record always stays in the dataset, so nothing is lost if you leave this off.
mcpConnectors- the MCP connectors to export this run's products into (Notion, Linear, Airtable, Apify). Leave it empty and nothing is exported.notionParentPageUrl- Notion connector only: the page under which one child page per product is created. Required whenmcpConnectorsincludes Notion, ignored otherwise.maxNotifyListings- how many products are exported to each connector in one run, default 50. This caps the export only; it never changes what the dataset returns.
Export runs after the dataset is complete and is best-effort: if a connector is unreachable the run still succeeds with a warning, and your products are still in the dataset.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | categories | categories (catalog by location) or products (product links or ids). |
locations | array | ["78701"] | Catalog mode: where to read the catalog, one entry per location. A US ZIP code, a city or place name, or exact lat,lng coordinates. |
locationId | string | (none) | Advanced: pin an exact Gopuff fulfillment location id and skip location resolution. |
categoryInputs | array | sample | Catalog mode: walk only these collections, as links or bare collection ids. Leave empty to walk the whole navigation. |
discoverCategories | boolean | true | Catalog mode: when no collections are set, read the storefront navigation and walk every collection it lists. |
inStockOnly | boolean | false | Catalog mode: hide items the selected location currently cannot deliver. |
productInputs | array | sample | Product mode: numeric product ids or any product link. Multi-value supported. |
maxItems | integer | 20 | Stop after this many records (0 = unlimited). One budget for the whole run, used by the locations in the order they are listed. |
maxPages | integer | 0 | Catalog mode: how many pages to walk inside each collection, 1 to 100. 0 walks every page the collection has, up to the 100-page ceiling. |
pageSize | integer | 50 | Catalog mode: how many products to request per page, 10 to 50. |
fetchDetails | boolean | false | Catalog mode: also read each product's own document for description, brand, SKU and image (billed as the detail-enrichment event). |
incrementalMode | boolean | false | Remember the previous run of the same scope and label every record NEW, UPDATED, UNCHANGED or REAPPEARED; records gone from a complete scan are reported EXPIRED. |
emitUnchanged | boolean | false | Incremental mode: also return (and bill) records that did not change since the previous run. |
emitExpired | boolean | false | Incremental mode: also return (and bill) records gone from a COMPLETE scan. Partial scans never mark records expired. |
stateKey | string | (none) | Incremental mode: name a monitoring campaign so two runs share a baseline even if their input text differs. Leave empty to derive it from mode, locations, collections and filters. |
resumeFromRunId | string | (none) | Skip records already collected by an earlier run or dataset so an interrupted crawl can continue. Compatible with incremental mode. |
mcpConnectors | array | (none) | Send every pushed record to these Apify MCP connectors (for example a Notion database) after the run. Leave empty to skip the export. |
notionParentPageUrl | string | (none) | When a Notion connector is used above, create pages under this parent. |
maxNotifyListings | integer | 50 | Upper bound on records sent to the connectors above. |
proxyConfiguration | object | Apify proxy, residential, US | The storefront read runs through the Apify proxy; the entry session and every page must share one residential exit in the US. |
Keyword search is deliberately not offered: the storefront answers keyword queries with result counts and facets but serves its result grid only to sessions with a delivery address set, which an anonymous read cannot do. The collection walk is the way to enumerate the catalog.
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"kind": "product","productId": "900001","url": "https://www.gopuff.com/p/example-trail-mix-share-size-4-oz/p900001","title": "Example Trail Mix, Share Size, 4 oz","price": 4.99,"currency": "USD","famPrice": 4.49,"priceChannel": "default","pricePerUnitUsd": 1.25,"unit": "oz","hasPromotion": true,"promotions": [{"text": "2 for $8", "couponId": "sample-coupon-id", "couponSystem": "SAMPLECOUPONS"}],"sizeLabel": "4oz","availability": "in_stock","quantityAvailable": 12,"snapEligible": true,"categoryId": "sampleCategoryId","categoryName": "Snacks","locationId": "100001","imageUrl": "https://images.gopuff.com/blob/sample/example-trail-mix.png","description": "A resealable trail mix blend, sample description text.","brand": "Example Snacks","sku": "900001","detailPrice": 4.99,"detailAvailability": "InStock","changeType": "NEW","changedFields": [],"firstSeenAt": "2026-01-01T00:00:00+00:00","lastSeenAt": "2026-01-01T00:00:00+00:00"}
Plan Requirement
Pay-per-event: one unit per returned record, plus an Actor Start event, plus a detail-enrichment unit for each record enriched from its own product document (only when that option is on). The default proxy setting (residential, US) is what this actor needs; keep it. A normal run is light on memory; if the log reports that the run switched to its fallback connection mode, give that run 2 GB of memory. A storefront that cannot be read fails the run loudly, it is never reported as an empty search.
FAQ
How much does it cost?
You pay per record returned, plus a detail-enrichment unit only for records where you turned that option on. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Gopuff?
This actor collects only publicly available storefront data: prices, promotions, stock and product details. You are responsible for how you use it: follow Gopuff's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Can I monitor prices and stock on a schedule?
Yes. Schedule the actor from the Schedules tab with the same input and turn on Incremental runs. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you ask for them.
Why did my run return fewer products than expected?
Catalog mode stops at Max items, and Max pages per collection limits how deep any single collection is walked. Raise either setting, or set Max items to 0, to collect more of the catalog.
Why did my run fail instead of returning an empty dataset?
If the storefront refuses every request or a location can't be resolved, the run stops with a clear message so "nothing in stock" is never confused with "nothing could be read". Run it again in a few minutes.
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.
๐ More scrapers you might like
Pair this actor with these related scrapers from the same team:
| ๐งฉ Walmart Scraper Scrape Walmart.com by keyword, URL, or item ID. Extract prices, was-prices, sellers... | ๐ฅฆ E.Leclerc Scraper Scrape E.Leclerc France (e.leclerc) grocery and retail products. Search by keyword or... |
| ๐งฉ Miravia Spain Scraper Scrape Miravia Spain by keyword, seller store or URL. Every row carries the selling price... | ๐งฉ Walgreens Products & Reviews Scraper Scrape Walgreens products by keyword, category or product URL. Extract prices... |
| ๐ฅฆ Woolworths AU Scraper Scrape Woolworths Australia (woolworths.com.au) grocery products and reviews. Search by... | ๐ท๏ธ bol.com Scraper Scrape bol.com products: title, price, list price and discount, EAN, brand, images... |
๐ Browse all abotapi scrapers
๐ฌ Support
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
- โญ Enjoying it? A quick review on the actor page helps other users find it.