# Amazon Product Scraper – Prices, Reviews, Offers & Sellers (`badr_xba/amazon-product-scraper`) Actor

Scrape Amazon products from search, category, best-seller and product URLs on every Amazon country: price, list price, stock, delivery, rating breakdown, reviews count, features, attributes, variants, images, best-seller ranks, plus other sellers' offers and seller details. Pay only for results.

- **URL**: https://apify.com/badr_xba/amazon-product-scraper.md
- **Developed by:** [Badr Bouargan](https://apify.com/badr_xba) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 1 total users, 1 monthly users, 96.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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

## Amazon Product Scraper – Prices, Reviews, Offers & Sellers

**Paste any Amazon link, ASIN or keyword and get clean product data (price, list price, discount, rating, reviews, stock, seller, delivery, images, variants) from every Amazon country. You pay only for the products you get.**

No Amazon account, no API key, no setup. Messy input is fine: tracking parameters, mobile links, short links, lowercase ASINs, several links pasted on one line and duplicates are all cleaned up for you.

### How to use it in 3 steps

1. **Paste** Amazon URLs, ASINs or search keywords into the first box. One per line is best, but a comma-separated list works too.
2. **Choose** how many products you want per URL with **Max results (per start URL)**.
3. **Click Start**, then download the results as JSON, CSV, Excel or HTML, or read them through the API.

The prefilled run (a "keyboard" search on amazon.com, 10 products) takes about a minute and costs about $0.05.

### What can you paste?

| Paste this | You get |
|---|---|
| Search `https://www.amazon.com/s?k=keyboard` | Every product on the result pages, in full detail |
| Keywords `wireless mouse` (or the **Search keywords** box) | The same as a search URL, on the **Amazon site** you pick |
| Category with any filter `https://www.amazon.com/s?bbn=…&rh=n%3A…` | Products in that category, with your price/brand/rating filters kept |
| Best sellers `https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics` (also new releases, movers & shakers, most wished for) | The ranked top 60, with rank and category |
| Product `…/dp/B09X7MPX8L`, `…/gp/product/…`, mobile `…/gp/aw/d/…`, `m.` / `smile.` subdomains, with `ref=`, `th=`, `psc=`… | That product |
| Short link `amzn.to/…`, `a.co/d/…` | The product it points to |
| ASIN `B09X7MPX8L` (any case) | That product, on the **Amazon site** you pick (amazon.com by default) |

**Supported countries:** amazon.com, .co.uk, .de, .fr, .es, .it, .nl, .se, .pl, .com.be, .ie, .com.tr, .ca, .com.mx, .com.br, .co.jp, .in, .com.au, .sg, .ae, .sa, .eg, .co.za. Full URLs always keep their own country.

Turn **Scrape product details** off to keep only what the result list shows (title, price, list price, rating, reviews, image, position, sponsored flag, badge). It is several times faster.

### Input example

```json
{
  "categoryOrProductUrls": [
    { "url": "https://www.amazon.com/s?k=keyboard" },
    { "url": "https://www.amazon.de/dp/B09X7MPX8L?th=1&psc=1" },
    { "url": "b07w4dhnbk, B0BSHF7WHW" }
  ],
  "searchKeywords": ["mechanical keyboard"],
  "amazonDomain": "amazon.com",
  "maxItemsPerStartUrl": 50,
  "maxOffers": 5,
  "scrapeSellers": true,
  "zipCode": "10001"
}
```

Only the first box matters. Every other field is optional and has a sensible default.

### Output example

A real row (amazon.fr product page, shortened):

```json
{
  "title": "SanDisk 1To Extreme microSDXC, carte micro sd + adaptateur SD, UHS-I, jusqu'à 190 Mo/s…",
  "url": "https://www.amazon.fr/dp/B09X7MPX8L",
  "asin": "B09X7MPX8L",
  "parentAsin": "B0DSDX1D16",
  "brand": "SANDISK",
  "price": { "value": 244.78, "currency": "€" },
  "listPrice": { "value": 278.99, "currency": "€" },
  "discountPercent": 12,
  "inStock": true,
  "inStockText": "En stock",
  "delivery": "jeudi 15 octobre",
  "deliveryText": "Livraison à 3,99 € jeudi 15 octobre . Commandez dans les 5 h 18 min . Détails",
  "condition": "New",
  "stars": 4.7,
  "reviewsCount": 113,
  "features": ["Gagnez du temps avec des vitesses de déchargement de carte allant jusqu'à 190 Mo/s…"],
  "thumbnailImage": "https://m.media-amazon.com/images/I/716kSUlHouL._AC_SY300_SX300_QL70_ML2_.jpg",
  "highResolutionImages": ["https://m.media-amazon.com/images/I/716kSUlHouL._AC_SL1500_.jpg"],
  "variantAsins": ["B0DCW7MST8", "B09X7C2GBC", "B09X7MPX8L"],
  "variantAttributes": [{ "key": "Taille", "value": "1 TB" }, { "key": "Style", "value": "Standard" }],
  "returnPolicy": "Retours de 14 jours et garanties légales",
  "seller": { "name": "Amazon", "id": null, "url": null, "shipsFrom": null },
  "sellerName": "Amazon",
  "reviewsLink": "https://www.amazon.fr/product-reviews/B09X7MPX8L",
  "loadedCountryCode": "FR",
  "originalAsin": "B09X7MPX8L",
  "input": "https://www.amazon.fr/dp/B09X7MPX8L"
}
```

Rows from a search also carry `categoryPageData` (`categoryUrl`, `productPosition`, `pageNumber`, `isSponsored`, `bestsellerBadge`). Rows from best-seller lists carry `bestsellerPageData` (rank and category). With **Maximum offers per product**, each row gets an `offers` array (position, price, condition, seller with rating, ships from, delivery). With **Scrape sellers**, `seller` also gets rating, ratings count, positive feedback %, business name and address.

Prices are always numbers with a separate `currency`. A field the page does not show is `null`; it is never invented.

**Output tabs:** *Products (overview)* is a table with image, title, ASIN, price, list price, discount %, rating, reviews, availability, seller, brand and link. *Offers and sellers* is another view, and *All fields* gives the full JSON/CSV/Excel.

Each run also saves:

- **RUN_SUMMARY**: products, offers and sellers saved, stop reason, requests, retries and amount charged.
- **FAILED_INPUTS**: every input that gave nothing, with an error code: `invalid_url`, `product_not_found`, `shortened_url_invalid`, `no_results_found`, `blocked`. **Failed inputs are never billed.** A bad line never stops the rest of the run.

### Pricing

Pay per event. Platform usage is included.

| Event | Free | Starter | Scale | Business |
|---|---|---|---|---|
| **Result** (one product saved) | $5.00 / 1,000 | $4.00 / 1,000 | $3.50 / 1,000 | $3.00 / 1,000 |
| **Offer** (one other-seller offer attached to a product) | $2.50 / 1,000 | $2.00 / 1,000 | $1.70 / 1,000 | $1.50 / 1,000 |
| **Seller** (one seller page read) | $2.50 / 1,000 | $2.00 / 1,000 | $1.70 / 1,000 | $1.50 / 1,000 |
| **Delivery location** (one delivery address set) | $60.00 / 1,000 | $50.00 / 1,000 | $40.00 / 1,000 | $35.00 / 1,000 |

You pay for offers, sellers and delivery locations only when you turn those options on. Each seller is read once per run, and a delivery address is charged at most once per Amazon site per run. **Example:** 100 products with full details cost $0.50 on the Free plan. To cap spending, set **Maximum results for the whole run** or a maximum cost per run, and the run stops cleanly at that limit.

### What it can and cannot do

**Can:**

- Scrape searches, categories with filters, best-seller-type lists and product pages on 23 Amazon countries.
- Collect offers from other sellers and seller details.
- Set a delivery country or ZIP code so prices and stock match that place.
- Let you choose the page language.
- Resume after a platform migration without billing twice.

**Cannot:**

- Get full review texts. You get the rating, star breakdown, ratings count and AI review summary.
- Scrape pages that need a login, or seller inventories ("all products of seller X").
- Go past Amazon's own limit of roughly 7–20 result pages per search. To get more, split the search with filters (see below).

### FAQ

**Do I need an Amazon account or API key?** No.

**Can I paste a whole list at once?** Yes. One per line, or comma-separated in one line. Duplicates are removed, including the same product pasted with different tracking parameters.

**How do I scrape ASINs from amazon.de or another country?** Pick the country in **Amazon site**, or paste full URLs such as `https://www.amazon.de/dp/B09X7MPX8L`.

**Why is the price missing on some products?** The product may be unavailable at the delivery address or sold only by other sellers. Turn on offers, or set a delivery country or ZIP code.

**Is it legal to scrape Amazon?** The Actor reads public pages, as any visitor sees them. Use the data in line with the laws that apply to you.

### Troubleshooting

- **`blocked` in FAILED_INPUTS / "Amazon refused the page":** in **Proxy**, switch to the RESIDENTIAL group. With residential proxies, the Actor uses addresses in each Amazon site's country automatically.
- **`no_results_found`:** the search or category is empty for that country or address. Open the URL in your browser to check.
- **`invalid_url`:** the line is not an Amazon URL, ASIN or keyword (for example an eBay link or the bare Amazon home page).
- **Prices in the wrong currency or for the wrong place:** set **Deliver to country** or **ZIP code**.
- **You need more than ~300 products from one search:** add several narrower URLs (price ranges, brands, sub-categories).
- **Still stuck?** Open an issue on the **Issues** tab with the run ID and the URL.

### Use it via API

**Python** (`pip install apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("badr_xba/amazon-product-scraper").call(run_input={
    "categoryOrProductUrls": [{"url": "https://www.amazon.com/s?k=keyboard"}],
    "maxItemsPerStartUrl": 20,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item.get("price"), item.get("stars"))
```

**JavaScript** (`npm install apify-client`)

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('badr_xba/amazon-product-scraper').call({
    categoryOrProductUrls: [{ url: 'https://www.amazon.com/dp/B09X7MPX8L' }],
    asins: ['B07W4DHNBK'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL** (runs the Actor and returns the products in one call)

```bash
curl -X POST "https://api.apify.com/v2/acts/badr_xba~amazon-product-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchKeywords": ["wireless mouse"], "amazonDomain": "amazon.co.uk", "maxItemsPerStartUrl": 10}'
```

### Integrations

- **Make, Zapier and n8n:** use the Apify app or node to start a run and read the dataset.
- **Google Sheets, Airtable, Slack and webhooks:** send results there through Apify integrations.
- **MCP:** AI agents (Claude, Cursor and others) can call this Actor through the Apify MCP server (`mcp.apify.com`).
- **Schedules:** run the Actor on a schedule to track prices, stock, discounts and rankings over time.

# Actor input Schema

## `categoryOrProductUrls` (type: `array`):

Paste anything from Amazon, one per line (several links pasted in one line are split automatically, duplicates removed):<br>• a search: <code>https://www.amazon.com/s?k=keyboard</code><br>• a category, filters kept: <code>https://www.amazon.com/s?bbn=16225016011\&rh=n%3A20972781011</code><br>• a best-seller / new-release list: <code>https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics</code><br>• a product, any shape: <code>https://www.amazon.de/dp/B09X7MPX8L</code>, <code>/gp/product/…</code>, mobile <code>/gp/aw/d/…</code>, with or without <code>ref=</code>/<code>th=</code>/<code>psc=</code><br>• a short link: <code>https://amzn.to/…</code>, <code>a.co/d/…</code><br>• a bare ASIN: <code>B09X7MPX8L</code> (any case) or plain keywords: <code>wireless mouse</code> — both use the <b>Amazon site</b> option below.<br>Every Amazon country works: .com, .co.uk, .de, .fr, .es, .it, .nl, .se, .pl, .com.be, .com.tr, .ca, .com.mx, .com.br, .co.jp, .in, .com.au, .sg, .ae, .sa, .eg, .co.za, .ie.

## `searchKeywords` (type: `array`):

Optional. Words to search on the chosen Amazon site, one search per line (e.g. <code>mechanical keyboard</code>, <code>usb c cable</code>). Same as pasting the search URL above.

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

Optional. Product codes alone, one per line or comma-separated (e.g. <code>B09X7MPX8L</code>), read on the chosen Amazon site (amazon.com by default). You can also paste ASINs in the first box.

## `amazonDomain` (type: `string`):

Amazon country used for bare ASINs and search keywords. Full URLs always keep their own country.

## `maxItemsPerStartUrl` (type: `integer`):

Maximum products saved for each start URL. 0 = no limit (the search stops when Amazon has no more pages).

## `maxSearchPagesPerStartUrl` (type: `integer`):

Stops after this many result pages for each search or category, even if the results limit is not reached. Amazon itself shows at most about 7–20 pages per search: to go further, use a narrower category or filters.

## `scrapeProductDetails` (type: `boolean`):

On (default): opens every product found in a list for the full data — features, description, attributes, variants, seller, delivery, rating breakdown, best-seller ranks, images. Off: keeps only the quick data shown in the list (title, price, rating, reviews, image, position, sponsored), much faster.

## `maxOffers` (type: `integer`):

Adds the offers of other sellers (price, condition, seller, rating, ships from, delivery) to each product, up to this number. 0 = no offers. Billed per offer.

## `scrapeSellers` (type: `boolean`):

Opens the page of the featured seller (and of each offer's seller when offers are on) to add its rating, ratings count, positive feedback, business name and address. Billed per seller page read; each seller is read once per run.

## `language` (type: `string`):

Language of the pages. Each Amazon country supports a few languages; an unsupported choice falls back to the country's default.

## `countryCode` (type: `string`):

Two-letter country code used as the delivery address (e.g. US, DE, MA), so prices, availability and delivery dates match that country. Leave empty to use the address Amazon picks. Billed once per Amazon site per run, only when the address is set.

## `zipCode` (type: `string`):

Postal code inside the Amazon site's own country (e.g. 10001 on amazon.com, 10115 on amazon.de). More precise than the country. Billed once per Amazon site per run, only when the address is set.

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

Hard ceiling on products saved (and billed) across all start URLs. 0 = no ceiling. The run also stops cleanly when your maximum cost per run is reached.

## `proxyCountry` (type: `string`):

Country of the residential proxy addresses. Auto picks the country of each Amazon site (amazon.de → Germany). Only applies with the residential proxy group.

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

The default Apify proxy works for most Amazon sites and is the cheapest. Switch to the residential group if many pages are refused.

## Actor input object example

```json
{
  "categoryOrProductUrls": [
    {
      "url": "https://www.amazon.com/s?k=keyboard"
    }
  ],
  "amazonDomain": "amazon.com",
  "maxItemsPerStartUrl": 10,
  "maxSearchPagesPerStartUrl": 9999,
  "scrapeProductDetails": true,
  "maxOffers": 0,
  "scrapeSellers": false,
  "maxItems": 0,
  "proxyCountry": "AUTO_SELECT_PROXY_COUNTRY",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Table: image, title, ASIN, price, list price, discount %, rating, reviews, availability, seller, brand and link.

## `offers` (type: `string`):

Featured seller, number of offers and the offers themselves.

## `allFields` (type: `string`):

Every field as JSON, CSV or Excel.

## `runSummary` (type: `string`):

Products, offers and sellers saved, stop reason, failures, requests and amount charged.

## `failedInputs` (type: `string`):

Start URLs that gave nothing, with an error code (invalid_url, product_not_found, no_results_found, blocked…).

# 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 = {
    "categoryOrProductUrls": [
        {
            "url": "https://www.amazon.com/s?k=keyboard"
        }
    ],
    "maxItemsPerStartUrl": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("badr_xba/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 = {
    "categoryOrProductUrls": [{ "url": "https://www.amazon.com/s?k=keyboard" }],
    "maxItemsPerStartUrl": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("badr_xba/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 '{
  "categoryOrProductUrls": [
    {
      "url": "https://www.amazon.com/s?k=keyboard"
    }
  ],
  "maxItemsPerStartUrl": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call badr_xba/amazon-product-scraper --silent --output-dataset

```

## MCP server setup

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