# Amazon Product Scraper (`web7/amazon-product-scraper`) Actor

Amazon product data by ASIN or URL in 12 marketplaces: price, list price, rating, review count, brand, stock and images. The item cap is global, not per input. No country surcharge. Unavailable or removed products come back with a reason and are never charged.

- **URL**: https://apify.com/web7/amazon-product-scraper.md
- **Developed by:** [Matheus Gaspar](https://apify.com/web7) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$7.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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Amazon Product Scraper — honest pricing, a real cap

**Extracts [Amazon](https://www.amazon.com) product data by ASIN or URL**: title, price, list price, rating, review count, brand, availability, image and feature bullets. Works across 12 Amazon marketplaces, with no login and no surcharge for switching country.

It was built around two complaints that come up again and again on competing scrapers: **billing that blows past the limit you set**, and **a surcharge for choosing a country**. Neither exists here.

### Why this Amazon scraper

**The cap is global, not per input.** You set `maxItems` and that is the maximum number of products for the entire run — not a limit applied separately to each entry in your list. That is the difference between asking for 100 and getting 100, versus asking for 100 with 20 inputs and finding 2,000 on the invoice.

**You only pay for what was delivered.** A product removed from Amazon, an invalid ASIN, or a blocked page produces a record with `available: false` and an explanation of what happened — and is **not charged**. No paying for empty rows.

That rule extends to partial deliveries. If Amazon never returns a price block after five attempts from five different IPs, the record still comes back with title, brand, rating, reviews and images, plus a `warning` field saying exactly what was missing — and it is **not charged either**. Price is the field you came for; a record without it is not a sale.

**Changing country does not cost more.** Querying `amazon.co.uk` instead of `amazon.com` is the same work and the same price. It is just a different domain.

**Blocks become retries, not errors.** Each attempt goes out through a different residential IP, in the same country as the domain, with increasing backoff. Captchas and 503s are treated as transient; the run only gives up after five attempts, and even then it returns a record explaining why instead of failing the whole job.

That last detail matters more than it looks: **with an IP from the wrong country, Amazon renders the product page with no price block and no buy button at all** — full page, title and reviews present, price silently missing. Matching the proxy country to the marketplace is what keeps the price field populated.

### What you can use it for

- **Price monitoring** — track your own or a competitor's price and list price over time, and compute the real discount.
- **Cross-market research** — compare a product across marketplaces to find where it is cheapest and where it is out of stock. Note that ASINs are usually marketplace-specific, so you need the ASIN of each country's listing, not the US one (see the FAQ).
- **Catalog enrichment** — fill titles, brands, images and feature bullets for a list of ASINs you already own.
- **Review intelligence** — rating and review count as a demand signal before you source a product.
- **Stock alerts** — `inStock` flips as soon as the buy box disappears.

### How to use the Amazon Product Scraper

1. Click **Try for free**.
2. Paste the ASINs or product URLs. You can mix both formats freely.
3. Pick the country and set the item cap.
4. Click **Start** and download the result as JSON, CSV, Excel or HTML.

To automate it, schedule runs or call the Actor from the [Apify API](https://docs.apify.com/api/v2).

### Input

| Field | Type | Description |
| --- | --- | --- |
| `productUrls` | array | ASINs (`B07FZ8S74R`) or full product URLs. Duplicates are dropped automatically. |
| `country` | string | `US`, `BR`, `UK`, `DE`, `FR`, `ES`, `IT`, `CA`, `MX`, `JP`, `IN`, `AU`. |
| `maxItems` | integer | **Total** cap for the run. Your account is never charged above it. |

```json
{
    "productUrls": ["B07FZ8S74R", "https://www.amazon.com/dp/B0BDHWDR12"],
    "country": "US",
    "maxItems": 100
}
```

### Output

```json
{
    "asin": "B0BDHWDR12",
    "url": "https://www.amazon.com/dp/B0BDHWDR12",
    "country": "US",
    "available": true,
    "title": "Apple AirPods Pro (2nd Gen) Wireless Earbuds",
    "brand": "Apple",
    "price": 249,
    "currency": "$",
    "rating": 4.7,
    "reviewsCount": 57939,
    "inStock": true,
    "image": "https://m.media-amazon.com/images/I/...jpg",
    "features": ["Active Noise Cancellation", "..."]
}
```

You can download the dataset in JSON, HTML, CSV or Excel.

| Field | What it is |
| --- | --- |
| `available` | `false` when the product is gone, the ASIN is invalid, or the page would not open. Not charged. |
| `title` | Product title as shown on the page. |
| `price` | Current price as a number, already normalized across locale formats. Absent when out of stock. |
| `listPrice` | Struck-through list price when present. Compare against `price` to get the discount. |
| `currency` | Currency symbol or code detected on the page. |
| `rating` | Rating from 0 to 5. |
| `reviewsCount` | Total review count, with no thousands separator. |
| `inStock` | Availability read from the page's stock block. |
| `image` | Main product image URL. |
| `features` | Up to 10 feature bullets. |
| `warning` | Present only when everything except the price came through. That record is not charged. |
| `error` | Explains why a record came back empty. |

### How much does it cost to scrape Amazon?

**$0.007 per product — $7.00 per 1,000.** One event, nothing else: no per-offer charge, no per-country charge, and no charge for run time, so a slow run never costs more than a fast one.

That single number is the whole bill. Scrapers that advertise a lower headline rate often add a second event for offers and a third for switching marketplace, so the amount you actually pay is not the number on the listing.

Records with `available: false` produce no billable event. Neither do records carrying a `warning`, which means the price never came through. In a 15-product test run this affected 1 record — you get the data, you do not get the bill.

### Tips

- Prefer ASINs over long URLs: same result, smaller input, and no risk of a tracking parameter interfering.
- Always set `maxItems`, even in testing. It is your safety net.
- ASINs are usually **marketplace-specific**. A US ASIN often returns 404 on amazon.de or amazon.co.jp — that is Amazon's catalog, not a scraper failure. Take each country's ASIN from its own product URL.
- If many records come back with `available: false` and a blocking error, confirm the residential proxy is enabled.

### FAQ

**Is scraping Amazon legal?** This Actor reads only public product pages, with no login and no customer personal data. You are still responsible for respecting Amazon's terms of service and the laws that apply to your use case.

**Why do some products come back with no price?** Products that are out of stock do not display a price on the page. The record comes back with `inStock: false` and the price absent — that is the correct data, not a failure.

**Why does my ASIN return `available: false` in another country?** Because it very likely does not exist there. Amazon assigns ASINs per marketplace: `B0BDHWDR12` resolves on amazon.com but returns 404 on amazon.co.uk, amazon.de and amazon.co.jp. Open the product on the target country's site and use the ASIN from that URL. Those 404 records are never charged.

**Can I search by keyword instead of ASIN?** Not yet. This version works with identified products. Ask on the **Issues** tab if you need it.

**Why is `reviewsCount` sometimes over a million?** Because some products really do have that many. The parser handles thousands separators in every locale format, so `1,038,159 ratings` becomes `1038159` rather than `1.038`.

**I found a problem.** Open a ticket on the **Issues** tab. I answer there.

# Actor input Schema

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

ASINs ou URLs de produto da Amazon. Aceita os dois formatos misturados; repetidos são descartados.

## `country` (type: `string`):

Define o domínio da Amazon consultado. Não há cobrança extra por trocar de país.

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

Limite TOTAL de produtos da execução, não por item da lista. Sua conta nunca é cobrada acima disso.

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

Proxy residencial é o que mantém a taxa de bloqueio baixa.

## Actor input object example

```json
{
  "productUrls": [
    "B07FZ8S74R",
    "https://www.amazon.com/dp/B0BDHWDR12"
  ],
  "country": "US",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One record per product, including the ones marked unavailable with the reason why.

# 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 = {
    "productUrls": [
        "B07FZ8S74R",
        "https://www.amazon.com/dp/B0BDHWDR12"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("web7/amazon-product-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 = { "productUrls": [
        "B07FZ8S74R",
        "https://www.amazon.com/dp/B0BDHWDR12",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("web7/amazon-product-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 '{
  "productUrls": [
    "B07FZ8S74R",
    "https://www.amazon.com/dp/B0BDHWDR12"
  ]
}' |
apify call web7/amazon-product-scraper --silent --output-dataset

```

## MCP server setup

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