# Amazon Product Scraper - Search, Bestsellers & Detail (`atlasdataworks/amazon-unified-extractor`) Actor

Amazon search, bestsellers and product detail in one actor and one normalized schema. Residential by default for 100% price completeness. Pay-per-event.

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

## Pricing

from $3.00 / 1,000 product scrapeds

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 — Search, Bestsellers & Product Detail in one actor

Scrape **Amazon search results, bestseller rankings and full product detail pages** from a single
actor, into **one normalized schema**. Built for price monitoring, catalogue building, competitive
research, and AI agents.

Most Amazon actors give you one surface and their own field names. This one returns identical
records whether a product came from a keyword search, a bestsellers grid, or its own detail page —
so your pipeline handles exactly one shape.

### Why this actor

- **100% price completeness, and we measure it.** Every run reports `priceCompleteness` in its
  output. The most common complaint about Amazon scrapers is prices going missing depending on
  proxy location or delivery country. This actor uses a residential tier **by default** and treats
  anything under 95% as a defect, not an acceptable outcome.
- **Three surfaces, one schema.** Search, bestsellers and detail all produce the same record.
- **Deduplicated across surfaces — and billed once.** A product found in search, in a bestsellers
  grid *and* on its detail page is returned **once**, with every sighting listed in `sources[]`.
  You are not charged three times for one product.
- **Sponsored results are excluded by default** and always flagged `sponsored: true` when you
  include them. Ads are never silently mixed into organic results.
- **Prices are parsed, not scraped as strings.** `{ amount, currency, raw }`, with the currency
  recorded as published and no FX guessing. A price that cannot be read is `null` — never a guess.

### Output

```json
{
  "asin": "B0GJTFXNRX",
  "title": "Apple AirTag (2nd Generation): Tracker for Keychain, Wallet, and More",
  "url": "https://www.amazon.com/dp/B0GJTFXNRX",
  "surface": "bestsellers",
  "brand": "Apple",
  "price": { "amount": 24.0, "currency": "USD", "raw": "$24.00" },
  "listPrice": { "amount": 29.0, "currency": "USD", "raw": "List: $29.00" },
  "discountPct": 17,
  "rating": 4.5,
  "reviewCount": 9464,
  "bestsellerRank": 2,
  "category": "electronics",
  "sponsored": false,
  "availability": "In Stock",
  "features": ["..."],
  "sources": [{ "surface": "bestsellers", "url": "https://www.amazon.com/dp/B0GJTFXNRX" }]
}
```

The run also writes a **summary** to the key-value store under `OUTPUT`, including
`priceCompleteness`, `degradedSources` and `creditsSpent`. Check `degradedSources` to tell a
genuinely empty result apart from a source that failed.

### Input

| Field | What it does |
|---|---|
| `searchQueries` | Keywords to search. Amazon caps keyword search at ~7 pages. |
| `bestsellerCategories` | Category slugs, e.g. `electronics`. Returns ranked tiles. |
| `asins` | Specific ASINs to fetch detail pages for. |
| `scrapeProductDetails` | Enrich every result with its detail page (premium event). |
| `includeSponsored` | Include ad placements, always flagged. Default off. |
| `domain` | `www.amazon.com`, `www.amazon.co.uk`, `www.amazon.de`, … |
| `cheapMode` | Cheaper proxy tier. **Lowers price completeness to ~84%.** Default off. |
| `scrapeDoToken` | Optional. Leave empty — access is included. Only for users who prefer their own scrape.do account. |

### Pricing (pay-per-event)

| Event | Fires | Price |
|---|---|---|
| `product-scraped` | per unique product delivered, after deduplication | **$0.003** ($3.00 / 1,000 products) |
| `product-detail` | per product enriched with a full detail page | **$0.005** ($5.00 / 1,000 details) |
| `Actor Start` | once per run, charged by the platform | $0.00005 ($0.05 / 1,000 runs) |
| `Result` | per record stored, charged by the platform | small, set by the platform |

`product-detail` is charged **in addition to** `product-scraped`, not instead of it, and only over
records actually delivered. You pay for delivered records, not runtime. Runs respect
`maxTotalChargeUsd`: when the cap is reached the actor stops delivering, reports how much of the
result set was delivered, and never charges past it.

Platform usage — compute and network — is bundled. There is no separate usage line on your bill.

### Using it from an AI agent (MCP)

The actor is callable as an MCP tool via Apify's MCP server. Example prompts:

> "Get the top 50 laptops on Amazon under $600 with their ratings and review counts."

> "What are the current top 20 bestsellers in electronics, with rank and price?"

> "Fetch full detail for ASIN B0GJTFXNRX including feature bullets and availability."

Every field is documented in the output schema, so an agent can plan against it without scraping
the README.

### Honest limits

- **Customer reviews are not available.** Amazon's `/product-reviews/` pages require a signed-in
  session, so this actor returns the **rating and review count** from public pages but not review
  text. Any actor offering full review text is doing something this one deliberately does not.
- **Amazon caps keyword search at roughly 7 pages.** Use bestseller categories or more specific
  keywords for deeper coverage.
- Bestseller tiles sometimes omit prices. Those rows are excluded from the `priceCompleteness`
  metric rather than being allowed to dilute it.
- Availability and delivery text vary by marketplace and region.

# Actor input Schema

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

Keywords to search on Amazon, e.g. "laptop". Amazon caps keyword search at about 7 pages.

## `bestsellerCategories` (type: `array`):

Bestseller category slugs, e.g. "electronics" or "electronics/172282". Returns ranked tiles; some tiles legitimately have no price, so bestsellers are excluded from the price-completeness metric.

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

Specific ASINs to fetch product-detail pages for. Detail pages are the only source of brand, availability and feature bullets, and are charged as the premium product-detail event.

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

Enriches every search/bestseller result with its detail page. Costs one extra request per product and charges the premium product-detail event per delivered record. Off by default.

## `maxItemsPerQuery` (type: `integer`):

Upper bound on products returned per search keyword or bestseller category.

## `maxPagesPerQuery` (type: `integer`):

Amazon restricts keyword search to roughly 7 pages; values above 7 are clamped.

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

Sponsored results are excluded by default and always flagged with sponsored=true when included, so ads are never silently mixed into organic results.

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

Marketplace host, e.g. www.amazon.com, www.amazon.co.uk, www.amazon.de.

## `cheapMode` (type: `boolean`):

Uses a cheaper proxy tier. Measured at about 84% price completeness versus 100% on the default residential tier - you are trading away this actor's main guarantee. Off by default.

## `scrapeDoToken` (type: `string`):

Leave this empty. The actor ships with its own access and needs nothing from you. Only set it if you have your own scrape.do account and would rather the requests ran on it.

## `maxTotalChargeUsd` (type: `integer`):

When the cap is reached the run stops delivering, reports how much of the result set was delivered, and never charges past it.

## Actor input object example

```json
{
  "searchQueries": [
    "laptop"
  ],
  "scrapeProductDetails": false,
  "maxItemsPerQuery": 100,
  "maxPagesPerQuery": 5,
  "includeSponsored": false,
  "domain": "www.amazon.com",
  "cheapMode": false
}
```

# Actor output Schema

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

One record per unique ASIN across every surface requested. A product seen in search, in a bestsellers grid and on its own detail page is returned ONCE, with each sighting listed in sources\[] - and billed once. Prices are parsed into {amount, currency, raw} with the currency recorded as published; a price that could not be read is null rather than guessed.

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

Per-run counts and health: priceCompleteness (the share of rows that carry a real price - this actor's core guarantee, floor 95% on residential), pricedRecords, rawCount, uniqueCount, mergedCount, deliveredCount, detailCount, creditsSpent, degradedSources and chargeLimitReached. Check degradedSources to tell a genuinely empty result from a source that failed, and priceCompleteness to verify the guarantee held on your run.

# 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": [
        "laptop"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("atlasdataworks/amazon-unified-extractor").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": ["laptop"] }

# Run the Actor and wait for it to finish
run = client.actor("atlasdataworks/amazon-unified-extractor").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": [
    "laptop"
  ]
}' |
apify call atlasdataworks/amazon-unified-extractor --silent --output-dataset

```

## MCP server setup

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

```

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/UtiCnIIHcPxbgeUab/builds/y602mfRWYUtN3Oiat/openapi.json
