# Amazon US Product Scraper - $3/1k & Price Monitor (`fascinating_lentil/amazon-scraper`) Actor

Scrape Amazon US products by keyword, ASIN, or URL and monitor price, stock, seller, and BSR changes in persistent watchlists. Changed-only delivery avoids product charges for unchanged repeats. Amazon India, Detailed mode, reviews, and structured exports remain supported.

- **URL**: https://apify.com/fascinating_lentil/amazon-scraper.md
- **Developed by:** [Md Jakaria Mirza](https://apify.com/fascinating_lentil) (community)
- **Categories:** E-commerce, Marketing
- **Features:** Limited permissions
- **Stats:** 42 total users, 4 monthly users, 95.8% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.00 / 1,000 product scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Amazon US Product Scraper - $3/1k & Price Monitor

Scrape public Amazon US (`amazon.com`) and Amazon India (`amazon.in`) product pages by keyword, ASIN, category URL, or product URL. Export prices, Buy Box sellers, fulfillment, coupons, deals, delivery promises, ratings, stock, images, specifications, badges, Best Seller Rank, and optional recent reviews without an Amazon login or API key. Persistent named watchlists compare every ASIN with its prior observation and can return only meaningful price, stock, Buy Box seller, coupon, or rank changes.

### Quick start

Run one keyword and save one product:

```json
{
  "searchKeyword": ["phone case"],
  "asinList": [],
  "categoryUrl": "",
  "marketplace": "amazon.com",
  "maxProducts": 1,
  "scrapeMode": "fast",
  "includeReviews": false,
  "maxReviewsPerProduct": 3,
  "trackPriceHistory": false,
  "watchlistName": "default",
  "priceChangeThresholdPercent": 1,
  "onlyChanged": false,
  "maxRequestsPerMinute": 15,
  "maxRunMinutes": 50
}
```

When proxy input is omitted, or set to plain Apify Proxy without a group, Auto mode tries lower-cost Apify datacenter access for Amazon US Fast searches. If no product is saved because of a CAPTCHA or failed request, it retries once with Residential access. Detailed, ASIN, review, and Amazon India runs use marketplace-matched Residential access. Export results as JSON, CSV, Excel, XML, or HTML, or consume them through the Apify API, schedules, webhooks, Make, Zapier, n8n, and other integrations.

### Fast and detailed modes

`fast` is the default for keyword and category searches. It saves ASIN, title, URL, price, original price, discount, currency, rating, review count, image, keyword, and Amazon's Choice status directly from listing pages. It avoids opening every product page, so it uses fewer requests and less Residential proxy traffic.

`detailed` opens every selected product page and adds the featured Buy Box seller, ships-from party, Buy Box status, source availability text, coupon, deal, Prime signal, delivery promise, stock, gallery images, category, brand, specifications, Best Seller status, rank, and optional recent reviews. ASIN, direct product URL, and review runs automatically use detailed mode.

If Amazon repeatedly replaces a requested ASIN detail page with its anti-bot interstitial, the Actor makes one exact-ASIN listing attempt rather than failing the whole run. A recovered row is explicitly marked `detailStatus: "listing-fallback"` with `detailFallbackReason`; unavailable detail-only fields stay empty. A normally enriched row is marked `detailStatus: "complete"`.

### What it extracts

- ASIN, title, canonical product URL, marketplace, and matching keyword
- Current price, original price or MRP, discount percentage, and currency
- Rating and total review count
- Featured Buy Box seller, ships-from party, Buy Box status, and source availability text
- Coupon, deal, Prime, and delivery-promise signals from detailed pages
- Main image and product gallery URLs
- Category, brand, and product specifications
- Amazon's Choice, Best Seller, and Best Seller Rank signals
- Optional recent review title, rating, body, date, verified-purchase flag, and URL
- Transparent `detailStatus` and `detailFallbackReason` fields when an exact-ASIN listing fallback was required
- Scraped timestamp
- Persistent named watchlists with bounded per-ASIN observation history
- Price movement, stock, Buy Box seller, coupon, and Best Seller Rank change detection
- Optional baseline/changed-only output so unchanged repeats do not incur product events
- Optional enriched snapshot rows for repeated monitoring

Fields are returned only when Amazon exposes them on the page.

### Input modes

The Actor chooses one mode in this order:

1. `asinList`
2. `categoryUrl`
3. `searchKeyword`

This makes it possible to enrich known products, crawl a focused Amazon URL, or discover products through search.

### Output dataset

The `Amazon Products` view puts product images, prices, ratings, stock, seller data, badges, ASINs, and source URLs first.

#### Verified product sample

This shortened record came from a successful public Actor run:

```json
{
  "asin": "B0GDXV7FVY",
  "title": "Compatible with iPhone 13/14 Case, Cute Aesthetic Striped Pattern Cover...",
  "url": "https://www.amazon.com/dp/B0GDXV7FVY",
  "domain": "amazon.com",
  "keyword": "phone case",
  "price": 8.49,
  "originalPrice": 9.99,
  "discountPercent": 15,
  "currency": "USD",
  "rating": 4.6,
  "reviewsCount": 231,
  "sellerName": "TIANLI LTD.",
  "inStock": true,
  "imageUrl": "https://m.media-amazon.com/images/I/617drO7n+KL._AC_SX569_.jpg",
  "isAmazonsChoice": true,
  "isBestSeller": false,
  "bestSellerRank": "#53 in Cell Phones & Accessories",
  "reviews": [],
  "scrapedAt": "2026-06-25T07:18:05.754Z"
}
```

Amazon listings change frequently. Price, stock, seller, rating, badges, ranks, and page availability reflect what Amazon exposed when the run completed.

#### Persistent watchlists and price-snapshot rows

Enable `trackPriceHistory`, keep the same `watchlistName` on scheduled runs, and the Actor remembers the last 30 observations for every marketplace + ASIN in that watchlist. Product rows gain `changeStatus`, previous values, price movement, change reasons, and an observation count. It also writes an enriched snapshot row after every emitted product:

```json
{
  "_type": "price-snapshot",
  "asin": "B0GDXV7FVY",
  "domain": "amazon.com",
  "title": "Compatible with iPhone 13/14 Case...",
  "url": "https://www.amazon.com/dp/B0GDXV7FVY",
  "price": 8.49,
  "originalPrice": 9.99,
  "discountPercent": 15,
  "currency": "USD",
  "inStock": true,
  "sellerName": "Seller B",
  "couponText": "Save 15% with coupon",
  "watchlistName": "competitor-prices",
  "changeStatus": "changed",
  "changeDetected": true,
  "changeReasons": ["price_decreased", "seller_changed", "coupon_changed"],
  "previousPrice": 9.49,
  "priceChange": -1,
  "priceChangePercent": -10.5374,
  "stockChanged": false,
  "previousSellerName": "Seller A",
  "sellerChanged": true,
  "previousCouponText": "Save 10% with coupon",
  "couponChanged": true,
  "observationCount": 4,
  "capturedAt": "2026-06-25T07:18:05.754Z"
}
```

Set `priceChangeThresholdPercent` to ignore small price movement. Stock, Buy Box seller, coupon, and Best Seller Rank changes remain independent. Set `onlyChanged: true` to emit the first baseline and later changed products only. Unchanged observations still update persistent history but do not create product/snapshot rows or trigger the `product-scraped` event. Snapshot rows never trigger an additional product event; storage and runtime still contribute to platform usage.

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `searchKeyword` | string\[] | `["phone case"]` | One to five search terms. |
| `asinList` | string\[] | `[]` | Direct 10-character ASINs; takes highest precedence. |
| `categoryUrl` | string | empty | Full supported Amazon category, search, or `/dp/<ASIN>` URL. |
| `marketplace` | string | `amazon.com` | `amazon.com` or `amazon.in`. |
| `maxProducts` | integer | `1` | Product limit per keyword/category, or total ASIN limit. |
| `scrapeMode` | string | `fast` | Use `fast` for lower-usage listing data or `detailed` for full product-page fields. |
| `includeReviews` | boolean | `false` | Fetch recent public review content for each product. |
| `maxReviewsPerProduct` | integer | `3` | Review limit when reviews are enabled. |
| `trackPriceHistory` | boolean | `false` | Enable persistent cross-run history, change fields, and enriched snapshot rows. |
| `watchlistName` | string | `default` | Stable name that isolates one monitoring history from another. |
| `priceChangeThresholdPercent` | number | `1` | Minimum absolute percentage movement that counts as a price change. |
| `onlyChanged` | boolean | `false` | Emit baselines and changes only; unchanged observations are not product-charged. |
| `maxRequestsPerMinute` | integer | `15` | Maximum request pace between 5 and 30 requests per minute. |
| `maxRunMinutes` | integer | `50` | Stop queued work cleanly after 5-50 minutes and preserve saved partial results. |
| `proxyConfig` | object | Auto | Optional override. Auto (also plain Apify Proxy with no group) tries datacenter US Fast access, falls back once to Residential if nothing was saved, and uses Residential for protected paths. |

Start with Fast mode and a small product limit. Detailed mode and reviews add requests and should be enabled only when those extra fields are needed.

### Common workflows

#### Monitor a known product

Provide one or more ASINs, enable `trackPriceHistory`, choose a stable `watchlistName`, and schedule the Actor. Each output explains price, stock, Buy Box seller, coupon, and Best Seller Rank changes against the prior observation. Enable `onlyChanged` when downstream workflows should receive and pay product events only for baselines and meaningful changes.

#### Compare search results

Use a focused keyword on Amazon US or India, then analyze product prices, discounts, ratings, sellers, brands, and badges.

#### Enrich a product catalog

Pass an ASIN list and merge the returned public product fields into an internal catalog or analytics dataset.

#### Analyze public reviews

Enable reviews with a small review limit to collect recent public review text for product research or downstream sentiment analysis.

### Pricing and cost control

This Actor uses Pay Per Event with platform usage paid by the user.

| Event | Price |
| --- | ---: |
| Actor start | $0.001 per GB of memory |
| Each successfully saved `product-scraped` item | $0.003 |

The default memory is 1 GB, so the startup event charge is approximately $0.001. A one-product run therefore has approximately $0.004 in event charges, plus platform usage such as compute, data transfer, dataset operations, and any Residential proxy traffic.

Product records are saved and charged atomically. Invalid, blocked, duplicate, incomplete, or unchanged products suppressed by `onlyChanged` do not trigger `product-scraped`, and the crawler stops when the user's maximum-cost limit is reached.

To control cost:

- Start with Fast mode, one product, and one keyword.
- Use Detailed mode only when seller, stock, specifications, rank, or review fields are required.
- Keep reviews and watchlists disabled for the first exploratory run.
- For scheduled ASIN monitoring, enable `onlyChanged` after confirming the baseline so unchanged repeats avoid product event charges.
- Use the default 15 requests per minute.
- Increase limits only after the small run returns the expected fields.
- Remember that Residential proxy traffic can be a meaningful part of total platform usage.
- Large Detailed or review runs stop cleanly at `maxRunMinutes`; products already saved remain valid and the `OUTPUT` key-value record reports a partial run.

### Reliability

The Actor uses Playwright, Residential proxy support, session rotation, retries, CAPTCHA/interstitial detection, conservative pacing, fallback selectors, and asset blocking for images, media, and fonts. Fast mode avoids product-detail navigation. Requests that return a block page, a blank search result page, or a product page without a title are retried. After detail retries are exhausted, a direct-ASIN run gets one exact listing fallback; recovered rows are labeled instead of being misrepresented as fully enriched products.

- When proxy settings are omitted or set to plain Apify Proxy without a group, the Actor tries Apify datacenter access for Amazon US Fast searches and falls back once to Residential if nothing was saved because of a CAPTCHA or failed request. Detailed, ASIN, review, and Amazon India runs use Residential access from the start. An explicit proxy group, custom proxy URLs, or direct access is still honored.
- Blocked sessions are retired before retrying, and unexpected first-page selector drift fails visibly instead of returning a misleading empty-success run.

If the spending limit is reached or atomic product saving fails, the Actor stops further product work.

### Limits

- Amazon can change page markup or anti-bot behavior without notice.
- CAPTCHA and block pages can still occur with Residential proxies.
- A `listing-fallback` row contains only fields Amazon exposed in the exact search listing; it does not promise seller, stock, specifications, ranks, or reviews.
- Review pages are more aggressively protected and are best-effort.
- Sponsored and organic product cards can both appear in keyword results.
- Some products do not expose list price, seller, specifications, badges, ranks, or reviews.
- Only `amazon.com` and `amazon.in` are supported.
- `maxProducts` applies per keyword, so multiple keywords can produce more total rows.

### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/fascinating_lentil~amazon-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchKeyword": ["phone case"],
    "marketplace": "amazon.com",
    "maxProducts": 1,
    "scrapeMode": "fast",
    "includeReviews": false,
    "trackPriceHistory": false,
    "watchlistName": "default",
    "priceChangeThresholdPercent": 1,
    "onlyChanged": false,
    "maxRequestsPerMinute": 15,
    "proxyConfig": {
      "useApifyProxy": true,
      "apifyProxyGroups": ["RESIDENTIAL"]
    }
  }'
```

### Responsible use

Use this Actor only for lawful collection of publicly available product information. You are responsible for complying with Amazon's conditions, robots rules, intellectual-property rights, privacy laws, consumer-protection rules, and regulations that apply to your use case.

Do not use the output for spam, deceptive listings, unlawful profiling, or unauthorized republication of copyrighted content. This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Amazon.

### License

Apache-2.0.

# Actor input Schema

## `searchKeyword` (type: `array`):

One to five product search terms. Ignored when an ASIN or category/product URL is provided.

## `asinList` (type: `array`):

Direct 10-character product ASINs. ASIN input takes precedence over URL and keyword input.

## `categoryUrl` (type: `string`):

Full amazon.com or amazon.in search/category URL, or one /dp/<ASIN> product URL.

## `marketplace` (type: `string`):

Which Amazon site to scrape. Use 'amazon.com' (US) or 'amazon.in' (India).

## `maxProducts` (type: `integer`):

Maximum products to save per keyword, category URL, or ASIN list.

## `scrapeMode` (type: `string`):

Fast saves listing fields from search/category pages with fewer requests. Detailed opens every product page for seller, stock, gallery, brand, specifications, badges, rank, and optional reviews. ASIN and review runs always use Detailed.

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

Fetch a list of recent reviews for each product. This creates extra requests and higher usage, so keep it disabled unless needed.

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

Maximum recent reviews to fetch per product when review collection is enabled.

## `trackPriceHistory` (type: `boolean`):

Remember each ASIN across runs, add price/stock/seller/BSR change fields, and store a snapshot row. History is kept per named watchlist in persistent storage.

## `watchlistName` (type: `string`):

Stable name used to keep independent histories, such as competitor-prices or holiday-deals. Use the same name on repeat scheduled runs.

## `priceChangeThresholdPercent` (type: `number`):

Minimum absolute percentage movement that counts as a price change. Stock, seller, and BSR changes are still detected independently.

## `onlyChanged` (type: `boolean`):

After the first baseline, suppress unchanged product and snapshot rows. Suppressed products do not trigger the product-scraped event. Requires the persistent watchlist option.

## `proxyConfig` (type: `object`):

Optional override. Auto mode (also plain Apify Proxy with no group) tries lower-cost datacenter access for Amazon US Fast searches, then falls back once to Residential if nothing was saved. Detailed, ASIN, review, and Amazon India runs use marketplace-matched Residential access. An explicit proxy group or custom URLs are used as given.

## `maxRequestsPerMinute` (type: `integer`):

Maximum request pace. The optimized default improves throughput while concurrency remains conservatively limited.

## `maxRunMinutes` (type: `integer`):

Soft runtime limit. When reached, the Actor stops queued work cleanly and preserves products already saved instead of hitting the cloud timeout.

## Actor input object example

```json
{
  "searchKeyword": [
    "phone case"
  ],
  "asinList": [],
  "categoryUrl": "",
  "marketplace": "amazon.com",
  "maxProducts": 1,
  "scrapeMode": "fast",
  "includeReviews": false,
  "maxReviewsPerProduct": 3,
  "trackPriceHistory": false,
  "watchlistName": "default",
  "priceChangeThresholdPercent": 1,
  "onlyChanged": false,
  "maxRequestsPerMinute": 15,
  "maxRunMinutes": 50
}
```

# Actor output Schema

## `results` (type: `string`):

Product rows include titles, ASINs, prices, Buy Box sellers, fulfillment, coupons, deals, Prime, delivery promises, specifications, availability, and optional reviews. Persistent watchlists add prior values, price, stock, seller, coupon and BSR changes, observation counts, and enriched snapshot rows. ASIN rows transparently report when exact-listing data was used because Amazon blocked the detail page.

# 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 = {
    "searchKeyword": [
        "phone case"
    ],
    "asinList": [],
    "categoryUrl": "",
    "marketplace": "amazon.com",
    "maxProducts": 1,
    "scrapeMode": "fast",
    "includeReviews": false,
    "maxReviewsPerProduct": 3,
    "trackPriceHistory": false,
    "watchlistName": "default",
    "priceChangeThresholdPercent": 1,
    "onlyChanged": false,
    "maxRequestsPerMinute": 15,
    "maxRunMinutes": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("fascinating_lentil/amazon-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 = {
    "searchKeyword": ["phone case"],
    "asinList": [],
    "categoryUrl": "",
    "marketplace": "amazon.com",
    "maxProducts": 1,
    "scrapeMode": "fast",
    "includeReviews": False,
    "maxReviewsPerProduct": 3,
    "trackPriceHistory": False,
    "watchlistName": "default",
    "priceChangeThresholdPercent": 1,
    "onlyChanged": False,
    "maxRequestsPerMinute": 15,
    "maxRunMinutes": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("fascinating_lentil/amazon-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 '{
  "searchKeyword": [
    "phone case"
  ],
  "asinList": [],
  "categoryUrl": "",
  "marketplace": "amazon.com",
  "maxProducts": 1,
  "scrapeMode": "fast",
  "includeReviews": false,
  "maxReviewsPerProduct": 3,
  "trackPriceHistory": false,
  "watchlistName": "default",
  "priceChangeThresholdPercent": 1,
  "onlyChanged": false,
  "maxRequestsPerMinute": 15,
  "maxRunMinutes": 50
}' |
apify call fascinating_lentil/amazon-scraper --silent --output-dataset

```

## MCP server setup

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