# Costco Scraper \[Only $0.85💰] | Prices | Reviews | Stock (`ahmed_jasarevic/costco-scraper`) Actor

Track Costco online and warehouse prices, Instant Savings promos, stock, ratings and reviews. Search by keyword or drop in product URLs and export clean JSON at $0.85 per 1,000 products.

- **URL**: https://apify.com/ahmed_jasarevic/costco-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 results

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

Extract costco.com product data for price monitoring, MAP enforcement and warehouse-vs-online arbitrage research: product names, item numbers, online and warehouse prices, Instant Savings promos, stock status, ratings, review counts, images, specs and category paths. Keyword search runs against Costco's own internal search API at **$0.85 per 1,000 products** with no browser and no proxy, and optional customer reviews from Costco's Bazaarvoice feed cost **$1.00 per 1,000 products**.

### Main Use Cases

- **Costco price monitoring** - track online and per-warehouse prices plus Instant Savings promos over time.
- **MAP and dealer price checks** - compare costco.com online pricing against warehouse pricing for a list of items.
- **Warehouse vs online arbitrage research** - find items that are cheaper in one channel.
- **Product catalog and SKU data builds** - item numbers, catalog IDs, brands, specs, images and category paths.
- **Customer review mining** - pull reviews, star ratings, verified-purchase badges and helpful-vote counts.
- **Stock and availability tracking** - monitor InStock / OutOfStock per warehouse and per ship-to ZIP.

### How It Works - The Bypass (No Official Costco API, No Browser)

Costco's storefront is a Next.js app; its listings and per-warehouse prices load client-side from internal JSON APIs that sit behind Kasada Bot Defense. The Actor reverse-engineers the whole data surface and uses two of its endpoints:

- **Keyword search** calls Costco's internal GRS search API directly. No browser and no Kasada token are required when the request carries the storefront's public `client-identifier` header and a complete JSON body with a non-empty `visitorId`.
- **URL mode** parses server-rendered product pages, which embed `application/ld+json` Product + BreadcrumbList plus a `priceInfo` state blob (online/delivered price, discounts, promo).

| # | Surface probed | Result |
| --- | --- | --- |
| 1 | Internal search API `POST https://gdx-api.costco.com/catalog/search/api/v1/search` | USED (keyword mode): returns real product rows without any Kasada token, provided (a) the request carries the public `client-identifier` header and (b) the JSON body is complete and includes a non-empty `visitorId`. Missing header returns `401 Missing credentials`; missing `visitorId` or fields returns `400 Bad Request`; a partial body returns the Kasada error page. With the full body it is a plain `200`. |
| 2 | Embedded JSON in served PDP HTML | USED (URL mode): every `/p/-/<slug>/<id>` page is server-rendered and embeds `application/ld+json` Product + BreadcrumbList plus a `priceInfo` state blob. |
| 3 | Mobile gateway `https://gdx-api-mobileapps.costco.com/.../search` | Same API and behaviour as #1 (same GRS backend); not needed now that the web host works directly. |
| 4 | Product API `.../catalog/product/product-api/{v1,v2}/products` | `403` with the search credential, `401 Missing credentials` without it; still gated. |
| 5 | Warehouse shelf price `dispprice-api` | Superseded: in search mode the per-warehouse price and stock already come back as `inventory(<warehouseId>, price)` and availability attributes inside the search response, with no separate call. |
| 6 | Kasada `p.js` VM (`/149e9513-.../2d206a39-.../p.js`, 152 KB, zvm-obfuscated) | Not needed. Kept for reference: it is bound to IP + User-Agent + TLS fingerprint, so forging tokens server-side is not viable, but the search API does not require them. |
| 7 | Product GraphQL `https://ecom-api.costco.com/ebusiness/product/v1/products/graphql` | Needs member OAuth (`costco-x-authorization: Bearer ...`). |
| 8 | Third-party search backend (Algolia / Meilisearch / ...) | None: Costco uses its own GRS / Fusion stack. |
| 9 | Bazaarvoice reviews `https://apps.bazaarvoice.com/bfd/v1/clients/Costco/.../reviews.json` | USED (reviews): plain JSON with a public `bv-bfd-token`, paginated (`limit`/`offset`, cap 100 per page), returning about 50 fields including text, rating, helpful votes, verified-purchase badge and location. |

**Why this choice:** the internal search API returns 12 of 12 fields as clean JSON with zero anti-bot cost when called the way the storefront calls it. No browser, no proxy, no paid solver. The `client-identifier` is a public value embedded in the costco.com bundle and in the Actor's code as `DEFAULT_CLIENT_IDENTIFIER` (not a secret and not an input field). If Costco rotates it, update the constant in the Actor source; grep the served HTML/JS for `client-identifier`.

### Input Parameters

| Field | Type | Required | Default | Notes |
| --- | --- | --- | --- | --- |
| `searchQueries` | array (string) | No | `["monitor"]` prefill | Keywords, one per line. When set, the Actor runs search mode against the internal GRS search API and returns matching products. Leave empty to scrape explicit product URLs instead. Results are limited by `maxItems`. |
| `productUrls` | array (string) | No | one monitor PDP prefill | Direct Costco product page URLs, e.g. `https://www.costco.com/p/-/...`, one per line. Used only in URL mode. |
| `warehouseId` | string | No | `847` | Costco warehouse number used for local price and stock. |
| `shipToPostal` | string | No | `98101` | Delivery ZIP code used to resolve online availability and pricing. |
| `shipToState` | string | No | `WA` | Two-letter state code matching the ZIP. |
| `includeReviews` | boolean | No | `false` | Fetch customer reviews for each product from Costco's Bazaarvoice feed into a separate `reviews` dataset. Enabling this applies an extra pay-per-event charge (`reviews`) once per product. |
| `maxReviewsPerProduct` | integer | No | `50` (1-1000) | Maximum number of customer reviews to pull per product while `includeReviews` is enabled. |
| `maxItems` | integer | No | `100` (1-20000) | Maximum number of products saved to the dataset; also sets the search page size. |
| `maxRequestsPerCrawl` | integer | No | `300` (min 1) | HTTP safety cap when crawling explicit product URLs. Not used in search mode. |
| `proxy` | object | No | `useApifyProxy: false` | Standard Apify proxy picker, off by default. Search mode does not need a proxy. |

Free Apify users get a 10-item preview per run; paid users get the full `maxItems` budget.

### Output Fields

Each product row (default dataset) carries `recordType: "product"`. Fields:

- Identity and classification: `recordType`, `source` (`search` or `crawl`), `url`, `productName`, `itemNumber`, `catalogId`, `brand`, `model`, `category`, `categoryPath` (breadcrumb array), `description`, `specs` (array).
- Pricing: `listPrice` (pre-discount), `onlinePrice` (effective post-discount price), `deliveredPrice` (when reported separately), `warehousePrice` (selected warehouse, search mode only, `null` in URL mode), `discountAmount` (`listPrice - onlinePrice`, `0` when no promo), `currency`.
- Promotions: `promo` (text when an Instant Savings offer is active), `promoStart`, `promoEnd`, `promoDetails` (raw blob for analysts).
- Availability and ratings: `availability` (e.g. `InStock`, `OutOfStock`), `rating` (0-5), `reviewCount`.
- Media: `images` (gallery array), `primaryImage`.
- Run context: `searchQuery`, `warehouseId`, `scrapedAt`.

#### Reviews dataset (optional, separate)

When `includeReviews` is on, each product's reviews go to a separate, run-scoped `reviews` dataset (declared under `storages.datasets` in `actor.json`, each dataset with its own schema). One row per review, with `recordType: "review"` and `source: "bazaarvoice"`:

`itemNumber, productName, reviewId, title, reviewText, rating, author, authorLocation, submissionDate, isRecommended, isVerifiedPurchase, positiveFeedbackCount, negativeFeedbackCount, totalFeedbackCount, language, pros, cons, scrapedAt`

On the run page, open the Storage tab and pick the dataset from the Dataset dropdown to view or export each one. The run Result tab links both (Products and Reviews). If opening the `reviews` dataset ever fails, review rows are written to the default dataset with `recordType: "review"` instead and a warning is logged.

Billing: only product rows in the default dataset trigger the built-in `apify-default-dataset-item` event. Review rows in the non-default dataset are charged through the custom `reviews` pay-per-event (1 event per product).

### Example Input And Output

Example input (keyword search with reviews):

```json
{
  "searchQueries": ["monitor"],
  "maxItems": 50,
  "warehouseId": "847",
  "shipToPostal": "98101",
  "shipToState": "WA",
  "includeReviews": true,
  "maxReviewsPerProduct": 30
}
```

Example product row:

```json
{
  "recordType": "product",
  "source": "search",
  "searchQuery": "monitor",
  "url": "https://www.costco.com/p/-/msi-27-gaming-qhd-qd-oled-240hz-003ms-monitor/4201021105",
  "productName": "MSI 27\" Gaming QHD QD-OLED 240Hz 0.03ms NVIDIA G-Sync & AMD FreeSync Monitor",
  "itemNumber": "2056897",
  "catalogId": "4201021105",
  "brand": "MSI",
  "model": "MAG 271QPX",
  "listPrice": 399.99,
  "onlinePrice": 349.99,
  "warehousePrice": 339.99,
  "deliveredPrice": 349.99,
  "discountAmount": 50.0,
  "currency": "USD",
  "promo": "Instant Savings $50 off",
  "availability": "InStock",
  "rating": 4.88,
  "reviewCount": 8,
  "primaryImage": "https://mobilecontent.costco.com/live/resource/img/...",
  "categoryPath": ["Computers", "PC Gaming", "Gaming Monitors"],
  "category": "Gaming Monitors",
  "warehouseId": "847",
  "scrapedAt": "2026-10-11T09:30:00.000Z"
}
```

Example review row (reviews dataset):

```json
{
  "recordType": "review",
  "source": "bazaarvoice",
  "itemNumber": "4000287902",
  "productName": "LG 32\" Class Ultrafine 4K UHD IPS Monitor",
  "reviewId": "4C5530F5-12345",
  "title": "Great monitor!",
  "reviewText": "Crisp text and excellent color out of the box.",
  "rating": 5,
  "author": "Scott",
  "authorLocation": "Seattle, WA",
  "submissionDate": "2026-09-01",
  "isRecommended": true,
  "isVerifiedPurchase": true,
  "positiveFeedbackCount": 4,
  "negativeFeedbackCount": 0,
  "totalFeedbackCount": 4,
  "language": "en_US",
  "pros": ["Sharp text", "Good color"],
  "cons": ["No speakers"],
  "scrapedAt": "2026-10-11T09:31:00.000Z"
}
```

### Integrations & Automation

- **Apify API** - run via `POST https://api.apify.com/v2/acts/{actorId}/runs`, export via `GET /v2/datasets/{datasetId}/items?clean=true&format=json`.
- **Schedules** - run daily to build a costco.com price history (recurring usage also improves Store recommendation signals).
- **Webhooks** - fire on run finished to push new price drops into your own system.
- **Zapier / Make** - via the Apify integration, e.g. new Instant Savings offers into Google Sheets or Airtable.
- **Pay-per-event** - $0.85 per 1,000 products (`result`), plus $1.00 per 1,000 products when `includeReviews` is on (`reviews`, charged once per product), plus a $0.00005 run start.

### Related Actors

- [costco-fast-product-scraper](https://apify.com/e-commerce/costco-fast-product-scraper): the Apify-owned Costco product scraper, useful for a like-for-like feature comparison.
- [costco-reviews-scraper](https://apify.com/e-commerce/costco-reviews-scraper): Apify-owned Costco reviews actor, if you need reviews only.
- [rigelbytes/costco-scraper](https://apify.com/rigelbytes/costco-scraper): a smaller community Costco product actor.
- [tesco-scraper](https://apify.com/ahmed_jasarevic/tesco-scraper): another large grocery / retail product scraper with price and detail fields.
- [amazon-bestsellers-scraper](https://apify.com/ahmed_jasarevic/amazon-bestsellers-scraper): Amazon category bestseller rankings for cross-retail product research.

### FAQ

#### Does Costco have an official API?

Costco has no public product API for third parties. The member-facing GraphQL (`ecom-api.costco.com`) needs member OAuth, and the product API endpoints return `403`. This Actor uses Costco's own internal GRS search API the same way the storefront does, plus server-rendered PDP JSON in URL mode, so no key is required.

#### What are the alternatives to this Costco scraper?

Store alternatives include e-commerce/costco-fast-product-scraper (about $0.0043 per product detail page), rigelbytes/costco-scraper (about $0.001 per result), parseforge/costco-scraper ($0.00757 per result) and e-commerce/costco-reviews-scraper ($0.002 per item, reviews only). This actor is the cheapest product mode seen at $0.85 per 1,000 results and adds per-warehouse pricing and Instant Savings fields.

#### How do I get Costco warehouse prices?

Set `warehouseId` (default `847`). In search mode the internal API returns the per-warehouse price and stock inside the same search response, so `warehousePrice` is populated. In URL mode there is no warehouse lookup, so `warehousePrice` is `null`.

#### Do I need a proxy or a browser to scrape Costco?

No. Search mode is plain HTTPS with no browser and no proxy. URL mode is Cheerio-only. Kasada tokens are not required for the search API when the request is formed the way the storefront forms it.

#### How do I get Costco customer reviews?

Set `includeReviews: true`. Reviews are fetched from Costco's Bazaarvoice feed into a separate `reviews` dataset, up to `maxReviewsPerProduct` per product. This adds a `reviews` pay-per-event charge once per product.

#### How much does a Costco scrape cost?

$0.85 per 1,000 product rows in the default dataset ($0.00085 per row), plus $1.00 per 1,000 products when `includeReviews` is on (one `reviews` event per product), plus a $0.00005 run start. Runs fit comfortably in 256 MB and need no paid anti-bot service.

#### Can I track Costco prices on a schedule?

Yes. Create an Apify Schedule for a daily run with your `searchQueries` and `warehouseId`, and store each day's dataset to build a price history and to catch Instant Savings changes.

#### Why is `warehousePrice` null sometimes?

`warehousePrice` is only returned in search mode, because only the internal search API carries per-warehouse inventory. In URL mode (`productUrls`) that field is `null` by design.

### SEO Keywords

costco scraper, costco api, costco product data, costco price tracker, costco warehouse prices, costco reviews scraper, costco item number lookup, costco inventory checker, costco price monitoring, costco product catalog, costco instant savings, costco price comparison, warehouse club pricing data, costco map enforcement, costco sku data, costco stock checker, scrape costco, costco dataset, costco price history, costco product images, costco online vs warehouse price

### For AI Agents & LLM Apps

- **Purpose**: returns one JSON row per costco.com product (name, item number, catalog ID, brand, online / warehouse / delivered prices, discounts, promo, availability, rating, review count, images, category path) and, optionally, one row per customer review in a separate dataset.
- **Minimal working input**:

```json
{ "searchQueries": ["monitor"], "maxItems": 10 }
```

- **Variant input** (reviews enabled, ship-to a specific ZIP and warehouse):

```json
{ "searchQueries": ["monitor"], "warehouseId": "847", "shipToPostal": "98101", "shipToState": "WA", "includeReviews": true, "maxReviewsPerProduct": 30 }
```

- **Output field names**: `recordType, source, searchQuery, url, productName, itemNumber, catalogId, brand, model, listPrice, onlinePrice, deliveredPrice, warehousePrice, discountAmount, currency, promo, promoStart, promoEnd, promoDetails, availability, rating, reviewCount, images, primaryImage, categoryPath, category, description, specs, warehouseId, scrapedAt`.
- **Review row field names**: `recordType, source, itemNumber, productName, reviewId, title, reviewText, rating, author, authorLocation, submissionDate, isRecommended, isVerifiedPurchase, positiveFeedbackCount, negativeFeedbackCount, totalFeedbackCount, language, pros, cons, scrapedAt`.
- **Behaviors an agent should know**:
  - Mode priority: if `searchQueries` is non-empty the Actor runs search mode; `productUrls` is used only when there are no search queries. Do not set both expecting a merged result.
  - `warehousePrice` is populated only in search mode and is `null` in URL mode.
  - `onlinePrice` is the effective post-discount price; `listPrice` is pre-discount; `discountAmount = listPrice - onlinePrice` (`0` when no promo).
  - `includeReviews: true` adds a billed `reviews` event once per product and writes to a separate `reviews` dataset (not the default dataset); if that dataset cannot be opened, review rows fall back to the default dataset with `recordType: "review"`.
  - `maxItems` also sets the search page size, so a very small value can reduce how many rows fit per request.
  - `maxRequestsPerCrawl` is ignored in search mode.
- **Billing**: pay-per-event - $0.00085 per product row in the default dataset, $0.001 per product when `reviews` is enabled (one event per product), $0.00005 per run start. Tiered pricing may be lower on higher Apify plans.

### Legal & Compliance Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Costco Wholesale Corporation (costco.com). It accesses only publicly available product pages and Costco's own storefront search API, does not log in, does not bypass member authentication and does not solve CAPTCHAs.

Users are responsible for complying with costco.com's terms of service and applicable data-protection law. Review rows can include a reviewer nickname and an optional review location; do not use extracted personal data for unsolicited commercial outreach in violation of applicable law (for example CAN-SPAM, GDPR or CCPA). Use the data for lawful purposes such as price research, catalog building and market analysis.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search on costco.com (one per line). When set, the Actor uses Costco's internal GRS search API and returns matching products — no browser, no proxy required. Results are limited by Max items. Leave empty to scrape explicit product URLs instead.

## `warehouseId` (type: `string`):

Costco warehouse number used for local price + stock. e.g. 847.

## `shipToPostal` (type: `string`):

Delivery ZIP code used to resolve online availability/pricing.

## `shipToState` (type: `string`):

Two-letter state code matching the ZIP.

## `productUrls` (type: `array`):

Direct Costco product page URLs to scrape (e.g. https://www.costco.com/p/-/...) — one per line.

## `includeReviews` (type: `boolean`):

Fetch customer reviews for each product from Costco's Bazaarvoice feed into a separate 'reviews' dataset. Enabling this applies an extra pay-per-event charge ('reviews') once per product — price is set by the developer in the Actor's monetization settings.

## `maxReviewsPerProduct` (type: `integer`):

Maximum number of customer reviews to pull per product when 'Include reviews' is enabled.

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

Maximum number of products to save to the dataset (also sets the search page size).

## `maxRequestsPerCrawl` (type: `integer`):

Maximum HTTP requests when crawling explicit product URLs (safety cap). Not used in search mode.

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "searchQueries": [
    "monitor"
  ],
  "warehouseId": "847",
  "shipToPostal": "98101",
  "shipToState": "WA",
  "productUrls": [
    "https://www.costco.com/p/-/msi-27-gaming-qhd-qd-oled-240hz-003ms-nvidia-g-sync--amd-freesync-monitor/4201021105"
  ],
  "includeReviews": false,
  "maxReviewsPerProduct": 50,
  "maxItems": 100,
  "maxRequestsPerCrawl": 300,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Products dataset. Empty when 'Include reviews' is the only enabled mode.

## `reviews` (type: `string`):

Customer reviews dataset, populated only when 'Include reviews' is enabled.

# 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 = {
    "searchQueries": [
        "monitor"
    ],
    "productUrls": [
        "https://www.costco.com/p/-/msi-27-gaming-qhd-qd-oled-240hz-003ms-nvidia-g-sync--amd-freesync-monitor/4201021105"
    ],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/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 = {
    "searchQueries": ["monitor"],
    "productUrls": ["https://www.costco.com/p/-/msi-27-gaming-qhd-qd-oled-240hz-003ms-nvidia-g-sync--amd-freesync-monitor/4201021105"],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/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 '{
  "searchQueries": [
    "monitor"
  ],
  "productUrls": [
    "https://www.costco.com/p/-/msi-27-gaming-qhd-qd-oled-240hz-003ms-nvidia-g-sync--amd-freesync-monitor/4201021105"
  ],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/costco-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/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/KIIs0sWEtIDThPcTP/builds/uFfRBwkm6aBZEsjjs/openapi.json
