# Amazon Product Search Scraper — Prices, Ratings, Sponsored (`marknetic/amazon-products`) Actor

Scrape Amazon search results: price, list price, rating, exact rating count, image and a sponsored-or-organic flag for every product. No login. Pay per product returned, with no start fee and nothing for failed pages.

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

## Pricing

from $1.40 / 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.
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 Search Scraper — Prices, Ratings & Sponsored Flag

Turn any Amazon search into a clean product table: title, price, list price, star rating, exact rating count, image and link. Each product is marked **sponsored or organic**, and you can export as JSON, CSV or Excel.

Type the search terms you care about, choose how many products you want, and run. There's no Amazon account, API key or browser setup.

Built for price monitoring, competitor and catalog research, product discovery, and tracking how paid placement crowds a search over time.

***

### Three guarantees

**1. You pay per product returned. Nothing else.**

There's no fee to start a run, and nothing for a page that fails or a run that finds nothing. Each product is charged once, even when Amazon repeats it across pages. Set a maximum cost and the run stops exactly there. It never delivers products it can't charge for, and it never charges for products it didn't deliver.

**2. Every value is what Amazon shows, or it's `null` with a reason.**

- **Prices** come exactly as written ("$29.95"), so the currency is never lost. The struck-through "was" price has its own field and never stands in for the real price.
- **Rating counts are exact.** Amazon shows a rounded count like "(41.3K)" next to the stars; this actor reads the exact figure Amazon publishes alongside it: **41,298**.
- **No missing field is left unexplained.** When a field is empty, a `_provenance` block on every row says why: the product simply has none (`absent`), or the value was on the page but couldn't be read (`unparseable`).

**3. Nothing is dropped silently.**

Every search term and page is accounted for in the run summary. Pages Amazon refused are listed with the reason. Records that fail validation are counted, never passed through half-empty.

***

### What you get

One row per distinct product (ASIN):

| Field | Example |
|---|---|
| `asin` | `B0BQPNMXQV` |
| `title` | `JBL Vibe Beam - True Wireless Earbuds - Black` |
| `price_display` | `$29.95`, the price you'd pay, as shown |
| `list_price_display` | `$49.95`, the "was" price, only on discounted items |
| `rating` | `4.2` |
| `rating_count` | `41298`, exact, not rounded |
| `sponsored` | `true` for a paid placement, `false` for organic, `null` if Amazon doesn't say |
| `url`, `image_url` | product page and main image |
| `source_url` | the search page the product came from |
| `_provenance` | where each value came from, or why it's `null` |

#### Real sample output

From a run on the Apify platform (product URL shortened, `_provenance` excerpted):

```json
{
  "asin": "B0BQPNMXQV",
  "title": "JBL Vibe Beam - True Wireless Earbuds - Black",
  "url": "https://www.amazon.com/JBL-Vibe-Beam-Wireless-Headphones/dp/B0BQPNMXQV",
  "image_url": "https://m.media-amazon.com/images/I/41+1Csr1pSL._AC_UY218_.jpg",
  "price_display": "$29.95",
  "list_price_display": "$49.95",
  "rating": 4.2,
  "rating_count": 41298,
  "sponsored": false,
  "source_url": "https://www.amazon.com/s?k=wireless+earbuds",
  "_provenance": {
    "price_display": { "source": "dom", "key": "span.a-price span.a-offscreen", "reason": null, "conflict": null },
    "rating_count":  { "source": "dom", "key": "[aria-label] \"N ratings\"",     "reason": null, "conflict": null },
    "sponsored":     { "source": "dom", "key": "href /sspa/click",               "reason": null, "conflict": null }
  }
}
```

#### A sponsored flag you can trust

Amazon doesn't label paid placement the same way on every page. Where the page states it, this actor reads that. Otherwise it reads where the product's own link goes: paid placements route through Amazon's sponsored-click tracker, organic ones go straight to the product. When neither tells, the field is `null` ("undetermined"), never a guess of "organic".

The word "Sponsored" in the page alone is never trusted, because it also appears in style names and on banner ads beside the results.

***

### Speed

Measured on the Apify platform, not estimated:

| | |
|---|---|
| **200 products** from two searches | **28 seconds** |
| **1,000 products** from five searches | **under 5 minutes** |
| **12,000 products** from 60 searches | **10–30 minutes**, typically about 14 |

No browser is launched; each search page returns up to about 50 products, and pages are fetched in parallel. Measured with default settings, except the 12,000-product runs (concurrency 3).

In a 24-hour test of 15 full-size runs (12,000 products each, spread across day and night), **98% of search pages were delivered**.

***

### Input

| Field | Description |
|---|---|
| **Search terms** | One or more Amazon searches, e.g. `wireless earbuds`, `standing desk`. |
| **Maximum results** | Stop after this many **distinct** products, which is also exactly what you're charged for. Defaults to 500. |
| **Concurrency** | Requests at once, 1–3. Defaults to 2. Faster isn't better on Amazon: higher settings return less. |

```json
{
  "queries": ["wireless earbuds", "standing desk"],
  "maxResults": 1000
}
```

***

### Pricing

**$2.00 per 1,000 products**, charged as products are delivered. Nothing on start and nothing for failures; your Apify plan's discount applies automatically.

A 100-product check costs at most **$0.20**, and 1,000 products cost **$2.00**. The maximum cost you set for a run is respected exactly: the run checks it before fetching anything and stops there.

***

### Typical uses

- **Price monitoring:** track asking and "was" prices for a set of searches on a schedule.
- **Competitor research:** see who ranks for your keywords, at what price and rating.
- **Paid-placement tracking:** measure how much of a search is sponsored, and by whom.
- **Product discovery:** find well-rated products in a category by exact rating count.

***

### Good to know

- **Amazon.com (US) search results only.** Requests come from US addresses, so prices are in USD as a US shopper sees them. Product detail pages, reviews and sellers are not included.
- **Amazon decides how deep a search goes.** It lists up to about 20 pages per search, sometimes far fewer, and the number can vary between requests. A run can therefore return fewer products than you asked for, with no failures. You're only charged for what's returned.
- **Amazon occasionally blocks for a while.** The 24-hour test hit one block episode on Amazon's side, lasting about an hour and a half; runs during it delivered less. When most recent pages fail, the run stops early instead of retrying a blocked source, and keeps and charges only what it already delivered. Running again later usually works.
- **Responsible use:** you're responsible for using the results lawfully and in line with Amazon's terms.

# Actor input Schema

## `queries` (type: `array`):

One or more Amazon search terms. Each term is fetched as an Amazon search page and paginated as far as your maximum results allows.

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

Stop after this many unique products. Products repeat across pages, so this counts distinct ASINs, which is also exactly what you are charged for.

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

How many requests to run at once, 1 to 3. Amazon throttles sustained crawling, and measured on live runs, going faster returns less: at 5 the success rate fell to 26% and the run peaked at 95% of its memory. The run clamps this to what its memory allows.

## Actor input object example

```json
{
  "queries": [
    "wireless earbuds",
    "standing desk"
  ],
  "maxResults": 100,
  "concurrency": 2
}
```

# Actor output Schema

## `products` (type: `string`):

One row per product, with the Overview view selected by default. Switch to All fields to see the \_provenance block.

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

Products requested and returned, failures by class, and what the run was charged.

# 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 = {
    "queries": [
        "wireless earbuds",
        "standing desk"
    ],
    "maxResults": 100,
    "concurrency": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("marknetic/amazon-products").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 = {
    "queries": [
        "wireless earbuds",
        "standing desk",
    ],
    "maxResults": 100,
    "concurrency": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("marknetic/amazon-products").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 '{
  "queries": [
    "wireless earbuds",
    "standing desk"
  ],
  "maxResults": 100,
  "concurrency": 2
}' |
apify call marknetic/amazon-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,marknetic/amazon-products"
        }
    }
}
```

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/pfDe9GAWxbXzFfB8v/builds/379sOzPFsisPJvg9u/openapi.json
