# Costco Scraper: Prices, Instant Savings, Stock & Reviews (`vant47/costco-scraper`) Actor

Get Costco products with warehouse and online prices, dated Instant Savings, member-only flags, delivery and warehouse availability by ZIP, item number, brand, rating and reviews. Use item IDs, product links, savings pages or sitemap keywords. About $0.005 per product. No login.

- **URL**: https://apify.com/vant47/costco-scraper.md
- **Developed by:** [fortbrand](https://apify.com/vant47) (community)
- **Categories:** E-commerce, Automation
- **Security:** Limited permissions
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Costco Scraper: Prices, Instant Savings, Stock & Reviews

For retail price analysts, brands and comparison services monitoring Costco item numbers, online prices and US warehouse availability. About **$0.005 per delivered product**: 20 products cost about **$0.10**, and 1,000 products cost about **$5**, plus the small Actor start charge. No Costco login, membership credentials or account cookies are needed.

Core inputs and retail fields match the Safeway and Albertsons Actor. Preserve the Costco extras to compare online and warehouse observations.

Cloud validation on 3 November 2026: 37 varied inputs across 12 ZIPs; monitoring jobs with 1,099 and 1,100 products; 10 live warehouse price checks; two forced reboots and spending-limit checks.

### What you get

| Data | Fields | Meaning |
| --- | --- | --- |
| Product identity | `productId`, `sku`, `itemNumber`, `parentProductId`, `title`, `brand` | Item number identifies the purchasable item; parent ID identifies the product family. |
| Selected price | `price`, `regularPrice`, `priceScope`, `priceWarehouseNumber` | The requested warehouse's price after savings and before savings. With no location, the scope is Costco.com online. |
| Online comparison | `onlinePrice`, `onlineRegularPrice`, `warehousePrice` | Separate online and warehouse observations. The Actor never fills a missing warehouse price with an online price. |
| Instant Savings | `onSale`, `promoText`, `promoType`, `promoStart`, `promoEnd`, `discountAmount`, `promotions` | Dated promotions for the selected price warehouse. |
| Online offers | `onlinePromotions` | Online promotion wording, dates and purchase limits, kept separately. |
| Membership | `memberOnly`, `memberPrice`, `memberProgram` | Source membership restriction and the selected member price where the source supplies it. |
| Online-only badge | `onlineOnly`, `onlineOnlySource` | Explicit source attribute or the badge on a savings card. Missing badges stay null. |
| Warehouse stock | `inStock`, `warehouseInStock`, `warehouseStockStatus` | An explicit inventory observation for the selected warehouse. Unknown stock stays null. |
| Delivery by ZIP | `deliveryInStock`, `deliveryStockStatus`, `deliveryLocation`, `deliveryByZip` | Delivery-program status using the distribution centers Costco returns for the requested ZIP. |
| Product metadata | `size`, `gtin`, `model`, `features`, `specifications`, `details` | UPC and extended metadata are available when `includeDetails` is enabled and the public page supplies them. |
| Reviews | `rating`, `reviewCount` | Aggregate rating and review count, without individual review text. |
| Location evidence | `storeId`, `storeName`, `location`, `requestedLocations`, `storeAddress`, `storeTimezone` | The resolved warehouse and requested ZIP context. |
| Traceability | `url`, `sourceUrl`, `scrapedAt`, `inventoryCheckedAt` | Public source links and observation timestamps. |

**Read `priceScope` before comparing prices.** A run with ZIP `98101` selects the nearby Seattle warehouse. Its `price` is that warehouse's published price or null. The national Costco.com price remains in `onlinePrice`. A run without ZIPs or store IDs uses virtual online warehouse `847`, so `priceScope` is `online`.

### Supported routes and coverage

`searchTerms` performs **sitemap keyword discovery**. Every term must appear within the product name encoded in a URL in Costco's current product sitemap. Short terms can match parts of words; use specific phrases to narrow discovery. It is useful for finding named products, brands and broad item types. It is not Costco's ranked search, does not search descriptions, and does not promise every product that the website search engine would find.

Savings pages with explicit product links are supported, including `https://www.costco.com/o/-/warehouse-savings`. Their printed warehouse item numbers and linked product families are checked against live product and inventory responses. A page's badge is retained when it explicitly says Online Only or Warehouse & Online.

An item can be unpublished online yet still have a valid warehouse price. Such warehouse observations are retained; `onlinePublished` and `onlineBuyable` explain the distinction. An unset zero/zero online price becomes null.

**Native category grids are not supported.** A category page can supply explicitly linked products, but a grid populated only by the blocked native search service returns a free note. There is no category-completeness claim. Use known item numbers, product links, sitemap keywords or the warehouse-savings page for a dependable monitoring basket.

### Start a run

1. Enter an item list, product links, or a keyword such as `coffee`.
2. Enter US ZIP codes, or exact warehouse IDs with ZIPs for delivery context.
3. Set the product limit, start the run, then export the Product prices dataset view or read the dataset through the API.

A warehouse basket:

```json
{
  "productIds": ["512599", "1217294", "1898552"],
  "locations": ["98101"],
  "maxItems": 20,
  "includeDetails": false
}
```

A keyword discovery run:

```json
{
  "searchTerms": ["organic coffee"],
  "locations": ["98101"],
  "maxItemsPerSearch": 20,
  "maxItems": 20
}
```

Current linked savings:

```json
{
  "startUrls": ["https://www.costco.com/o/-/warehouse-savings"],
  "locations": ["10001"],
  "dealsOnly": true,
  "maxItemsPerSearch": 100,
  "maxItems": 100
}
```

Online prices without a warehouse selection:

```json
{
  "productIds": ["512599", "1898552"],
  "maxItems": 20
}
```

### Inputs

| Input | Type | Default | How it works |
| --- | --- | --- | --- |
| `searchTerms` | array of strings | `coffee` if no source is supplied | Matches all keyword words against names in the live public sitemap. |
| `startUrls` | array of strings or URL objects | empty | Public Costco.com product and savings URLs. Native category grids may return a free unsupported-source note. |
| `productIds` | array of strings | empty | Warehouse item numbers or parent product IDs; up to 20,000 supplied numbers. |
| `locations` | array of ZIP strings | empty | Resolves the nearest US warehouse and delivery distribution centers. The input form prefills `98101`. |
| `storeIds` | array of numeric strings | empty | Selects exact US warehouse IDs. Supply a ZIP as well for delivery context and warehouse verification fallback. |
| `maxItemsPerSearch` | integer | 20 | New rows from each keyword or linked page at each warehouse; up to 10,000. |
| `maxItems` | integer | 20 | Global delivered-product limit; up to 20,000. Product ID lists use this limit. |
| `dealsOnly` | boolean | false | Keeps live selected-warehouse or online promotions. Online promotion data remains separate. |
| `includeDetails` | boolean | false | Adds public-page description, barcode, category and specifications where available. No separate details fee. |
| `proxyConfiguration` | object | automatic | Datacenter first, a working direct route next, US residential retry when needed. Explicit settings are respected. |

Exact `storeIds` take priority; ZIPs still define delivery. ZIPs sharing a warehouse share one product charge. Distinct delivery-center groups are checked independently. `deliveryByZip` and `requestedLocations` retain every ZIP; `location` is the first ZIP for nearest-warehouse selections.

### Output example

A real Seattle observation on 3 November 2026, with extra metadata omitted:

```json
{
  "retailer": "Costco",
  "country": "US",
  "currency": "USD",
  "storeId": "1",
  "storeName": "Seattle",
  "location": "98101",
  "productId": "1898552",
  "itemNumber": "1898552",
  "title": "Ninja Crispi 5-in-1 Portable Glass Air Fry Cooking System, 3 Containers & Cover, Cream",
  "price": 124.99,
  "regularPrice": 159.99,
  "priceScope": "warehouse",
  "onlinePrice": 124.99,
  "onSale": true,
  "promoType": "Instant Savings",
  "promoStart": "2026-10-19T07:00:00Z",
  "promoEnd": "2026-11-15T08:00:00Z",
  "discountAmount": 35,
  "warehouseInStock": true,
  "deliveryInStock": true,
  "recordType": "PRODUCT"
}
```

Core retail fields precede Costco extras. Size and descriptions are catalog metadata. Unpublished fields stay null. Unit prices require a published quantity factor and unit; no package size or shelf quantity is guessed.

### Monitor prices every day

Create an Apify task containing the item list, ZIPs and product limit you want to monitor. Add that task to an Apify schedule. Each scheduled run produces its own dataset and observation timestamps; retain those datasets in your own database for history.

Compare warehouse observations by `(retailer, storeId, productId)`. Keep `onlinePrice` separate. Null prices and stock are unknown, and should not trigger an out-of-stock alert.

The Actor resumes from its dataset after an interrupted run. Saved product rows and accepted product charges are reconciled before additional work. A duplicate discovered through another keyword, URL or parent product does not receive a second product charge in that run.

### Price and spending limits

| Delivered products | List-price product charge |
| --- | --- |
| 1 | $0.005 |
| 20 | $0.10 |
| 100 | $0.50 |
| 1,000 | $5.00 |

The platform start charge is $0.00005, with the platform's memory-based minimum. Bronze has a 5% product discount, Silver 10%, and Gold and higher 20%. The Pricing tab is authoritative for the plan running the Actor.

Failures, unsupported-source notes, empty matches, retries and duplicate products have no product charge. A product with an unreported warehouse price can still provide a current online price, explicit inventory, membership flags and catalog identity. Those delivered product records are billable. Check the output fields against your requirements before selecting a large basket.

Apify's maximum total charge and `maxItems` both apply. The Actor checks affordability before saving a row and records `spendingLimitReached` in `SUMMARY`.

### API use

Start asynchronously and read the returned dataset ID:

```bash
curl -X POST 'https://api.apify.com/v2/acts/vant47~costco-scraper/runs' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"productIds":["512599","1898552"],"locations":["98101"],"maxItems":20}'
```

Python:

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('vant47/costco-scraper').call(run_input={
    'productIds': ['512599', '1898552'],
    'locations': ['98101'],
    'maxItems': 20,
})
for row in client.dataset(run['defaultDatasetId']).iterate_items():
    if row.get('recordType') == 'PRODUCT':
        print(row['productId'], row['price'], row['onlinePrice'])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('vant47/costco-scraper').call({
  productIds: ['512599', '1898552'], locations: ['98101'], maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter(row => row.recordType === 'PRODUCT'));
```

Read `SUMMARY` from the run's default key-value store for products, stores, deals, free failures, duplicates, source outcomes and coverage notes. `DEALS` contains only delivered deal records; for a large export it contains a part index. Dataset views include Product prices, Instant Savings and Full product data. Notes are separate `NOTE` records, so filter `recordType` when loading numeric price tables.

### Use with AI agents (MCP)

Expose `vant47/costco-scraper` through `https://mcp.apify.com` and fetch its input schema first. Example request: collect Costco items 512599 and 1898552 for ZIP 98101, show warehouse and online prices separately, limit to 20 products, and report missing stock as unknown. Read `SUMMARY` for coverage notes.

### Limits and interpretation

- US Costco.com and US warehouse selection only. Costco Business Delivery, Same-Day delivery checkout and other country storefronts are separate products.
- Native ranked search and dynamically populated category grids are unavailable through this signed-out route. Sitemap discovery has different coverage and ordering.
- A public API response can omit an item, warehouse price, online price or inventory observation. Null values remain null.
- `onlineOnly` requires explicit source evidence. An absent in-warehouse program is not proof of online exclusivity.
- Warehouse availability is an online inventory signal, not an audited shelf count or a purchase guarantee. Delivery availability does not reserve stock or a delivery slot.
- Membership restrictions, quantity limits, taxes, shipping and checkout conditions can affect the final transaction. Source shipping notes and promotion limits are retained; no checkout is attempted.
- Ratings and review counts are aggregate observations. Individual reviews and personal information are not collected.
- Exact warehouse lookups can be refused separately from the map lookup. Supplying a nearby ZIP enables independent verification of the requested ID.

### FAQ

#### Does this require a Costco membership or account?

No. The Actor reads signed-out public responses. It does not log in, accept account cookies or solve verification challenges.

#### Why is the warehouse price null while onlinePrice is populated?

Costco returned an online price but did not publish a price for the selected warehouse. The Actor keeps these observations separate instead of substituting one for the other.

#### Why are some stock fields null?

The source did not report a recognized stock state for that fulfillment center. Missing inventory is unknown. Only explicit stock values become true or false.

#### Are categories supported?

Explicit product links on a page can be read. Native category grids are unavailable and return a free note when there are no such links. For ongoing monitoring, save the item IDs returned by a supported discovery run.

#### Do variations create extra rows?

Yes. Distinct item numbers produce separate rows. Parent IDs can expand into variants; repeated item numbers at one warehouse are deduplicated.

# Actor input Schema

## `searchTerms` (type: `array`):

Match all terms within product names in Costco's live public sitemap. This is keyword discovery, not Costco ranked search.

## `startUrls` (type: `array`):

Costco product URLs and linked savings pages. Category grids without explicit product links produce a free note.

## `productIds` (type: `array`):

Costco warehouse item numbers or parent product IDs. For example 512599 or 100401327. No login.

## `locations` (type: `array`):

US ZIP codes. Selects the nearest US warehouse and the delivery distribution centers for each ZIP. Warehouse price is never replaced with a national price.

## `storeIds` (type: `array`):

Optional exact US warehouse IDs, for example 1. ZIPs still control delivery availability. With no ZIP, use the warehouse ZIP for delivery.

## `maxItemsPerSearch` (type: `integer`):

Maximum product rows per keyword, linked savings page or category source at each warehouse. Product ID lists use the global maxItems limit.

## `maxItems` (type: `integer`):

Global product row limit across all selected warehouses. About $0.005 per delivered product; 20 products cost about $0.10 plus the small start charge.

## `dealsOnly` (type: `boolean`):

Keep products with a live warehouse or online Instant Savings promotion. Warehouse and online prices and promotions remain separate.

## `includeDetails` (type: `boolean`):

Fetch optional public product pages for UPC/GTIN, category hierarchy, specifications and description. No additional product fee.

## `proxyConfiguration` (type: `object`):

Automatic: default US datacenter first, direct HTTP where datacenter refuses, then US residential retry. Explicit proxy settings are respected.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee"
  ],
  "locations": [
    "98101"
  ],
  "maxItemsPerSearch": 20,
  "maxItems": 20,
  "dealsOnly": false,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `products` (type: `string`):

No description

## `dealsView` (type: `string`):

No description

## `dealsOnly` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "coffee"
    ],
    "locations": [
        "98101"
    ],
    "maxItemsPerSearch": 20,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("vant47/costco-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["coffee"],
    "locations": ["98101"],
    "maxItemsPerSearch": 20,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("vant47/costco-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "coffee"
  ],
  "locations": [
    "98101"
  ],
  "maxItemsPerSearch": 20,
  "maxItems": 20
}' |
apify call vant47/costco-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vant47/costco-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ZW2aIIH9CqPpizREu/builds/bMQbNiXeUOoPp73jl/openapi.json
