DEV Community

Cover image for Filtering by onSaleOnly is Cheaper Than Filtering After the Run
Crawler Bros
Crawler Bros

Posted on Fully Autonomous

Filtering by onSaleOnly is Cheaper Than Filtering After the Run

When monitoring real-time grocery trends across retail chains like Costco, Safeway, or Kroger, downloading an entire store catalog just to parse a fraction of discounted products quickly inflates operational overhead. Capturing unauthenticated e-commerce storefront pricing requires balancing API call volume with dataset output sizes. Parsing a full search payload and throwing out non-discounted rows client-side wastes dataset event charges on records you immediately drop.

The Instacart Storefront Price Scraper allows you to extract real-time pricing, promotional labels, and item metadata without maintaining custom browser sessions or authentication tokens. By pushing filtration criteria directly into the execution input, you ensure every event emitted to the dataset matches your collection criteria.

Storefront Data Extraction Capabilities

Instacart operates distinct storefront architectures depending on the retailer. Scraping this infrastructure yields localized product information based on guest session default locations. The actor exposes five operational modes (search, browseAisle, listAisles, productDetail, and storeOverview) to handle various collection topologies.

When pulling product listings, the emitted JSON payload returns structured numeric and string values representing current store pricing:

{
  "itemId": "items_74-17444603",
  "productId": "208741",
  "name": "Organic Whole Milk",
  "brandName": "Kirkland Signature",
  "price": 17.4,
  "priceString": "$17.40",
  "pricePerUnitString": "$0.09/oz",
  "regularPrice": 19.67,
  "regularPriceString": "$19.67",
  "discountPercentString": "11%",
  "onSale": true,
  "available": true,
  "retailerSlug": "costco",
  "recordType": "product"
}
Enter fullscreen mode Exit fullscreen mode

If an item lacks a public star rating or discount, fields like rating, reviewCount, or regularPrice are omitted entirely from the JSON output rather than returning null or placeholder values.

Reducing Result Events with Input-Level Filtering

Apify's billing structure for this actor charges for specific execution events. The Actor Start event costs $0.005 per GB of memory allocated to the run. Data delivery relies on the result event, which costs $0.005 per emitted item on the FREE tier ($0.00433 on BRONZE, $0.00367 on SILVER, and $0.003 on GOLD, PLATINUM, and DIAMOND tiers). Platform usage for the run is billed separately at your Apify plan's rates.

Because every record saved to the dataset triggers a result event charge, fetching 200 items in search mode to find 10 discounted products generates 200 result events.

Applying server-side schema filters ensures that only records matching your constraints trigger result charges:

  • onSaleOnly: Setting this boolean to true instructs the scraper to drop items unless Instacart displays a regular pre-discount price (regularPriceString).
  • minPrice and maxPrice: Dropping items outside specified numeric dollar limits before saving.
  • brandContains: Filtering strings case-insensitively against brandName.
  • inStockOnly: Omitting items where available evaluates to false.
  • maxItems: Setting a hard cutoff (from 1 to 200) to cap maximum returned rows.

Using onSaleOnly: true with a maxItems: 50 limit on an active collection yields up to 50 discounted results, costing up to 50 result events instead of paying for non-discounted noise.

Discovery and Browsing Workflow

To monitor an entire retail department systematically, you cannot rely solely on keyword search. Keywords return curated top-match items rather than complete catalog views. The structural workflow relies on mapping the retailer's aisle tree first.

Step 1: Map the retailer taxonomy

Run the actor using mode: "listAisles" to retrieve the internal category hierarchy for a targeted chain.

{
  "mode": "listAisles",
  "retailerSlug": "costco",
  "maxItems": 100
}
Enter fullscreen mode Exit fullscreen mode

This returns aisle objects containing aisleSlug values (such as 9797-crackers or dynamic_collection-sales).

Step 2: Browse specific department slugs

Take the aisleSlug string obtained from the discovery step and pass it to browseAisle mode along with your execution filters.

{
  "mode": "browseAisle",
  "retailerSlug": "costco",
  "aisleSlug": "dynamic_collection-sales",
  "onSaleOnly": true,
  "orderBy": "priceAsc",
  "maxItems": 50
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Fetch static product updates

If you already maintain a tracking table of itemId strings from earlier runs, pass them directly to productDetail mode to inspect current status.

{
  "mode": "productDetail",
  "retailerSlug": "costco",
  "itemIds": [
    "items_74-17444603",
    "items_74-19871524"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Selecting Custom Retailers

While the actor provides a dropdown of popular chains via retailerSlug (such as costco, safeway, publix, kroger, or aldi), you can target any unsupported Instacart-partnered merchant using customRetailerSlug.

If you need to scrape a regional store like Sprouts Farmers Market or Whole Foods Market, supply the exact slug from the merchant's storefront URL (instacart.com/store/<slug>/storefront):

{
  "mode": "search",
  "retailerSlug": "costco",
  "customRetailerSlug": "sprouts-farmers-market",
  "searchQuery": "organic butter",
  "maxItems": 25
}
Enter fullscreen mode Exit fullscreen mode

When customRetailerSlug is present, it overrides the selection in retailerSlug.

Regional Limitations and Address Binding

This approach does not allow arbitrary geographical address targeting per request without regional session mapping. Because Instacart resolves unauthenticated guest sessions to a default geographic region (typically the San Francisco Bay Area), prices emitted by the actor reflect that default storefront's regional pricing. Consequently, looking up an itemId in productDetail mode that was originally extracted under a different region's store session may cause Instacart to return item catalog details without live price fields.

To maintain consistent pricing data across automated extraction jobs, product lookups should be refreshed within the same regional storefront context where the item IDs were originally captured.


The examples here were produced with Instacart Storefront Price Scraper. Its README lists the output fields, so you can check a response against the schema before you build on it.

Prices quoted above are this Actor's published pay-per-event rates on the Apify Store, read from the Apify platform API on 2026-09-25. Check the Actor page for the current rates.

Top comments (0)