# Amazon Offers Scraper (`w3crawler/amazon-offers-scraper`) Actor

Reads public Amazon all-offers pages for supplied ASINs and emits normalized offer rows with seller, price, condition, fulfillment, delivery, and product context when exposed.

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

## Pricing

from $2.99 / 1,000 offers

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

### What does Amazon Offers Scraper do?

Amazon Offers Scraper reads Amazon's public all-offers display fragment for one or more ASINs and emits verified offer rows when the response exposes both a real price and a seller identity. It can retain condition, fulfillment, delivery, seller feedback, product context, and primary media when those values are public.

The Actor uses serialized direct HTTPS requests to the public AOD route referenced by Amazon product pages. It does not log in, use private APIs, solve CAPTCHAs, use stealth or fingerprint spoofing, configure a proxy, retry automatically, or bypass access controls. Denials, redirects outside the selected marketplace, challenge pages, and changed/empty offer markup are recorded in logs and OUTPUT_SUMMARY, never as dataset rows.

### Why use Amazon Offers Scraper?

Use it for bounded public offer comparison, seller/condition snapshots, price checks, and source-backed marketplace research.

The Actor:

- accepts up to 50 ASINs, with a legacy single-ASIN alias;
- requests the public all-offers fragment once per ASIN;
- filters by condition, seller name, and inclusive price range;
- deduplicates by ASIN, seller, price, currency, and condition;
- applies a parsed page/pageSize window per ASIN before the global maxItems cap; and
- writes an OUTPUT_SUMMARY key-value record with request counts, candidate/output counts, operational failures, and data availability.

Offer records are not emitted from a page that exposes only a product title, a placeholder price, or no seller identity.

### What data can Amazon Offers Scraper extract?

| Group | Fields |
| --- | --- |
| Offer identity | asin, offerPosition, position, condition |
| Pricing | price, currency, listPrice, savingsPercentage |
| Seller | sellerName, sellerId, sellerUrl, sellerRating, sellerRatingCount, sellerPositivePercentage |
| Fulfillment | shipsFrom, deliveryEstimate |
| Product context | title, productRating, productRatingCount, productUrl, imageUrl |
| Source context | sourceUrl, responseUrl, locale, marketplace, offerCount, offerCountMessage, scrapedAt |
Missing values are omitted. Seller ratings, delivery, product metadata, and media are included only when the public response exposes them. Prices and availability are observations at request time, not guarantees of checkout price, stock, taxes, shipping, or eligibility.

### How to scrape Amazon offers

1. Open the Actor in Apify Console and open the Input tab.
2. Enter one or more public Amazon ASINs.
3. Choose locale, page/pageSize, filters, and whether product details or media should be retained.
4. Set a conservative request delay for multiple ASINs.
5. Start the run and inspect both the dataset and OUTPUT_SUMMARY key-value record.

For each ASIN, the runtime requests the public /gp/product/ajax/aodAjaxMain?asin=... fragment on the locale's Amazon marketplace, parses current AOD blocks with a legacy fallback, requires a seller and numeric price, then filters and deduplicates the rows. Requests are serialized. There is no browser navigation, product-page crawl, private API call, cursor pagination, proxy fallback, or automatic retry.

### How much will it cost to scrape Amazon offers?

A run makes at most one public request per validated ASIN. page and pageSize select rows locally from each response; they do not add requests. A non-zero requestDelayMs spaces ASIN request starts, while requestTimeoutMs bounds each request. More ASINs increase run time and compute. includeProductDetails and includeMedia retain fields from the same AOD response and do not create extra page requests. Check the run usage and plan pricing in Apify before scheduling batches.

### Input

See the Input tab for the complete schema. asins takes precedence over the legacy asin field. The following examples use valid ten-character ASIN shapes.

#### Single-ASIN bounded run

```json
{
  "asins": ["B0EXAMPLE1"],
  "maxItems": 10,
  "page": 1,
  "pageSize": 20,
  "includeProductDetails": true,
  "includeMedia": true,
  "dedupe": true,
  "locale": "en-US",
  "requestDelayMs": 400,
  "requestTimeoutMs": 45000
}
```

#### Filtered multi-ASIN run

```json
{
  "asins": ["B0EXAMPLE1", "B0EXAMPLE2"],
  "maxItems": 30,
  "page": 1,
  "pageSize": 30,
  "conditions": ["NEW"],
  "sellerNames": ["Example Seller"],
  "minPrice": 10,
  "maxPrice": 200,
  "includeProductDetails": true,
  "includeMedia": false,
  "concurrency": 1,
  "requestDelayMs": 500,
  "maxRetries": 0,
  "requestTimeoutMs": 45000
}
```

Supported fields are asins (up to 50), asin, maxItems (1–100, default 30), page (1–1000, default 1), pageSize (1–100, default 30), conditions, sellerNames, minPrice, maxPrice, includeProductDetails (default true), includeMedia (default true), dedupe (default true), locale, concurrency, requestDelayMs (0–10000, default 400), maxRetries, requestTimeoutMs (5000–120000, default 45000), and proxyUrl. concurrency, maxRetries, and proxyUrl are compatibility fields only: the runtime remains serialized, non-retrying, and direct.

The supported locale list includes en-US, en-IN, en-GB, en-CA, en-AU, de-DE, fr-FR, it-IT, es-ES, ja-JP, nl-NL, pl-PL, sv-SE, and pt-BR. Conditions and sellerNames are case-insensitive exact filters. Numeric filters apply to the parsed public price.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

Normal dataset rows contain offer and product fields only; actor envelopes, debug flags, access flags, transport flags, and run counters are removed before emission. A typical row is:

```json
{
  "asin": "B0EXAMPLE1",
  "offerPosition": 1,
  "price": 19.99,
  "currency": "USD",
  "condition": "NEW",
  "sellerName": "Example Seller",
  "sellerId": "A0000000000000",
  "sellerUrl": "https://www.amazon.com/sp?seller=A0000000000000",
  "shipsFrom": "Amazon.com",
  "deliveryEstimate": "This item can be delivered by Friday.",
  "sourceUrl": "https://www.amazon.com/gp/product/ajax/aodAjaxMain?asin=B0EXAMPLE1",
  "responseUrl": "https://www.amazon.com/gp/product/ajax/aodAjaxMain?asin=B0EXAMPLE1",
  "locale": "en-US",
  "marketplace": "amazon.com",
  "title": "Example public product",
  "productRating": 4.5,
  "productRatingCount": 1200,
  "productUrl": "https://www.amazon.com/dp/B0EXAMPLE1",
  "position": 1,
  "scrapedAt": "2026-09-08T00:00:00.000Z"
}
```

The dataset contains only verified offer records. When there are no matching offers, it remains empty; request and access failures are recorded in logs and the OUTPUT_SUMMARY key-value record. The summary reports status, requestedAsinCount, requestCount, candidateItems, filteredCount, duplicateCount, successfulItems, diagnosticCount, diagnosticItems, blockedCount, requestErrorCount, stoppedOnBlock, page, pageSize, locale, marketplace, dataAvailable, usedProxy, and completedAt. diagnosticCount is an operational failure count; diagnosticItems is always zero. dataAvailable is true only when at least one verified offer row is emitted. A run with usable offer rows plus per-ASIN failures is SUCCEEDED. A blocked or failed run with no offer rows uses `status: FAILED` and `dataStatus: FAILED`. A successful run with no matching offers completes with `status: SUCCEEDED` and `dataStatus: NO_RESULTS`.

### Tips and advanced options

Start with one known public ASIN and pageSize 10–30. Use includeProductDetails false or includeMedia false for a smaller dataset. Keep requestDelayMs conservative for multiple ASINs. AOD responses can contain a pinned offer plus repeated or promotional blocks; dedupe is enabled by default to prevent duplicate seller/price/condition rows.

Amazon may return HTTP 401, 402, 403, 429, redirects outside Amazon, Akamai/bm-verify interstitials, CAPTCHA pages, or changed HTML. The Actor records bounded evidence and stops at the access boundary. It does not solve, bypass, or silently replace the source with another route.

### FAQ, support, and responsible use

**Why is the dataset empty when the product page exists?** The product page and its all-offers fragment can expose different public content. A successful HTTP response without a numeric price and seller is not a verified offer result; the run summary explains failures when a request failed.

**Does page select a server-side page?** No. page and pageSize select a bounded slice of parsed offers returned for each ASIN; the Actor does not claim unsupported cursor pagination.

**Does proxyUrl enable a proxy?** No. It remains only for compatibility with older inputs; usedProxy is always false and requests are direct.

**Where do I report an issue?** Use the Actor's Issues tab and include the run ID, input shape, logs, dataset URL, and OUTPUT_SUMMARY. Use the API tab for dataset and key-value-store endpoints.

The Actor extracts only public offer information for legitimate purposes. Do not collect account or private data, evade authentication or CAPTCHAs, or ignore Amazon terms, robots guidance, rate limits, privacy law, and other applicable rules. This Actor is not affiliated with Amazon.

Run summaries include the required `status`, `runStatus`, and `dataStatus` fields. `status` and `runStatus` are `SUCCEEDED` when source-backed rows were saved or a run completed cleanly with no matches; they are `FAILED` only when a real failure occurs before any rows are saved. `dataStatus` is `COMPLETE`, `PARTIAL`, `NO_RESULTS`, or `FAILED`. Failure details stay in the run logs; key-value summaries retain counts only.

# Actor input Schema

## `asins` (type: `array`):

One or more Amazon ASINs to inspect on the public all-offers page.

## `asin` (type: `string`):

Optional single-ASIN alias retained for older runs; asins takes precedence when provided.

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

Maximum verified offer records across all supplied ASINs.

## `page` (type: `integer`):

1-based page applied to parsed public offers for each ASIN.

## `pageSize` (type: `integer`):

Number of parsed offers per ASIN included on the selected page.

## `conditions` (type: `array`):

Optional case-insensitive condition filters such as NEW or USED.

## `sellerNames` (type: `array`):

Optional case-insensitive exact seller-name filters.

## `minPrice` (type: `number`):

Optional inclusive minimum offer price in the selected marketplace currency.

## `maxPrice` (type: `number`):

Optional inclusive maximum offer price in the selected marketplace currency.

## `includeProductDetails` (type: `boolean`):

Include title, product rating, rating count and canonical product URL when exposed.

## `includeMedia` (type: `boolean`):

Include the public primary product image URL when exposed.

## `dedupe` (type: `boolean`):

Remove duplicate seller, price, currency and condition combinations per ASIN.

## `locale` (type: `string`):

Amazon marketplace and Accept-Language locale used for public requests.

## `concurrency` (type: `integer`):

Compatibility field retained for older inputs; requests are always serialized.

## `requestDelayMs` (type: `integer`):

Minimum spacing between ASIN request starts.

## `maxRetries` (type: `integer`):

Compatibility field retained for older inputs; the direct runner performs no automatic retries.

## `requestTimeoutMs` (type: `integer`):

Per-request timeout for public HTML retrieval.

## `proxyUrl` (type: `string`):

Compatibility field retained for older inputs; this actor never configures or uses a proxy.

## Actor input object example

```json
{
  "asins": [
    "B0GVG9DKJP"
  ],
  "maxItems": 30,
  "page": 1,
  "pageSize": 30,
  "conditions": [],
  "sellerNames": [],
  "includeProductDetails": true,
  "includeMedia": true,
  "dedupe": true,
  "locale": "en-US",
  "concurrency": 1,
  "requestDelayMs": 400,
  "maxRetries": 2,
  "requestTimeoutMs": 45000
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing only verified public Amazon offer records.

## `keyValueStore` (type: `string`):

Key-value store containing the OUTPUT_SUMMARY run summary.

# 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 = {
    "asins": [
        "B0GVG9DKJP"
    ],
    "maxItems": 30,
    "page": 1,
    "pageSize": 30,
    "includeProductDetails": true,
    "includeMedia": true,
    "dedupe": true,
    "locale": "en-US",
    "concurrency": 1,
    "requestDelayMs": 400,
    "maxRetries": 2,
    "requestTimeoutMs": 45000
};

// Run the Actor and wait for it to finish
const run = await client.actor("w3crawler/amazon-offers-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 = {
    "asins": ["B0GVG9DKJP"],
    "maxItems": 30,
    "page": 1,
    "pageSize": 30,
    "includeProductDetails": True,
    "includeMedia": True,
    "dedupe": True,
    "locale": "en-US",
    "concurrency": 1,
    "requestDelayMs": 400,
    "maxRetries": 2,
    "requestTimeoutMs": 45000,
}

# Run the Actor and wait for it to finish
run = client.actor("w3crawler/amazon-offers-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 '{
  "asins": [
    "B0GVG9DKJP"
  ],
  "maxItems": 30,
  "page": 1,
  "pageSize": 30,
  "includeProductDetails": true,
  "includeMedia": true,
  "dedupe": true,
  "locale": "en-US",
  "concurrency": 1,
  "requestDelayMs": 400,
  "maxRetries": 2,
  "requestTimeoutMs": 45000
}' |
apify call w3crawler/amazon-offers-scraper --silent --output-dataset

```

## MCP server setup

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