# Amazon Search Scraper · 20 Marketplaces · Ranks & Ads (`molded_mountainpass/amazon-search-scraper`) Actor

Scrape Amazon search results by keyword or URL on 20 marketplaces: ASIN, title, price, list price, stars, reviews, sponsored/Prime/Amazon's Choice/Best Seller flags, delivery, coupon, bought-in-past-month and position, plus organic rank, sales estimate, video ads and brand banners. No login.

- **URL**: https://apify.com/molded_mountainpass/amazon-search-scraper.md
- **Developed by:** [Divya Raj](https://apify.com/molded_mountainpass) (community)
- **Categories:** E-commerce, SEO tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 search results

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 Search Scraper do?

**Amazon Search Scraper** is an Amazon search results scraper and keyword rank tracker. It turns any keyword or Amazon search URL into a clean table of **every product on the results page (the Amazon SERP)**, on **20 Amazon marketplaces**. Each row has the **ASIN, title, price, list price, stars, review count, page position, sponsored / Prime / Amazon's Choice / Best Seller flags, delivery promise, coupon and "bought in past month" volume**. Sponsored video ads and brand banners come along in the same run.

It reads [Amazon](https://www.amazon.com) search pages over plain HTTP, with no browser and no login, so runs are fast and cheap. On Apify you also get API access, scheduling, integrations (Google Sheets, Make, Zapier, webhooks), proxy rotation and run monitoring.

**Try it:** type a keyword, pick a marketplace and click **Start**. Or call it as an **Amazon search API** from your own code (see [Standby mode](#amazon-search-api-standby-mode)).

### Why use Amazon Search Scraper?

- **Keyword and rank tracking.** See where your products and your competitors' products rank for each keyword, with both the position shoppers see and an **organic rank** that skips ads.
- **Price and promotion monitoring.** Track prices, list prices, coupons and deals across marketplaces. **Monitoring mode** outputs only products that are new or changed since the last run.
- **Product and market research.** Find best sellers, compare ratings and reviews, and size demand with **estimated monthly sales** taken from Amazon's "bought in past month" label.
- **Advertising intelligence.** Every row says whether it's sponsored, and sponsored video ads and **brand banners** (with their featured ASINs) are captured too, so you see who is buying ads on a keyword.
- **Local prices.** Set a delivery ZIP or postal code to get the prices and delivery dates shoppers in that area see.

### How to scrape Amazon search results

1. Enter one or more keywords in **Search keywords** and choose a **Marketplace**, or paste Amazon search links into **Search URLs**.
2. Optionally set **Max results per keyword**, **Sort by**, a price range, minimum stars or **Prime only**.
3. Under **Proxy Configuration**, select the **Residential** group (see [proxies](#proxies-and-what-to-expect)).
4. Click **Start**.
5. Download the results from the **Output** tab as JSON, CSV, Excel or HTML, or fetch them with the API.

#### Which Amazon links work?

You don't need links at all: keywords plus a marketplace build the right URLs for you. If you paste links, use **search result pages**, the page you land on after typing in Amazon's search box. Their address contains **`/s?k=`**:

| Works | Doesn't work |
| :--- | :--- |
| `https://www.amazon.com/s?k=wireless+headphones` | `https://www.amazon.com/dp/B09BF64J55` (product page) |
| `https://www.amazon.de/s?k=kaffeemaschine` | `https://www.amazon.com/stores/Nike/page/...` (brand store) |
| `https://www.amazon.com/s?k=laptop&rh=n%3A565108` (filters kept) | `https://www.amazon.com/b?node=679255011` (category page) |

Unsupported links are skipped with a warning in the log; they don't crash the run.

### Input: keywords, marketplace and filters

All fields are on the **Input** tab. The main ones:

| Field | Default | Description |
| :--- | :--- | :--- |
| `searchQueries` | | Keywords. Each is a separate search, echoed in every row as `searchQuery`. |
| `startUrls` | | Amazon search URLs (`/s?k=...`). The marketplace comes from each URL. |
| `country` | `US` | US, CA, MX, BR, UK, DE, FR, IT, ES, NL, SE, PL, TR, JP, IN, AU, SG, SA, AE, EG. |
| `language` | `AUTO` | Language asked of Amazon. `AUTO` uses the marketplace's own. |
| `maxResultsPerQuery` | `50` | Most rows per keyword. `0` = no limit. |
| `maxResults` | `0` | Most rows in the whole run. `0` = no limit. |
| `maxPages` | `5` | Pages per keyword (1–20). A search also stops at its last page. |
| `sortBy` | `relevance` | `relevance`, `price-asc-rank`, `price-desc-rank`, `review-rank`, `date-desc-rank`, `featured-rank`. |
| `minPrice` / `maxPrice` | `0` | Price range in the marketplace's currency. `0` = open. |
| `minStars` | `0` | Minimum rating, 1–4, also checked on every row. |
| `primeOnly` | `false` | Prime-eligible products only (amazon.com). |
| `includeSponsored` | `true` | `false` leaves out sponsored products, video ads and banners. Positions stay as shoppers see them. |
| `deliveryZipCodes` | | Delivery postcode per marketplace, e.g. `{"US": "10001", "DE": "10115"}`. |
| `monitoringMode` | `off` | `changes` outputs only new or changed products (see below). |
| `concurrency` | `5` | Pages fetched at the same time (1–20). |
| `proxyConfiguration` | Apify Proxy | Proxy settings. Residential recommended. |

Example:

```json
{
  "searchQueries": ["echo dot", "smart speaker"],
  "country": "US",
  "maxResultsPerQuery": 50,
  "sortBy": "review-rank",
  "minStars": 4,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

Less common fields: `rankChangeThreshold` and `monitorStoreName` for monitoring, `saveHtml` for debugging, and `scrapeMode: "ads"` for the [sponsored-ads-only output](#sponsored-ads-only-output). The older field names `searchTerms`, `domain` and `maxItems` are still accepted.

### Output: Amazon search results data

One row per search result. A row from a live `wireless earbuds` search on amazon.com:

```json
{
  "asin": "B0FQFB8FMG",
  "title": "Apple AirPods Pro 3 Wireless Earbuds with Active Noise Cancellation",
  "url": "https://www.amazon.com/dp/B0FQFB8FMG",
  "marketplace": "US",
  "searchQuery": "wireless earbuds",
  "sortBy": "relevance",
  "page": 1,
  "positionOnPage": 2,
  "positionOverall": 2,
  "isSponsored": false,
  "isAmazonChoice": false,
  "isBestSeller": true,
  "isPrime": true,
  "price": { "value": 199.0, "currency": "$", "raw": "$199.00", "currencyCode": "USD" },
  "listPrice": { "value": 249.0, "currency": "$", "raw": "$249.00", "currencyCode": "USD" },
  "stars": 4.4,
  "reviewsCount": 16767,
  "thumbnailImage": "https://m.media-amazon.com/images/I/61solmQSSlL._AC_UY218_.jpg",
  "deliveryText": "Join Prime to get FREE delivery Today 6 PM - 11 PM",
  "fastDeliveryText": "Or Non-members get FREE delivery Mon, Oct 26",
  "badgeText": null,
  "couponText": null,
  "prevPurchased": true,
  "purchaseVolumeText": "10K+ bought in past month",
  "variantHint": null,
  "bestSellerCategory": "in Earbud & In-Ear Headphones",
  "input": { "country": "US", "sortBy": "relevance", "maxPages": 5, "...": "..." },
  "scrapedAt": "2026-10-21T05:52:27Z",
  "type": "result",
  "organicRank": 2,
  "adType": null,
  "badges": ["Best Seller", "Prime"],
  "boughtPastMonthCount": 10000,
  "estimatedMonthlySales": { "low": 10000, "high": 19999, "isEstimate": true },
  "deliveryLocation": "New York 10001",
  "zipApplied": null
}
```

Brand banners are `type: "banner"` rows with `headline`, `brand` and `featuredAsins`. Video ads are sponsored rows with `adType: "video"`; they sit outside the result grid, so their positions are empty. A page that still fails after retries becomes a free `type: "error"` row and the run continues.

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

#### Data fields

| Field | Description |
| :--- | :--- |
| `asin`, `title`, `url`, `thumbnailImage` | The product. |
| `marketplace`, `searchQuery`, `sortBy`, `input` | Which search the row came from. |
| `page`, `positionOnPage`, `positionOverall` | Position as shoppers see it, sponsored cards included. |
| `organicRank` | Position among organic results only. |
| `isSponsored`, `adType` | Sponsored flag and ad format (`sponsored_product`, `video`, `brand_banner`). |
| `isAmazonChoice`, `isBestSeller`, `bestSellerCategory`, `isPrime`, `badges`, `badgeText` | Badges on the card. |
| `price`, `listPrice` | `{value, currency, raw, currencyCode}`. |
| `stars`, `reviewsCount` | Rating and number of ratings. |
| `purchaseVolumeText`, `boughtPastMonthCount`, `estimatedMonthlySales` | "10K+ bought in past month", as text, as a number and as a low/high band. The band is an **estimate**: Amazon rounds the label down. |
| `couponText`, `deliveryText`, `fastDeliveryText`, `variantHint`, `prevPurchased` | Promotions, delivery promise and other card details. |
| `deliveryLocation`, `zipApplied` | The delivery location the page was priced for, and whether your postcode was applied. |
| `scrapedAt` | UTC timestamp. |

#### Sponsored-ads-only output

`scrapeMode: "ads"` keeps this Actor's original output: only the sponsored placements, as rows with `keyword`, `domain`, `page`, `asin`, `title`, `price`, `rating`, `reviewsCount`, `adPlacement` (`Headline Brand Banner`, `Sponsored Video Row Ad` or `Search Grid Inline`) and `scrapedAt`. API calls that send the older `searchTerms` / `domain` fields get this output automatically.

### Monitoring mode: only new or changed products

Set **Monitoring** to *Only new or changed results* and schedule the Actor, for example daily. It keeps each search's last results in a named key-value store (`amazon-search-monitor` by default) and outputs, and charges for, only:

- **new** products (`changeType: "new"`), and
- **changed** products (`changeType: "changed"`) whose price, list price, coupon, badges, rating, "bought in past month" figure or title changed, or whose rank moved by at least **Rank change that counts** places (default 3).

Changed rows carry `changedFields`, `priceDelta`, `rankDelta` (negative means it moved up) and the previous values. Use a different **Monitoring store name** per client or project to keep separate histories.

### Delivery ZIP or postal code

Prices, delivery dates and availability depend on the delivery address. Set **Delivery ZIP or postal code per marketplace**, e.g. `{"US": "10001", "DE": "10115"}`, at no extra charge. Every row shows `deliveryLocation` and `zipApplied`, so you never mistake default-location prices for local ones. Postcodes work on amazon.com, amazon.de and amazon.ca; amazon.co.uk doesn't accept them yet.

### Proxies and what to expect

Amazon serves full result pages most reliably to **residential** IP addresses, so select the Residential group under **Proxy Configuration**. On datacenter proxies, including the default Apify Proxy, you may get reduced pages, fewer results or a CAPTCHA. The Actor detects CAPTCHAs and reduced pages and retries with a fresh session, but it can't return data Amazon didn't serve.

A page usually has 16 to 60 products, depending on the keyword and the layout Amazon picks for the request.

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

**$1 per 1,000 results** ($0.001 per result), plus $0.001 per run start. Compute and proxy costs are included, so that's all you pay. For example, 50 results for one keyword cost about $0.05.

Error rows are never charged, and monitoring runs charge only for products that are new or changed. The **Pricing** tab always shows the current price.

Three ways to cap a run:

- **Max results per keyword** and **Max total results**: the number of rows.
- **Max pages per keyword**: the number of search pages read.
- **Maximum cost per run** in Run options: the run stops cleanly when it's reached.

### Tips

- Start with one keyword and `maxResultsPerQuery: 20` to check the output, then scale up.
- Use `sortBy: "review-rank"` with `minStars: 4` to find the best-rated products fast.
- Schedule daily runs with monitoring mode to build a price and rank history without paying for unchanged rows.
- Use the **Standby API** below when you need results in real time inside your own app.

#### Amazon search API (Standby mode)

With Standby, the Actor stays warm and answers HTTP requests instead of running once:

```
GET https://<your-actor>.apify.actor/?keyword=wireless+earbuds&domain=amazon.com&mode=search&maxPages=1
```

It responds with the rows as a JSON array. Query parameters: `keyword` (repeatable), `url` (repeatable), `domain`, `maxPages`, `mode` (`search` for every result; `ads`, the default, for sponsored ads only) and `zip` (a delivery postcode for `domain`).

### FAQ

**Is scraping Amazon legal?** This Actor collects only publicly visible, non-personal product data from search result pages. Scraping public data is generally lawful in many jurisdictions, but it depends on your location, purpose and the applicable terms. Review Amazon's Terms of Service and consult your own legal counsel before running at scale. You're responsible for how you use the output.

**Can I track Amazon keyword rankings?** Yes. Every row has `positionOverall` (as shoppers see it) and `organicRank` (ads excluded). Schedule a daily run, optionally with monitoring mode, to build a rank history per keyword and ASIN.

**Can I use it as an Amazon search results API?** Yes, in two ways: start runs through the Apify API and read the dataset, or call the Standby URL and get the rows back in the HTTP response.

**How is it different from other Amazon search scrapers?** Besides the standard fields (ASIN, title, price, stars, reviews, badges, sponsored flag, position), it adds organic rank, an estimated monthly sales band, delivery ZIP or postcode pricing, monitoring mode, sponsored video ads and brand banners with their featured ASINs.

**Does it collect personal data?** No. It extracts product listings and ads only.

**Why did I get few or no results?** Almost always the proxy: use Residential. The run's `RUN_STATS` record lists pages read and failed, CAPTCHAs, rows by type and why the run stopped.

**Can it scrape product detail pages?** No, only search result pages. Product page URLs are skipped with a warning.

**Known limitations.** Amazon changes its markup regularly; a major layout change can need an update. Tested live on 19 marketplaces in October 2026. **amazon.fr** currently answers every request with a JavaScript robot check, which an HTTP-only scraper can't pass, so FR searches return a free error row. Smaller marketplaces (MX, IT, TR, AE, PL) block more often; the Actor retries with fresh sessions. `isPrime` is most reliable on amazon.com.

### Support

Found a bug or need a field that isn't extracted? Open a ticket on the **Issues** tab. Custom scraping solutions are available on request.

# Actor input Schema

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

Keywords to search for. Each keyword is a separate search on the marketplace below, and every row says which keyword found it (`searchQuery`). You can combine keywords with Search URLs.

## `startUrls` (type: `array`):

Amazon search result URLs (the address after you search on Amazon, containing `/s?k=`). Use them for filters Amazon's own URL supports, such as a category. The marketplace is taken from each URL's domain. Product pages (/dp/) are skipped.

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

Amazon marketplace for the Search keywords. Search URLs keep their own marketplace. Empty: amazon.com.

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

Language the Actor asks Amazon for (Accept-Language). Auto uses the marketplace's own language, for example German on amazon.de. Pick English to get English text everywhere Amazon offers it.

## `maxResultsPerQuery` (type: `integer`):

Most result rows per keyword or URL. 0 = no limit (Max pages then limits the run). A page has about 16 results.

## `maxResults` (type: `integer`):

Most result rows in the whole run, across all keywords. 0 = no limit. The run also stops cleanly at the maximum cost per run set in Run options.

## `maxPages` (type: `integer`):

How many result pages to read per keyword (Amazon shows up to about 20). A search stops earlier at its last page, or when a page has fewer than 4 organic results.

## `sortBy` (type: `string`):

Amazon's sort order, as in the Sort by menu on the search page. Every row says which one was used (`sortBy`).

## `minPrice` (type: `integer`):

Only products from this price, in the marketplace's currency (dollars on amazon.com, euros on amazon.de, ...). 0 = no minimum.

## `maxPrice` (type: `integer`):

Only products up to this price, in the marketplace's currency. 0 = no maximum.

## `minStars` (type: `integer`):

Only products rated at least this many stars: 1 to 4, or 0 for all. 4 uses Amazon's own '4 Stars & Up' filter; every value is also checked on each row, and unrated products are left out.

## `primeOnly` (type: `boolean`):

Only Prime-eligible products, using Amazon's Prime filter. Amazon offers this filter on amazon.com only; other marketplaces ignore it.

## `includeSponsored` (type: `boolean`):

Off: sponsored listings, video ads and brand banners are left out. They still count in positionOnPage, so positions match what shoppers see.

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

'Every search result' outputs each organic and sponsored product (see the README for all fields). 'Sponsored ads only' is this Actor's original output: sponsored grid ads, video ads and brand banners in the original format. Without this field, API calls get every search result when they use the fields above (searchQueries, country, ...) and the original output when they use the original ones (searchTerms, domain).

## `monitoringMode` (type: `string`):

'Only new or changed' remembers every search's last results and outputs (and charges) only products that are new or whose price, list price, coupon, badges, rating, 'bought in past month' or rank changed. Rows get changeType, changedFields, priceDelta and rankDelta. Schedule the Actor to track a keyword daily. Works with 'Every search result'.

## `rankChangeThreshold` (type: `integer`):

In monitoring, a product counts as changed when its organic rank (or an ad's position) moves by at least this many places.

## `monitorStoreName` (type: `string`):

Named key-value store that keeps the last results of each search. Use a different name to keep separate histories, for example one per client.

## `deliveryZipCodes` (type: `object`):

Prices, delivery dates and availability depend on where Amazon delivers. Give a postcode per marketplace, by country code or domain, for example {"US": "10001", "DE": "10115", "amazon.co.uk": "SW1A 1AA"}. No extra charge. Rows show deliveryLocation and zipApplied (whether Amazon accepted it).

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

How many pages are fetched at the same time. The pages of one keyword are always read in order, so this speeds up runs with several keywords. 3-5 is reliable; more is faster but meets more temporary blocks.

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

Amazon blocks datacenter IPs aggressively. Select RESIDENTIAL groups for reliable results; the default works but may return few or zero ads.

## `saveHtml` (type: `boolean`):

Store each search page's HTML in the run's key-value store. Useful when reporting a parsing problem.

## `searchTerms` (type: `array`):

Older name of Search keywords, still accepted.

## `domain` (type: `string`):

Older way to pick the marketplace, e.g. amazon.de, still accepted. Marketplace (country) wins when both are set.

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

Older name of Max total results, still accepted.

## Actor input object example

```json
{
  "searchQueries": [
    "wireless earbuds"
  ],
  "country": "US",
  "language": "AUTO",
  "maxResultsPerQuery": 50,
  "maxResults": 0,
  "maxPages": 5,
  "sortBy": "relevance",
  "minPrice": 0,
  "maxPrice": 0,
  "minStars": 0,
  "primeOnly": false,
  "includeSponsored": true,
  "scrapeMode": "search",
  "monitoringMode": "off",
  "rankChangeThreshold": 3,
  "monitorStoreName": "amazon-search-monitor",
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "saveHtml": false
}
```

# Actor output Schema

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

No description

# 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": [
        "wireless earbuds"
    ],
    "country": "US",
    "scrapeMode": "search"
};

// Run the Actor and wait for it to finish
const run = await client.actor("molded_mountainpass/amazon-search-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": ["wireless earbuds"],
    "country": "US",
    "scrapeMode": "search",
}

# Run the Actor and wait for it to finish
run = client.actor("molded_mountainpass/amazon-search-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": [
    "wireless earbuds"
  ],
  "country": "US",
  "scrapeMode": "search"
}' |
apify call molded_mountainpass/amazon-search-scraper --silent --output-dataset

```

## MCP server setup

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