Gopuff Scraper - US Quick-Commerce Prices & Assortment avatar

Gopuff Scraper - US Quick-Commerce Prices & Assortment

Pricing

from $1.50 / 1,000 product records

Go to Apify Store
Gopuff Scraper - US Quick-Commerce Prices & Assortment

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

Abot API

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

2 days ago

Last modified

Categories

Features

Limited permissions

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.

FieldExample
kind"product"
productId"900001"
sku"900001" (product mode and detail-enriched catalog records)
urlGopuff 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 / currency4.99 / "USD"
famPrice4.49 (the Fam-member price, when the tile carries one)
pricePerUnitUsd / famPricePerUnitUsd / unit1.25 / 1.12 / "oz"
hasPromotion / promotionstrue / 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 / sponsoredtrue (each flag appears only when it applies)
hsaFsaEligible / isBundletrue (each flag appears only when it applies; not treated as a change signal in incremental mode)
imageUrlthe product's tile image
description / detailCategorydetail-enriched records only
detailPrice / detailAvailability / detailImageUrlfrom the product's own document (detail enrichment or product mode)
priceScope"sessionDefault" (product mode: the detail document's own pricing location)
changeType / changedFields / firstSeenAt / lastSeenAtincremental mode only

How to Use

  1. Pick a mode: Catalog by location (the default) walks a fulfillment location's collections; Product links or ids reads one or more products directly.
  2. 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.
  3. 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.
  4. 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 ApifyClient
client = 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. A record is identified by product and location, so the same product at another location is still collected.
  • Incremental mode (incrementalMode) is for recurring runs over the same scope. Each record is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only after a run that scanned its whole scope to the end, and only with emitExpired). stateKey names 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 when mcpConnectors includes 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.

Link shapeFieldWhat happens
gopuff.com/c/<slug>/<id> or gopuff.com/c/<id>CollectionsWalks that collection
gopuff.com/deals/<slug>/<id>CollectionsWalks that deal collection
gopuff.com/p/<slug>/p<id> or bare 198176Product links or idsOne enriched product record
gopuff.com/ (home), gopuff.com/shopCollectionsWalks the whole storefront navigation, only while discoverCategories ("Walk the whole navigation") is on (with it off, nothing is walked)
gopuff.com/dealsCollectionsWalks the whole storefront navigation, only while discoverCategories ("Walk the whole navigation") is on (use a /deals/<slug>/<id> link for one deal collection)
Search pages (gopuff.com/search?...), or a product link pasted into CollectionsCollectionsSkipped with a warning in the run log (put product links in Product links or ids)
Anything elseeitherSkipped with a warning in the run log

If every entry in Collections is skipped, the run stops with an input message and collects nothing, so no products are read and no records are charged (only the Actor Start event applies); it does not fall back to walking the whole navigation.

The Console form pre-fills one example product and example collection links; through the API both fields default to empty, and empty Collections walks the whole navigation. Set the field to narrow the walk. Navigation links given beside specific collections are ignored with a warning, and only the listed collections are walked. Navigation links with discoverCategories switched off walk nothing (a warning is logged).

Runs with no location. If catalog mode gets no location at all (no Locations and no Storefront location id), the actor reads the example location 78701 instead of returning nothing, logs a warning, and bills only the records it delivers as usual. That example read is never used for incremental tracking: no state is saved and no record is marked EXPIRED from it, so a later run with your own location starts from its own baseline. With incremental mode and your own stateKey and no location, the run stops with an input message and collects nothing. If Locations has entries but none can be read as a ZIP code, place name or coordinates pair, the run also stops with an input message.

Input Parameters

ParameterTypeDefaultDescription
modestringcategoriescategories (catalog by location) or products (product links or ids).
locationsarray(none)Catalog mode: where to read the catalog, one entry per location (the Console form pre-fills 78701). A US ZIP code, a city or place name, or exact lat,lng coordinates. Left empty (and no Storefront location id set), the run reads the example location 78701 so it still returns records, and a warning says so; with incremental mode and your own stateKey it stops with an input message instead.
locationIdstring(none)Advanced: pin an exact Gopuff fulfillment location id and skip location resolution.
categoryInputsarray(none)Catalog mode: walk only these collections, as links or bare collection ids. Leave empty to walk the whole navigation.
discoverCategoriesbooleantrueCatalog mode: when no collections are set, read the storefront navigation and walk every collection it lists.
inStockOnlybooleanfalseCatalog mode: hide items the selected location currently cannot deliver.
productInputsarray(none)Product mode: numeric product ids or any product link. Multi-value supported.
maxItemsinteger20Stop after this many records (0 = unlimited). One budget for the whole run, used by the locations in the order they are listed.
maxPagesinteger0Catalog mode: how many pages to walk inside each collection. 0 (default) walks every page, up to a built-in ceiling of 100 pages per collection.
pageSizeinteger50Catalog mode: how many products to request per page, 10 to 50.
fetchDetailsbooleanfalseCatalog mode: also read each product's own document for description, brand, SKU and image (billed as the detail-enrichment event).
incrementalModebooleanfalseRemember 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.
emitUnchangedbooleanfalseIncremental mode: also return (and bill) records that did not change since the previous run.
emitExpiredbooleanfalseIncremental mode: also return (and bill) records gone from a COMPLETE scan. Partial scans never mark records expired.
stateKeystring(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.
resumeFromRunIdstring(none)Skip records already collected by an earlier run or dataset so an interrupted crawl can continue. Compatible with incremental mode.
ignoreFieldsForChangesarray[]Incremental mode only: field names (nested with dots, for example promotions.label) that must not make a record UPDATED or appear in changedFields. They stay in the output.
mcpConnectorsarray(none)Send every pushed record to these Apify MCP connectors (for example a Notion database) after the run. Leave empty to skip the export.
notionParentPageUrlstring(none)When a Notion connector is used above, create pages under this parent.
maxNotifyListingsinteger50Upper bound on records sent to the connectors above.
proxyConfigurationobjectApify proxy, residential, USResidential recommended; keep the default. See Plan Requirement.

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

Residential proxy recommended. Gopuff sits behind a managed browser challenge and a first-party bot wall. The default proxy setting (Apify residential, US) reads the storefront directly, which is the fastest and most reliable way to run this actor; keep it. A datacenter group is challenged on the direct read, so the actor falls back to a slower browser session on that connection and still reads the catalog, but it takes longer and is less reliable. Apify free plans do not include residential proxies, so on a free plan the actor can only try its backup connection, and pages may still be unavailable. A paid Apify plan, or your own residential proxy URLs, is the reliable way to run it.

What you see in the run log:

  • If the selected connection is unavailable, the log prints: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs."
  • When pages are then served by the backup: "Served over the backup connection (the default connection was unavailable)."
  • If the proxy is refused for the account and nothing loads, the run fails with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
  • If residential is unavailable and the backup cannot load the pages, it fails with: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Gopuff pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
  • Any other total read failure: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."

A storefront that cannot be read always fails the run loudly; it is never reported as an empty search.

Pricing

Pay-per-event, as registered on the Pricing tab (rates are shown there, not here):

  • Product record: one unit for each record returned in the dataset.
  • Actor Start: charged when the run starts; the number of units scales with the run's memory (one per GB, minimum one).
  • Detail enrichment: one unit for each record enriched from its own product document, only when Enrich from product documents is on. It is charged one record at a time, right after that enriched record is delivered, so a stopped or failed run is billed only for the enriched records it actually delivered.

Unchanged records (unless emitUnchanged is on), expired records (unless emitExpired is on and the scan was complete), skipped records and failed records are never charged. Use Max items to cap the cost of any run.

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.

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 (quoted under Plan Requirement) 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...
🧩 Walgreens Products & Reviews Scraper
Scrape Walgreens products by keyword, category or product URL. Extract prices...
πŸ₯¦ 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...
🏷️ bol.com Scraper
Scrape bol.com products: title, price, list price and discount, EAN, brand, images...
πŸ›’ The Warehouse NZ Scraper
Scrape The Warehouse New Zealand search results, category pages, and direct product URLs...

πŸ‘‰ 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.