# Amazon Search Results Scraper - Product Search & Keyword Rank (`tagadanar/amazon-search-scraper`) Actor

Amazon search results as flat rows from keywords or search links: rank and organic rank, price, list price, rating, reviews, bought in past month, Prime, Best Seller, Amazon's Choice and sponsored flags. amazon.com. $1 per 1,000 results + $0.001/run, usage included.

- **URL**: https://apify.com/tagadanar/amazon-search-scraper.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** E-commerce, SEO tools
- **Security:** Limited permissions
- **Stats:** 4 total users, 3 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 search 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 Search Results Scraper

Type a keyword (or paste an Amazon search link) and get the results page back
as a flat table, in Amazon's order: rank, organic rank, ASIN, title, price, list
price, discount, rating, review count, "bought in past month", Prime, Best
Seller and Amazon's Choice badges, and whether the slot is a paid ad. One row
per result, **$1 per 1,000 results**, no API key, no proxy to set up.

It reads search result pages only and never opens product pages, which is why
it is fast and cheap. If you need the product page itself (Best Sellers Rank,
seller, stock, image gallery), use
[Amazon Product Scraper](https://apify.com/tagadanar/amazon-product-scraper).

### What you get

| field | example | notes |
| --- | --- | --- |
| `searchQuery` | `wireless mouse` | the keyword that found the row (`null` for a category link without one) |
| `position` | `3` | rank on the results, all slots counted, across pages |
| `organicPosition` | `2` | rank among organic results only; `null` on sponsored slots |
| `page` / `positionOnPage` | `1` / `3` | where the card sat |
| `asin` | `B004YAVF8I` | |
| `title` | `Logitech M185 Compact Ambidextrous…` | |
| `url` | `https://www.amazon.com/dp/B004YAVF8I` | clean link, no tracking blob |
| `image` | `https://m.media-amazon.com/images/I/…jpg` | |
| `price` / `currency` / `priceText` | `12.99` / `USD` / `$12.99` | `null` when the card shows no offer ("See options") |
| `listPrice` / `discountPercent` | `17.99` / `28` | the struck-through List or Typical price |
| `rating` / `reviewCount` | `4.4` / `45515` | |
| `boughtInPastMonth` / `boughtInPastMonthCount` | `10K+ bought in past month` / `10000` | the count is Amazon's floor ("10K+" = at least 10,000) |
| `isPrime` | `true` | the card offers Prime delivery |
| `isBestSeller` / `bestSellerCategory` | `true` / `Computer Mice` | "Best Seller in Computer Mice" |
| `isAmazonsChoice` | `true` | |
| `badges` | `["Best Seller", "Limited time deal"]` | also Climate Pledge Friendly, New Arrival |
| `sponsored` | `false` | ad slots are labelled, never hidden |
| `couponText`, `delivery`, `availability` | `Save 15%`, `FREE delivery Tomorrow…`, `Only 3 left in stock` | as Amazon words them |
| `brand` | `Logitech` | only where Amazon prints a brand line on the card |
| `totalResults` | `45326` | the result count Amazon claims for the search |
| `status` | `ok` | `price-withheld` rows were delivered free (see Pricing) |

The marketplace is **amazon.com**, read the way a shopper in the United States
sees it, in US dollars.

### Who uses it

**Keyword rank tracking.** Every row carries its rank and its organic rank, so
you can schedule a keyword list daily and chart where your ASIN, and your
competitors', sit on the first pages, organic and paid separately.

**Sponsored share.** `sponsored` on every row tells you who is buying the
keyword and how many of the first slots are ads.

**Product and niche research.** Price, rating, review count and "bought in past
month" side by side for a whole keyword, sortable by demand rather than by
whatever Amazon ranked first today.

**Price monitoring across a category.** Paste a search link with your own
department and filters, run it on a schedule, and diff the datasets.

### Input

```json
{
  "keywords": ["wireless mouse", "usb c hub"],
  "maxResultsPerSearch": 100,
  "sort": "relevance",
  "includeSponsored": true
}
```

Filters, all checked again on every row before it is delivered:

```json
{
  "keywords": ["mechanical keyboard"],
  "minPrice": 30,
  "maxPrice": 120,
  "minRating": "4",
  "primeOnly": true,
  "includeSponsored": false,
  "maxResultsPerSearch": 200
}
```

A search link from your browser keeps its department, filters and sort:

```json
{
  "searchUrls": ["https://www.amazon.com/s?k=usb+c+hub&rh=n%3A172282&s=review-rank"]
}
```

| input | what it does |
| --- | --- |
| `keywords` | one search per keyword |
| `searchUrls` | amazon.com search result links (`/s?k=…`); product links are not search pages and are skipped |
| `sort` | Featured, price low to high, price high to low, average review, newest, best sellers |
| `maxResultsPerSearch` | stop each search after this many results (default 50, up to 1,000) |
| `maxPagesPerSearch` | how deep to page (up to 20, Amazon's own limit) |
| `minPrice` / `maxPrice` | price range in US dollars, sent to Amazon as its price filter and checked on every row |
| `minRating` | minimum stars: 4.5, 4, 3, 2 or 1 and up |
| `primeOnly` | Prime-eligible results only |
| `includeSponsored` | turn off to keep organic results only |

### Pricing

Pay per result delivered, never per page read.

| event | price |
| --- | --- |
| Search result | **$1.00 per 1,000** ($0.90 Bronze, $0.80 Silver, $0.70 Gold) |
| Actor start | $0.001 per run |

Platform usage is included: there is nothing else to pay and no proxy to fund.
Results dropped by your filters cost nothing. A page that Amazon served as its
cached copy with no price on any card is delivered free, each row marked
`status: "price-withheld"`.

### FAQ

**How deep can one keyword go?**
Twenty result pages. Amazon advertises tens of thousands of results for a broad
keyword but stops paginating at page 20, and past that it keeps answering with a
page of filler that looks perfectly healthy. The actor stops at the last real
page, never bills the filler, and says in the run status where and why each
search stopped. A page holds about 16 to 48 results depending on the layout, so
plan on a few hundred per keyword; split a broad keyword (brand, model, colour)
for more.

**What happens when Amazon refuses a request?**
Amazon's 503 is a throttle, not a ban, so a refused page is retried on a second
TLS fingerprint and a second route with fresh cookies before the actor gives up.
If Amazon still refuses, the run fails with a status starting `BLOCKED:` that
names what was tried. It never reports "no results" when it was turned away.

**And when a keyword genuinely has no matches?**
The run succeeds and says so, with Amazon's own result count of 0 as evidence.
Amazon fills that page with a few unrelated "you might also like" cards; those
are not shipped as results for your keyword.

**Which Amazon sites?**
amazon.com only, for now. Amazon prices search results for the visitor's
delivery country, and from the routes this actor uses the European and UK sites
answer with most prices missing or converted into dollars. Rather than sell
half-empty rows, those sites are left out.

**Why is a price sometimes empty?**
That card shows no offer on the results page (variants to pick, "See options").
The row is still a real result with its rank. If you only want priced results,
set a price range.

**Is this legal?**
It reads pages Amazon shows to anyone without logging in, and collects no
personal data. Check the terms that apply to your own use.

***

Amazon search scraper, Amazon search results scraper, Amazon keyword rank
tracker, Amazon SERP scraper, Amazon organic rank, Amazon sponsored products
tracker, Amazon product search API alternative, Amazon best seller badge,
Amazon bought in past month, Amazon price scraper, ASIN finder by keyword.

# Changelog

This Actor's version history is a separate document: https://apify.com/tagadanar/amazon-search-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

One keyword per line, exactly what you would type into Amazon's search box, e.g. <code>wireless mouse</code>. Each keyword is its own search, and every row says which keyword found it and at what rank.

## `searchUrls` (type: `array`):

Search result pages copied from your browser, e.g. <code>https://www.amazon.com/s?k=usb+c+hub\&rh=n%3A172282</code>. The link keeps every filter, department and sort you picked on Amazon, and its own Amazon site. Product pages (<code>/dp/…</code>) are not search pages and are skipped.

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

Which Amazon site the keywords are searched on. Search links keep their own site.

## `sort` (type: `string`):

Amazon's own sort order for keyword searches. Search links keep the sort they carry.

## `maxResultsPerSearch` (type: `integer`):

Stop each keyword or link after this many results. You pay per result delivered, never per page read.

## `maxPagesPerSearch` (type: `integer`):

How deep to page through each search. Amazon itself stops at page 20 however many results it advertises, so 20 is the maximum, and the run stops at the last page Amazon actually offers.

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

Only keep results priced at or above this, in US dollars. Sent to Amazon as its own price filter and checked again on every row; results with no price on the card are left out when a price range is set.

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

Only keep results priced at or below this, in US dollars. Leave empty for no limit.

## `minRating` (type: `string`):

Only keep results rated at least this many stars. Unrated results are left out when this is set.

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

Only keep results that show the Prime badge.

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

Sponsored (ad) slots are delivered and flagged <code>sponsored: true</code>. Turn this off to keep organic results only. Either way each row carries its organic rank.

## Actor input object example

```json
{
  "keywords": [
    "wireless mouse"
  ],
  "marketplace": "com",
  "sort": "relevance",
  "maxResultsPerSearch": 20,
  "maxPagesPerSearch": 20,
  "primeOnly": false,
  "includeSponsored": true
}
```

# Actor output Schema

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

One row per search result in the default dataset.

# 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 = {
    "keywords": [
        "wireless mouse"
    ],
    "maxResultsPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/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 = {
    "keywords": ["wireless mouse"],
    "maxResultsPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/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 '{
  "keywords": [
    "wireless mouse"
  ],
  "maxResultsPerSearch": 20
}' |
apify call tagadanar/amazon-search-scraper --silent --output-dataset

```

## MCP server setup

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