Arcadium Data Scrapers
Home / Guides / Amazon Product & Best Sellers Scraper

How to use Amazon Product & Best Sellers Scraper

Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.

$0.54 per 1,000 search results (live Apify price on 2026-11-01).

1. In the Apify Store (no code)

  1. Open arcadium/amazon-products and sign in to Apify (a free account works).
  2. Fill in the input form. The fields below are the ones the example uses.
  3. Set a maximum cost per run in the run options if you want a hard cap.
  4. Start the run. Rows appear in the Output tab as they arrive.
  5. Export the dataset as JSON, CSV or Excel, or connect an integration.
Input fieldTypeDescription
searchesarrayKeywords to search on the chosen store, e.g. ["wireless earbuds", "usb c cable"]. Each term gives up to maxResultsPerSearch result rows in Amazon's order: position, sponsored flag, ASIN, title, price, list price, rating, rating count, badges, bought in past month. Also read from keywords, searchQueries, searchQuery or queries (other Amazon actors' names).
categoriesarrayCategory paths as in the store's Best Sellers URLs, e.g. ["electronics", "electronics/172541", "kitchen"] (amazon.de: "ce-de"). Each category gives one ranked list per listTypes entry, up to maxResultsPerList ranks. A Best Sellers URL works here too.
asinsarrayProduct ids, e.g. ["B0DCH8VDXF", "B08JHCVHTY"]. Each gives one product row: title, image, rating, star split, rating count, Buy Box price and seller, list price, ships from, delivery promise, and the other offers (condition, price, seller).
urlsarrayAny mix of search URLs (https://www.amazon.com/s?k=yoga+mat, filters kept), Best Sellers / New Releases / Movers & Shakers URLs (https://www.amazon.de/gp/bestsellers/kitchen) and product URLs (https://www.amazon.co.uk/dp/B0DCH8VDXF). Each URL is read on its own store.
marketplacestringStore for searches, categories and ASINs (URLs use their own store). Prices, sellers and delivery are those a shopper in that country sees: non-US stores are read from an IP in their country. Example: DE. Lowercase codes (us, uk, de) and the names country, countryCode, amazonDomain or website are accepted too.
maxResultsPerSearchintegerResult rows per search term or search URL, 1 to 1,000 (default 48). Amazon shows 16-60 cards per page; the actor reads as many pages as needed. Sponsored cards count unless includeSponsored is off. Also read from maxResultsPerKeyword or maxResultsPerQuery.
includeSponsoredbooleanKeeps sponsored (ad) cards in search results, flagged with sponsored: true. Turn off to get organic results only; skipped ads are free. Default: true. excludeSponsored: true (another actor's name) means the same as false here.

Example input:

{
  "searches": [
    "wireless earbuds"
  ],
  "categories": [],
  "asins": [],
  "urls": [],
  "marketplace": "US",
  "maxResultsPerSearch": 20,
  "includeSponsored": true
}

2. Over the Apify API

The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).

curl -X POST "https://api.apify.com/v2/acts/arcadium~amazon-products/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searches":["wireless earbuds"],"categories":[],"asins":[],"urls":[],"marketplace":"US","maxResultsPerSearch":20,"includeSponsored":true}'

3. From JavaScript

// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/amazon-products').call({
  "searches": [
    "wireless earbuds"
  ],
  "categories": [],
  "asins": [],
  "urls": [],
  "marketplace": "US",
  "maxResultsPerSearch": 20,
  "includeSponsored": true
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

4. From Python

# pip install apify-client
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/amazon-products").call(run_input={
    "searches": ["wireless earbuds"],
    "categories": [],
    "asins": [],
    "urls": [],
    "marketplace": "US",
    "maxResultsPerSearch": 20,
    "includeSponsored": True,
})
items = client.dataset(run.default_dataset_id).list_items().items  # apify-client 3.x returns a Run object
print(items)

5. In n8n

Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.

{
  "nodes": [
    {
      "name": "Run arcadium/amazon-products",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        0,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/arcadium~amazon-products/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\"searches\":[\"wireless earbuds\"],\"categories\":[],\"asins\":[],\"urls\":[],\"marketplace\":\"US\",\"maxResultsPerSearch\":20,\"includeSponsored\":true}",
        "options": {
          "timeout": 300000
        }
      }
    }
  ],
  "connections": {}
}

6. From an AI assistant (MCP)

Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=arcadium/amazon-products",
      "headers": {
        "Authorization": "Bearer <APIFY_TOKEN>"
      }
    }
  }
}

More on the MCP page.

7. From LangChain

# pip install langchain-apify   (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("arcadium/amazon-products")
rows = tool.invoke({"run_input": {
    "searches": ["wireless earbuds"],
    "categories": [],
    "asins": [],
    "urls": [],
    "marketplace": "US",
    "maxResultsPerSearch": 20,
    "includeSponsored": True,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])

Sample output

One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.

{
  "rowType": "searchResult",
  "marketplace": "US",
  "domain": "amazon.com",
  "currency": "USD",
  "searchTerm": "wireless earbuds",
  "page": 1,
  "position": 2,
  "organicPosition": null,
  "asin": "B0C1BTXM9W",
  "sponsored": true,
  "title": "Wireless Earbuds, Bluetooth 5.4 Ear Buds LED Power Display Headphones Bass Stereo ...",
  "url": "https://www.amazon.com/dp/B0C1BTXM9W",
  "imageUrl": "https://m.media-amazon.com/images/I/614gb9uXQuL.jpg",
  "price": 19.99,
  "priceText": "$19.99",
  "listPrice": 28.49,
  "listPriceText": "$28.49",
  "rating": 4.3,
  "ratingCount": 14589,
  "badges": [],
  "boughtPastMonth": 6000,
  "boughtPastMonthText": "6K+ bought in past month",
  "deliveryText": "Join Prime to get FREE delivery Tomorrow, Oct 23",
  "scrapedAt": "2026-10-22T08:00:00.000Z"
}
FieldWhat it holds
rowTypeKind of row. Filter on this first. 'searchResult': one search result card (charged as search-result). 'bestseller': one entry of a Best Sellers, New Releases, Movers & Shakers, Most Wished For or Gift Ideas list (charged as bestseller). 'product': one light product row with Buy Box and offers (charged as product). 'error': an input that gave no data; see code and message (free).
marketplaceCountry code of the Amazon store, e.g. US, DE, JP.
domainStore domain, e.g. amazon.de.
currencyCurrency of every price on the row, e.g. USD, EUR, JPY.
asinAmazon product id (10 letters and digits), e.g. B0DCH8VDXF.
urlCanonical product link https://www.amazon.<store>/dp/<ASIN>.
titleProduct title as the store shows it. Null on rank-only list entries (detailsComplete false).
imageUrlMain product image, full size.
priceSearch and list rows: price shown on the card, as a number in the store's currency (e.g. 19.99). Null when the card shows no price (unavailable, variants only).
priceTextPrice exactly as shown, e.g. '$19.99', '€27,99', '¥8,990'.
listPriceSearch rows: struck-through list or typical price, when shown. Product rows: the Buy Box offer's reference price ('List Price', 'Was', 'RRP').
listPriceTextReference price exactly as shown.
ratingAverage star rating, 0 to 5, e.g. 4.5. Null when the product has no ratings.
ratingCountNumber of ratings (global ratings on product rows).
searchTermSearch rows: the search term (or the URL's keyword) the card came from.
pageSearch rows: results page of the card (1-based).
positionSearch rows: 1-based position over all pages, sponsored cards included (the order a shopper sees).
organicPositionSearch rows: 1-based position among non-sponsored results; null for sponsored cards.
sponsoredSearch rows: true for sponsored (ad) cards.
badgesSearch rows: badges on the card, e.g. 'Best Seller', "Amazon's Choice", 'Overall Pick', 'Limited time deal'.
boughtPastMonthSearch rows: lower bound from 'bought in past month' (e.g. 1000 for '1K+'). Null when not shown.
boughtPastMonthTextSearch rows: the 'bought in past month' text as shown.
deliveryTextSearch rows: first delivery line, e.g. 'FREE delivery Mon, Oct 26'.
listTypeList rows: bestsellers, new-releases, movers-and-shakers, most-wished-for or most-gifted.
categoryList rows: category path as in the list URL, e.g. 'electronics/172541'; empty for the all-departments list.
categoryNameList rows: category name as shown, e.g. 'Electronics'.
listTitleList rows: page heading, e.g. 'Best Sellers in Electronics'.
rankList rows: rank in the list (1 = top).
rankChangePercentMovers & Shakers rows: sales-rank gain over the past 24 hours in percent (e.g. 1250). Null on other lists.
salesRankMovers & Shakers rows: sales rank now. Null on other lists.
salesRankYesterdayMovers & Shakers rows: sales rank 24 hours ago. Null on other lists.
detailsCompleteList rows: false when Amazon gave only the ASIN and rank for the entry (title, price and rating null).
starPercentProduct rows: share of ratings per star in percent, e.g. {"5": 73, "4": 12, "3": 8, "2": 2, "1": 5}. Null without ratings.
hasBuyBoxProduct rows: true when Amazon shows a featured offer (Buy Box). False for 'No featured offers available'.
buyBoxPriceProduct rows: price of the featured (Buy Box) offer, as a number.
buyBoxPriceTextProduct rows: Buy Box price exactly as shown.
listPriceLabelProduct rows: label of the reference price, e.g. 'List Price:', 'Was:', 'RRP:'.
buyBoxConditionProduct rows: condition of the featured offer, e.g. 'New', 'Used - Like New'.
buyBoxSellerProduct rows: business name of the Buy Box seller, e.g. 'Amazon.com' or a merchant name.
buyBoxSellerIdProduct rows: Amazon merchant id of the Buy Box seller (e.g. A3US3KTV1R02M4); null when Amazon sells it.
buyBoxShipsFromProduct rows: who ships the Buy Box offer, e.g. 'Amazon.com'.
buyBoxFulfilledByAmazonProduct rows: true when Amazon ships the Buy Box offer (FBA or Amazon itself).
buyBoxDeliveryProduct rows: delivery promise of the Buy Box offer, e.g. 'FREE delivery Tuesday, October 27'.
otherOfferCountProduct rows: number of other offers Amazon lists besides the Buy Box.
offersProduct rows: other offers (up to maxOffers), each with condition, price, priceText, listPrice, soldBy (business name), sellerId, shipsFrom, fulfilledByAmazon, sellerRating, sellerRatingCount, sellerPositiveText, deliveryText, conditionNote.
sourceProduct rows: the ASIN, URL, search term or list the product came from.
scrapedAtWhen the row was read, ISO 8601 UTC.
inputError rows: the search term, category, ASIN or URL that gave no data.
codeError rows: not_found, no_match, invalid_input, blocked or unavailable.
messageError rows: what happened, in plain words.
platformError rows: always 'amazon'.

Tutorials

Schedule it

In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.