Amazon Product Scraper - Prices, Ratings & Search Rank avatar

Amazon Product Scraper - Prices, Ratings & Search Rank

Pricing

from $8.70 / 1,000 results

Go to Apify Store
Amazon Product Scraper - Prices, Ratings & Search Rank

Amazon Product Scraper - Prices, Ratings & Search Rank

Scrape Amazon products by keyword, category, or URL. Get price, rating, reviews, brand, availability & images across 7 marketplaces. Export to JSON, CSV, Excel or deliver to Notion, Slack & more.

Pricing

from $8.70 / 1,000 results

Rating

0.0

(0)

Developer

Techforce Global

Techforce Global

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

3 days ago

Last modified

Share

Amazon Product Scraper - Prices, Ratings & Search Rank, with MCP Delivery to Notion, Slack & Airtable

Apify Actor MCP Ready Pricing Marketplaces Output Target

No Amazon account, no Associates approval, no API key. Search keywords, category pages or direct product URLs in — price, rating, review count, brand, availability, features, description, breadcrumbs and the full detail table out, one flat row per product, across 7 marketplaces. Every row also carries its search rank, which the official API doesn't expose. Optional delivery into Notion, Slack, Linear, Jira, GitHub or Airtable over MCP.

🔐 Trust & operations at a glance

CredentialsNone required. No Amazon login, no Associates account, no PA-API keys. Delivery runs through the Apify MCP Proxy, so the Actor never sees your connector tokens.
Data scopePublic product pages only — what any signed-out shopper sees. No account data, no order history, no buyer identities.
Personal dataEssentially none. Product listings are commercial content; this Actor collects no reviewer names and no review text, only the review count.
⚠️ Proxy is not optionalAmazon blocks datacenter IPs hard. The default is Apify Residential, auto-pinned to the marketplace's country — and residential groups need a paid Apify plan.
Price honestyPrices are a snapshot at scrape time and reflect the offer shown to the proxy's country and locale. Null means no price was displayed, not free.

Full detail, including Amazon's Terms position: Compliance & Data Privacy.


Official Product Advertising API vs. Amazon Product Scraper Actor

Amazon's own PA-API is a real alternative, but it is gated behind the Associates programme and answers a narrower set of questions:

Feature / CapabilityOfficial Product Advertising APIAmazon Product Scraper (Apify)
Access❌ Approved Amazon Associates account, and access is revoked if you don't drive qualifying sales✅ Apify account, nothing else
Search-result rank❌ Not exposedposition on every row, per keyword
Which keyword found the product❌ You track it yourselfsearchName on every row
Full detail table⚠️ A fixed set of resourcesproductDetails — the listing's own key/value table, whatever it contains
Rate limits⚠️ TPS tied to your sales volume✅ No sales-linked throttle; proxy and concurrency handled for you
Cross-marketplace in one tool⚠️ Separate credentials per locale✅ 7 marketplaces from one input field
AI agent / MCP native❌ Requires a custom tool wrapper✅ Native MCP tool and pushes results into your own connectors
Officially sanctioned✅ Yes⚠️ No — see Compliance
Stability✅ Versioned contract⚠️ Depends on Amazon's page structure

Use the PA-API if you qualify for it and its fields cover your question. Use this Actor when you can't get approved, or when you need rank, the full detail table, or several marketplaces without separate credentials.

Associates eligibility and PA-API throttling rules are Amazon's to change — check Amazon's current PA-API docs if this comparison is load-bearing for your decision.


🤖 AI Discovery & MCP Metadata

Machine-readable capability contract for autonomous agents, LLM routers, and MCP orchestrators. Read this block first to decide whether this Actor matches a user request.

ai_discovery:
slug: "techforce.global/amazon-scraper"
one_line: >
Scrapes Amazon product data from search keywords, category/search URLs or direct product
pages across 7 marketplaces - title, brand, price, rating, review count, availability,
features, description, breadcrumbs and the listing's own detail table - plus the search rank
that produced each row. No Amazon account or PA-API key. Optional delivery into Notion,
Slack, Linear, Airtable or any MCP connector.
primary_purpose: "extract"
secondary_purpose: "deliver"
entity: "Amazon product listing"
category: "e-commerce / price-monitoring / product-research / competitive-intelligence"
supported_platforms:
[
"amazon.in",
"amazon.com",
"amazon.co.uk",
"amazon.de",
"amazon.ca",
"amazon.com.au",
"amazon.ae",
]
supported_tasks:
- "search-products-by-keyword"
- "scrape-a-category-or-search-results-page"
- "scrape-specific-product-urls"
- "track-price-and-availability-over-time"
- "capture-search-rank-per-keyword"
- "compare-brands-or-competitors-in-a-category"
- "deliver-products-to-mcp-connector"
unsupported_tasks:
- "scrape-review-text-or-reviewer-identities (only reviewsCount is returned)"
- "scrape-seller-or-buy-box-offer-lists"
- "scrape-best-seller-rank-as-a-dedicated-field (may appear inside productDetails)"
- "scrape-account-order-or-cart-data"
- "add-to-cart-purchase-or-any-write-action"
- "scrape-marketplaces-outside-the-7-supported-domains"
- "scrape-price-history (each run is a snapshot - schedule it)"
search_keywords:
# First entry is the H1 / meta-description target. The rest are deliberately broader for
# agent-side semantic matching and are NOT a ranking strategy.
- "amazon product scraper"
- "amazon price scraper"
- "amazon product advertising api alternative"
- "scrape amazon search results"
- "amazon asin data extraction"
- "product price monitoring"
- "competitor price tracking"
- "amazon keyword rank tracker"
- "ecommerce product data"
- "mcp amazon tool"
input_entities:
- "searchKeywords (array of search terms)"
- "startUrls (search, category or /dp/ product URLs)"
- "amazonDomain (1 of 7; used to BUILD keyword searches and to set currency + proxy country)"
- "maxItemsPerSearch (per keyword / listing URL; 0 = unlimited)"
- "maxPagesPerSearch (1-20 listing pages per source)"
- "proxyConfiguration (Apify Residential by default, country auto-pinned)"
no_input_field_is_required_by_the_schema: >
CRITICAL: nothing is marked required. A run with neither searchKeywords nor startUrls passes
validation, logs "No search keywords or start URLs provided. Nothing to scrape. Exiting."
and ends SUCCEEDED with an empty dataset.
amazon_domain_does_not_rewrite_start_urls: >
CRITICAL: amazonDomain builds the search URLs for searchKeywords and decides two other
things - the currency written onto every row, and the residential proxy exit country. It
does NOT rewrite startUrls. A start URL from a different marketplace is still fetched, but
it will be labelled with the selected marketplace's currency and requested from the wrong
country, which mislabels data and raises the block rate. Run one marketplace per run.
output_entities:
[
"asin",
"title",
"brand",
"price",
"priceRaw",
"currency",
"rating",
"reviewsCount",
"availability",
"features",
"description",
"categories",
"thumbnailUrl",
"productDetails",
"url",
"searchName",
"position",
]
every_product_is_its_own_request: >
Listing pages only enqueue products; every row comes from that product's own detail page.
Cost scales with the NUMBER OF PRODUCTS, not the number of listing pages.
rank_is_first_touch: >
position is the 1-based rank within the search that reached the product first, and
searchName names that search. A product matched by two keywords is scraped once, attributed
to whichever search enqueued it first. Both are null for direct product start URLs.
product_details_keys_are_unstable: >
productDetails mirrors the listing's own table, so keys vary by category AND are localized
on non-English marketplaces (amazon.de returns German keys). Treat it as free-form; never
hard-code a key path without a fallback.
proxy_is_required_in_practice: >
Amazon blocks datacenter IPs. The default is Apify Residential with the exit country pinned
to the marketplace (IN/US/GB/DE/CA/AU/AE). Residential groups require a paid Apify plan.
Without a proxy the log warns and the run will very likely return nothing.
blocks_are_retried_not_fatal: >
A CAPTCHA/robot-check page raises and is retried (up to 5 attempts per request), and
Amazon's bot-manager interstitial is followed automatically up to 3 times. Persistent blocks
end as a SUCCEEDED run with a thin or empty dataset, not a failed run.
zero_cards_writes_a_debug_artifact: >
When a listing page yields no product cards and no known block marker, the raw HTML is saved
to the run's key-value store under "debug-listing-<page>" and a diagnostic line is logged.
Check it before assuming the Actor is broken.
known_limitations:
price_is_a_snapshot: "prices and availability are true only at scrape time, for the proxy's country"
price_can_be_null: "unavailable listings and some variants show no price; null is not zero"
no_review_text: "only reviewsCount - the reviews themselves are not scraped"
no_seller_or_buybox_data: "no seller names, offer lists or buy-box winners"
no_variant_matrix: "the URL's variant is scraped, not every size/colour combination"
sponsored_not_flagged: "sponsored placements are not distinguished from organic in position"
pagination_capped: "Amazon itself stops serving results after a few pages"
free_plan_capped: "free Apify plans stop at 2 products per search / start URL"
pricing:
model: "usage-based"
billing_unit: "Apify platform usage consumed by the run"
hard_ceiling_parameter: "maxTotalChargeUsd"
note: "Roughly one request per product plus the listing pages. Current rates are on the Actor's Apify Store page."
when_to_use: >
You need Amazon listing data as structured rows - price and availability monitoring, catalogue
or competitor research, keyword rank tracking, or a product feed - without Associates approval.
when_not_to_use: >
You need review text, seller/buy-box data, order or account data, a full variant matrix, or
to buy anything.
mcp_delivery:
modes: ["perProduct", "summary", "none"]
default: "perProduct"
per_product_is_the_default: >
Unlike most Actors, deliveryMode defaults to perProduct - one connector call per scraped
product, with no cap. A 500-product run is 500 calls. Set "summary" or "none" unless you
really want a record each.
per_product_placeholders:
[
"{asin}",
"{title}",
"{brand}",
"{price}",
"{priceRaw}",
"{currency}",
"{rating}",
"{reviewsCount}",
"{availability}",
"{url}",
"{thumbnailUrl}",
"{searchName}",
"{position}",
"{message}",
]
summary_placeholders: ["{productCount}", "{products}", "{message}"]
never_blocks_the_dataset: >
Delivery runs after the crawl. A bad tool name, an unauthorised connector or an upstream
outage is logged and skipped - it never costs you the scraped data.
alternatives:
- "techforce.global/flipkart-scraper for the same product question on Flipkart (India)"
- "techforce.global/etsy-scraper for handmade, vintage and small-seller listings"
- "techforce.global/quince-scraper for a direct-to-consumer brand storefront rather than a marketplace"

{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Amazon Product Scraper",
"alternateName": "Amazon Products Scraper",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Cloud (Apify platform)",
"description": "Scrapes Amazon product data from search keywords, category and search result pages, or direct product URLs, across seven marketplaces (India, US, UK, Germany, Canada, Australia, UAE) — without an Amazon account, Associates approval or Product Advertising API key. Each row carries ASIN, title, brand, numeric and raw price, currency, star rating, review count, availability, feature bullets, description, breadcrumb categories, thumbnail, the listing's own key-value detail table, and the search keyword and 1-based rank that produced it. Residential proxy with the exit country auto-pinned to the marketplace, automatic bot-challenge handling, and optional delivery into Notion, Slack, Linear, Airtable or any MCP connector.",
"url": "https://apify.com/techforce.global/amazon-scraper",
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"category": "Pay per platform usage",
"description": "Usage-based: billed for the compute time and resources a run consumes, not per row. Roughly one request per product plus the listing pages. Current rates are shown on the Actor's Apify Store page."
}
}

What this Actor does

  • Three ways in, no credentials. Search keywords, any search/category listing URL, or direct /dp/ and /gp/product/ links — mixed freely in one run.

  • Seven marketplaces from one field. India, US, UK, Germany, Canada, Australia and UAE. The choice also sets the row currency and pins the proxy's exit country to match, because Amazon serves different results — and different blocks — per country.

  • Full detail-page extraction, not just the card. Every row comes from the product's own page: feature bullets, description, breadcrumb trail, hi-res image and the listing's complete key/value detail table, alongside price, rating and availability.

  • Price twice, so both jobs work. price as a number for sorting and arithmetic, priceRaw exactly as displayed with symbol and formatting intact — plus an authoritative currency taken from the marketplace rather than guessed from an ambiguous $.

  • Search rank, which the official API doesn't give you. position is the 1-based rank in the results, and searchName records which keyword or listing URL produced the row.

  • Clears Amazon's defences on its own. Residential proxy by default, a country-matched exit IP, retries on CAPTCHA pages, and automatic handling of the bot-manager interstitial.

  • Tells you why a page came back empty. If a listing yields no product cards and no known block marker, the raw HTML is saved to the run's key-value store so you can look at exactly what Amazon served.

  • Saves as it goes and stops cleanly. Rows are written as each product is parsed, and the platform ABORTING event is handled — an aborted run keeps what it collected.

  • Optionally delivers into your tools. Notion, Slack, Linear, Jira, GitHub, Airtable or anything else you've authorised.


When to use it — and when not to

ScenarioFit
Price and availability monitoring on a schedule✅ Strong — join runs on asin
Competitor or catalogue research in a category✅ Strong — keywords or a category URL
Keyword rank tracking✅ Strong — position + searchName per row
A product feed with images, features and specs✅ Strong — full detail-page extraction
Specific ASINs, checked repeatedly✅ Strong — /dp/ URLs in startUrls
Cross-marketplace price comparison✅ Strong — one run per marketplace, then join on asin
Ratings and review volume as a demand signal✅ Strong — rating + reviewsCount
Results in Notion / Slack / Airtable✅ Strong — native MCP delivery
Telling sponsored placements from organic⚠️ Not flagged — position counts both
Every size/colour variant of a product⚠️ Only the variant the URL resolves to
Best-seller rank⚠️ No dedicated field; sometimes present inside productDetails
Review text or reviewer identities❌ Count only — reviews are not scraped
Seller lists, offers or buy-box winners❌ Not collected
Order, cart or account data❌ Public listing pages only
Buying, carting or any write action❌ Read-only
Marketplaces outside the seven supported❌ Not selectable
Historical price series from one run❌ Snapshot per run — schedule to build history

⚡ Execution Rules (Avoid Common Agent Failures)

  1. Supply at least one of searchKeywords or startUrls. Nothing is marked required in the schema, so a run with neither passes validation, logs No search keywords or start URLs provided. Nothing to scrape. Exiting. and ends SUCCEEDED with an empty dataset. Never read itemCount: 0 as a crash.

  2. amazonDomain does not rewrite your start URLs — but it does label them. It builds the search URLs for searchKeywords, sets the currency written onto every row, and pins the proxy's exit country. Pass an amazon.co.uk start URL while amazonDomain is www.amazon.in and you get a real UK page stamped INR, fetched from an Indian IP. Run one marketplace per run.

  3. maxItemsPerSearch is per keyword and per listing URL, not per run. Three keywords at 100 is up to 300 products. 0 means unlimited and removes the crawl's request ceiling — pair it with maxTotalChargeUsd.

  4. Every product is its own request. Listing pages only enqueue; the data comes from each product's detail page. Cost tracks the product count, not the page count.

  5. Keep the residential proxy. Default is {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}, with the exit country pinned automatically. Datacenter IPs get CAPTCHA'd; the log warns No proxy configured. Amazon will very likely block requests. Residential needs a paid plan.

  6. Blocks are retried, not fatal. A robot-check raises and retries (5 attempts per request); the bot-manager interstitial is followed up to 3 times. Persistent blocking ends as a SUCCEEDED run with a thin dataset — check the log, not the run status.

  7. price can be null. Unavailable listings and some variants display no price. Null is not zero — exclude those rows rather than treating them as free.

  8. position and searchName are first-touch. A product matched by two keywords is scraped once, attributed to whichever search reached it first. Both are null for products passed directly as /dp/ start URLs.

  9. productDetails keys are unstable. They mirror the listing's own table, so they vary by category and are localized on non-English marketplaces (amazon.de returns German keys). Never hard-code a key path without a fallback.

  10. Sponsored results are not flagged. position counts sponsored and organic placements alike — don't present it as organic rank.

  11. maxPagesPerSearch caps your pagination, Amazon caps the rest. The input allows up to 20 pages, but Amazon itself stops serving useful results after a handful.

  12. deliveryMode defaults to perProduct — one connector call per product, with no cap. A 500-product run is 500 calls. Set summary or none unless you want a record each.

  13. Free Apify plans stop at 2 products per search / start URL. Direct product URLs share one bucket. That's a smoke test, not a data pull.

dependencies:
- rule: "at least one of searchKeywords / startUrls must be non-empty"
on_violation: "run ends SUCCEEDED with an empty dataset and a warning in the log - it does NOT fail validation"
- rule: "amazonDomain must match the marketplace of any startUrls you pass"
on_violation: "rows are stamped with the wrong currency and fetched from the wrong exit country"
- rule: "maxItemsPerSearch 0 removes the internal request ceiling"
note: "always pair it with maxTotalChargeUsd"
- rule: "delivery requires mcpConnector AND mcpTool"
on_violation: "delivery is skipped with a warning; every dataset row is still written"
- rule: "mcpArguments must reference {message} for the rendered template to appear anywhere"
on_violation: "message body is empty; the tool is still called"
- rule: "mcpConnector only resolves when the Actor runs on the Apify platform"
on_violation: "local runs log 'APIFY_MCP_PROXY_URL is not set' and skip delivery"
authentication:
actor_input: none
platform: "Apify API token required for API / SDK / MCP invocation; paid plan required for residential proxy groups"
target_site: "no Amazon account, Associates membership or PA-API key required (public pages only)"

📥 Input Contract

.actor/input_schema.json is authoritative — if this page disagrees with the schema files, the schema files win.

ParameterTypeRequiredDefaultNotes
searchKeywordsarray<string>see noteEach keyword becomes its own search on amazonDomain
startUrlsarraysee noteSearch, category or product URLs. Listing pages are crawled; /dp/ and /gp/product/ pages are scraped directly
amazonDomainstring (enum)⬜ Nowww.amazon.inMarketplace for keyword searches. Also sets row currency and the proxy exit country
maxItemsPerSearchinteger⬜ No100Per keyword / per listing URL. 0 = unlimited (also removes the request ceiling)
maxPagesPerSearchinteger⬜ No5120 listing pages per source
proxyConfigurationobject⬜ NoApify ResidentialCountry auto-pinned to the marketplace. Leave enabled.

At least one of searchKeywords or startUrls must be non-empty. Nothing is required in the schema, so this is enforced at runtime.

Marketplaces

amazonDomainMarketplaceRow currencyProxy exit
www.amazon.inIndia (default)INRIN
www.amazon.comUnited StatesUSDUS
www.amazon.co.ukUnited KingdomGBPGB
www.amazon.deGermanyEURDE
www.amazon.caCanadaCADCA
www.amazon.com.auAustraliaAUDAU
www.amazon.aeUnited Arab EmiratesAEDAE

The currency comes from this table rather than the on-page symbol, because $ alone is ambiguous across USD, CAD and AUD. That is also why a start URL from another marketplace is mislabelled — see execution rule 2.

Accepted startUrls shapes

ShapeExampleWhat happens
Search resultshttps://www.amazon.in/s?k=laptopCrawled and paginated; products enqueued
Category / listingany browse or node listing URLSame as a search page
Product pagehttps://www.amazon.com/dp/B0XXXXXXXXScraped directly; searchName and position are null

Delivery (optional)

ParameterTypeDefaultDescription
mcpConnectorstring""A connector you've authorised on your Apify account — Notion, Slack, Linear, Jira, GitHub, Airtable, or any MCP-compatible connector. Leave empty for dataset-only runs.
deliveryModestring (enum)perProductperProduct (one call per product, uncapped) · summary (one call with all products) · none.
mcpToolstring""Tool to call — create_page, send_message, create_issue. Required when a connector is set; run once and the log lists the connector's tools.
mcpArgumentsobject{}Arguments for the tool. String leaves support {placeholder} tokens.
mcpMessageTemplatestring""Template rendered and exposed to mcpArguments as {message}.

Placeholders by mode:

ModePlaceholders
perProduct{asin} {title} {brand} {price} {priceRaw} {currency} {rating} {reviewsCount} {availability} {url} {thumbnailUrl} {searchName} {position} {message}
summary{productCount} {products} (a markdown list of every product) {message}

Null values render as an empty string rather than the word "None". The array and object fields (features, categories, productDetails) are not exposed as placeholders — use the dataset for those.


📤 Output Contract & Data Structure

One dataset row per product, written as each detail page is parsed. Every row carries the same 17 keys; nullable fields come back null, never "N/A".

FieldTypeNullableMeaning
asinstringyesAmazon's product ID. The stable key for joining runs and de-duplicating
titlestringyesProduct title as listed
brandstringyesBrand or manufacturer, from the byline or the detail table
pricenumberyesNumeric price for sorting and arithmetic. Null when no price is shown
priceRawstringyesPrice exactly as displayed, symbol and formatting intact
currencystringyesFrom the marketplace table above, not guessed from the symbol
ratingnumberyesAverage stars out of 5. Null when the product has no ratings
reviewsCountintegeryesNumber of ratings/reviews. The reviews themselves are not scraped
availabilitystringyesStock or delivery text as displayed, e.g. In stock
featuresarraynoFeature bullets. [] when the page has none
descriptionstringyesDescription text, when the page provides one
categoriesarraynoBreadcrumb trail, broadest first. [] when absent
thumbnailUrlstringyesMain product image, hi-res when available
productDetailsobjectnoThe listing's own key/value table. Keys vary by category and are localized
urlstringnoCanonical product page URL
searchNamestringyesThe keyword or listing URL that produced this row. Null for direct product URLs
positionintegeryes1-based rank within that search. Null for direct product URLs

Rank is first-touch. A product matched by two keywords appears once, carrying the searchName and position of whichever search reached it first. Sponsored placements are counted in position and are not flagged.

Example output object

{
"asin": "B0XXXXXXXX",
"title": "Acme Wireless Over-Ear Headphones, 40h Battery, Active Noise Cancelling",
"brand": "Acme",
"price": 7499.0,
"priceRaw": "₹7,499.00",
"currency": "INR",
"rating": 4.3,
"reviewsCount": 2841,
"availability": "In stock",
"features": [
"Up to 40 hours of playback on a single charge",
"Hybrid active noise cancellation with transparency mode",
"Multipoint pairing with two devices"
],
"description": "Built for long listening sessions…",
"categories": ["Electronics", "Headphones", "Over-Ear Headphones"],
"thumbnailUrl": "https://m.media-amazon.com/images/I/71XXXXXXXXL._SL1500_.jpg",
"productDetails": {
"Brand": "Acme",
"Colour": "Midnight Black",
"Form Factor": "Over Ear",
"Item Weight": "250 g"
},
"url": "https://www.amazon.in/dp/B0XXXXXXXX",
"searchName": "wireless headphones",
"position": 7
}

Values illustrate shape and formatting — the product and numbers are invented. Note that productDetails keys are whatever that listing happened to publish; a different category, or amazon.de, returns a different key set.

What a successful run looks like

  • Status: SUCCEEDED
  • Dataset: one row per product, in completion order (not rank order — sort on position)
  • Log: a startup line naming the marketplace and source counts, one [LISTING] "<search>" page N: X cards, enqueued Y products per page, a [PRODUCT] Saved "<title>" per product, then Crawl finished. Scraped N product(s).
  • Zero results is also a success. No sources supplied, a persistent block, or a listing layout the parser didn't recognise all return an empty dataset with SUCCEEDED. Check the log.
  • A debug-listing-<page> record in the key-value store means a page returned no cards and no block marker — the raw HTML is there for inspection.

Dataset views

ViewShows
ProductsThumbnail, title, brand, price, currency, rating, reviews, availability, ASIN, link
Pricing & RankingSearch name, rank, title, brand, numeric and raw price, rating, reviews, ASIN
Full DetailASIN, title, brand, price, availability, features, description, categories, detail table

▶️ Invocation & Integration

Authenticate every call with Authorization: Bearer <APIFY_TOKEN>.

Apify Console

Open the Actor pageInput tab → pick the marketplace → type search keywords and/or paste Amazon URLs → set maxItemsPerSearch → leave the residential proxy on → Start.

Model Context Protocol (MCP)

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=techforce.global/amazon-scraper"

Then ask your agent for "the ten cheapest 4-star-plus wireless headphones on amazon.in".

Python (apify-client)

import os
from apify_client import ApifyClient
client = ApifyClient(os.getenv("APIFY_TOKEN"))
run = client.actor("techforce.global/amazon-scraper").call(run_input={
"searchKeywords": ["wireless headphones"],
"amazonDomain": "www.amazon.in",
"maxItemsPerSearch": 50,
"maxPagesPerSearch": 3,
"deliveryMode": "none",
"proxyConfiguration": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"]},
})
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
if not rows:
raise SystemExit("Nothing scraped — check the log (no sources? blocked?).")
# price is nullable — exclude, don't coerce to 0.
priced = [r for r in rows if r.get("price") is not None]
print(f"{len(priced)}/{len(rows)} rows have a price")
for r in sorted(priced, key=lambda r: r["price"])[:10]:
stars = f'{r["rating"]}★' if r.get("rating") is not None else ' — '
print(f'#{r.get("position") or "-":>3} {r["currency"]} {r["price"]:>10,.2f} '
f'{stars:>6} ({r.get("reviewsCount") or 0:>6}) {(r.get("title") or "")[:55]}')

JavaScript / TypeScript (apify-client)

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("techforce.global/amazon-scraper").call({
startUrls: [
{ url: "https://www.amazon.com/dp/B0XXXXXXXX" },
{ url: "https://www.amazon.com/dp/B0YYYYYYYY" },
],
amazonDomain: "www.amazon.com", // must match the URLs' marketplace
deliveryMode: "none",
proxyConfiguration: {
useApifyProxy: true,
apifyProxyGroups: ["RESIDENTIAL"],
},
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const p of items) {
// Direct product URLs carry no searchName/position — that's expected.
console.log(
`${p.asin} ${p.currency ?? ""} ${p.priceRaw ?? "no price"} ${p.availability ?? ""}`,
);
// productDetails keys differ per category and per marketplace — probe, don't assume.
const weight =
p.productDetails?.["Item Weight"] ??
p.productDetails?.["Artikelgewicht"];
if (weight) console.log(` weight: ${weight}`);
}

cURL — synchronous (waits, returns the dataset)

curl -X POST \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{
"searchKeywords": ["running shoes"],
"amazonDomain": "www.amazon.com",
"maxItemsPerSearch": 20,
"maxPagesPerSearch": 2,
"deliveryMode": "none",
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}' \
'https://api.apify.com/v2/acts/techforce.global~amazon-scraper/run-sync-get-dataset-items'

cURL — asynchronous with a spend cap (required for maxItemsPerSearch: 0)

# 1. Start with a hard spend limit
curl -X POST -H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{ "searchKeywords": ["laptop"], "amazonDomain": "www.amazon.co.uk",
"maxItemsPerSearch": 0, "maxPagesPerSearch": 10,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] } }' \
'https://api.apify.com/v2/acts/techforce.global~amazon-scraper/runs?maxTotalChargeUsd=10'
# 2. Poll, then 3. fetch the dataset when SUCCEEDED
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' 'https://api.apify.com/v2/actor-runs/<runId>'
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
'https://api.apify.com/v2/datasets/<DATASET_ID>/items?clean=true&format=json'

Tracking specific ASINs on a schedule

{
"startUrls": [
{ "url": "https://www.amazon.in/dp/B0XXXXXXXX" },
{ "url": "https://www.amazon.in/dp/B0YYYYYYYY" }
],
"amazonDomain": "www.amazon.in",
"deliveryMode": "none",
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

The cheapest and most predictable shape: one request per ASIN, no listing crawl. Put it on a schedule and join runs on asin to build the price history a single run can't give you.

Keyword rank tracking

{
"searchKeywords": ["wireless earbuds", "noise cancelling earbuds"],
"amazonDomain": "www.amazon.com",
"maxItemsPerSearch": 30,
"maxPagesPerSearch": 2,
"deliveryMode": "none",
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Sort by position within each searchName to see who ranks where. Remember sponsored slots are counted in the same sequence.

With MCP delivery — a price digest into Slack

{
"searchKeywords": ["mechanical keyboard"],
"amazonDomain": "www.amazon.com",
"maxItemsPerSearch": 20,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
},
"mcpConnector": "<your-authorized-slack-connector>",
"mcpTool": "send_message",
"deliveryMode": "summary",
"mcpMessageTemplate": "Found {productCount} products:\n\n{products}",
"mcpArguments": { "channel": "#price-watch", "text": "{message}" }
}

Set summary deliberatelyperProduct is the default and would post one Slack message per product.


⚠️ Autonomous Agent Error Handling & Resolution Matrix

Read this first: nothing about the pages fails the run. Missing sources, a persistent CAPTCHA and an unrecognised layout all end SUCCEEDED while the log carries the reason. An agent that checks run status alone will read an empty dataset as success-with-data — check the row count and the log.

The CONDITION labels are documentation handles for observable states; this Actor writes no error code into the dataset.

ConditionWhat you observeCauseDeterministic agent action
NO_SOURCES_PROVIDEDSUCCEEDED, empty dataset; log: No search keywords or start URLs provided. Nothing to scrape. Exiting.Both inputs empty — not caught by validationModify Input: supply keywords or URLs.
NO_PROXY_CONFIGUREDLog: No proxy configured. Amazon will very likely block requests.Proxy omitted or unusableModify Input: enable Apify Proxy, residential group.
BLOCKED_CAPTCHARetries in the log, then a thin/empty datasetDatacenter IP, or the residential pool is being challengedRetry with residential, lower volume, and re-run off-peak. Persistent blocks are not a bug you can configure away.
BM_VERIFY_NOT_CLEAREDLog: bot-manager (bm-verify) challenge not cleared after N attempt(s)Amazon's JS interstitial survived 3 automatic attemptsRetry later with residential; that request is abandoned, the run continues.
ZERO_CARDS_ON_LISTINGLog: 0 product cards found … + a debug-listing-<page> record in the key-value storeLayout change, or a block with an unknown markerInspect the saved HTML. Tiny/garbled body = encoding; robot/captcha text = proxy.
WRONG_CURRENCY_ON_ROWSRows show a currency that doesn't match the pageamazonDomain ≠ the marketplace of your startUrlsModify Input: one marketplace per run.
REGION_REDIRECT_OR_BLOCKOdd results or heavy blocking on start URLsExit country pinned to amazonDomain, not to the URLModify Input: set amazonDomain to match the URLs.
NULL_PRICEprice / priceRaw nullListing shows no price (unavailable, variant-gated)Expected. Null ≠ zero — exclude from averages.
NULL_RANKposition / searchName nullThe product came from a direct /dp/ start URLExpected. Rank only exists for search-sourced rows.
DUPLICATE_KEYWORD_ATTRIBUTIONA product matched two keywords but appears onceFirst-touch attribution; the URL is de-duplicatedExpected. Run keywords separately if per-keyword rank matters for both.
PRODUCT_DETAILS_KEY_MISSINGYour key path returns nothingKeys vary by category and are localized per marketplaceFix consumer: probe several key spellings, or read the whole object.
FEWER_ITEMS_THAN_REQUESTEDRows < maxItemsPerSearchAmazon stopped serving results, or maxPagesPerSearch ran outExpected. Raise pages, or accept the ceiling Amazon imposes.
RUN_UNBOUNDEDRun grows far past expectationsmaxItemsPerSearch: 0 removes the request ceilingAbort, set a real cap, and use maxTotalChargeUsd.
FREE_PLAN_CAPPED2 products per source; log: Free plan detected — capping results to 2 …Free Apify planUpgrade the plan.
CONNECTOR_CALL_STORMHundreds of connector callsdeliveryMode defaults to perProduct, uncappedModify Input: switch to summary or none.
CONNECTOR_TOOL_NOT_FOUNDLog: Tool 'x' is not available on this connector. Available tools: …Wrong mcpTool name (empty is logged separately)Modify Input: copy an exact name from that log line. Dataset unaffected.
CONNECTOR_UNREACHABLELog: Could not reach the connector: … or APIFY_MCP_PROXY_URL is not setConnector not authorised, or running locallyAuthorise it, or apify push and run on the platform. Data already saved.
AUTH_INVALIDHTTP 401Missing or malformed APIFY_TOKENAbort & prompt user for a valid token.
RATE_LIMITED_APIFYHTTP 429Apify API rate / concurrency limits — not AmazonRetry: exponential backoff (2s, 4s, 8s).
SYNC_TIMEOUTHTTP 408 on the sync endpointRun exceeded the synchronous ceilingReconfigure: async POST /runs + polling.

Provenance: every log line, status and dataset condition above is taken from this Actor's own source and verified against it. The three HTTP rows describe the Apify API transport layer, not this Actor — confirm them against the Apify API reference before wiring them into automated retry logic.


🗣️ Natural Language → Actor Mapping

A user says…IntentConstructed Actor input
"Find wireless headphones on Amazon"Keyword search{"searchKeywords":["wireless headphones"],"maxItemsPerSearch":50}
"Scrape this Amazon search page"Listing crawl{"startUrls":[{"url":"<search url>"}],"amazonDomain":"<matching domain>"}
"Get the details for this product"Single ASIN{"startUrls":[{"url":"https://www.amazon.com/dp/B0XXXXXXXX"}],"amazonDomain":"www.amazon.com"}
"Track these 20 ASINs daily"Price monitoring20 /dp/ start URLs on a schedule; join runs on asin
"What's the cheapest X?"Price rankingKeyword search, then sort on price excluding nulls
"Who ranks top 10 for this keyword?"Rank tracking{"searchKeywords":["<kw>"],"maxItemsPerSearch":10} then sort on position
"Compare prices in the US and UK"Cross-marketTwo runswww.amazon.com and www.amazon.co.uk — joined on asin
"Everything in this category"Bulk catalogueCategory URL, maxItemsPerSearch: 0 plus maxTotalChargeUsd
"Only well-reviewed products"Quality filterScrape, then filter rating >= 4 and reviewsCount >= 100
"Is it in stock?"Availability check/dp/ URL, read availability
"What are the specs?"Detail tableRead productDetails and features
"Send price drops to Slack"Scrape + deliverAbove, plus mcpConnector, mcpTool, deliveryMode: "summary"
"It returned nothing"Empty resultCheck a source was supplied, the proxy is residential, and the log for block lines
"What do reviewers actually say?"Review text❌ Not collected — only reviewsCount
"Who's winning the buy box?"Seller data❌ Not collected
"Buy it for me"Write action❌ Read-only

Should NOT route here: review text or reviewer identities · seller, offer or buy-box data · order, cart or account data · a full variant matrix · marketplaces outside the seven supported · purchasing or any write action · price history from a single run (schedule it instead) · non-Amazon retailers — use Flipkart Scraper, Etsy Scraper or Quince Scraper for those catalogues.


🧭 Agent Execution & Routing Logic

Does the user want AMAZON LISTING data?
├── NO → wrong Actor.
│ Flipkart listings (India) → Flipkart Scraper
│ Etsy handmade / vintage → Etsy Scraper
│ Quince (DTC storefront) → Quince Scraper
└── YES
├── FIRST: which marketplace? amazonDomain sets currency AND proxy country.
│ └── start URLs from another marketplace? → SPLIT INTO ONE RUN PER MARKETPLACE
├── What do they have?
│ ├── a topic → searchKeywords (gives position + searchName)
│ ├── a search/category → startUrls (listing; crawled and paginated)
│ └── specific products → startUrls with /dp/ (cheapest, most predictable)
├── ALWAYS keep proxyConfiguration on RESIDENTIAL (paid plan required)
├── Size the run
│ ├── maxItemsPerSearch → PER keyword / PER listing URL (0 = unlimited, no ceiling)
│ ├── maxPagesPerSearch → 1-20, but Amazon stops serving results early
│ └── every product = one request → cost tracks PRODUCT COUNT
├── What is the actual question?
│ ├── cheapest → sort price, EXCLUDING nulls
│ ├── best reviewed → rating + reviewsCount together (one without the other misleads)
│ ├── who ranks → position within searchName (sponsored included, unflagged)
│ ├── in stock? → availability
│ ├── specs → features + productDetails (keys vary + localized)
│ └── price over time → SCHEDULE it; join runs on asin
└── Should results land in another app?
├── yes → mcpConnector + mcpTool + {message} in mcpArguments
│ digest → summary · record each → perProduct (DEFAULT, UNCAPPED)
└── no → deliveryMode "none", or leave mcpConnector empty
[Execute Actor]
├──► SUCCEEDED with rows → sort/filter, remembering price and rank are nullable
├──► SUCCEEDED, 0 rows → READ THE LOG: no source / blocked / 0 cards (+ debug-listing HTML)
└──► 2 rows per source → free plan cap, not a data pull

💰 Cost Control & Pricing Transparency

Billing model: usage-based. This Actor bills for platform usage — the compute time and resources a run consumes — not per row. Current rates are on the Actor's Apify Store page; the Console shows the live total mid-run.

The shape to keep in mind: one request per product, plus one per listing page. Fifty products from one keyword is roughly 50 detail requests plus 2–3 listing pages.

ChoiceEffect on cost
maxItemsPerSearchThe main lever — it is the product count, and products are the requests.
Number of keywords / start URLsMultiplies it: 3 keywords × 100 is 300 products, not 100.
maxItemsPerSearch: 0Removes the internal request ceiling entirely. Never run it without maxTotalChargeUsd.
maxPagesPerSearchA few extra listing requests; minor next to the product count.
Direct /dp/ URLsThe cheapest shape — no listing crawl at all.
Being blockedRetries burn requests and return nothing. A datacenter proxy is the most expensive setting on this page.

Worked examples — relative run shape

ScenarioListing requestsProduct requestsNotes
Probe — 1 keyword, maxItemsPerSearch: 515Baseline. Confirms proxy and marketplace.
20 tracked ASINs, no search020Cheapest per row; ideal for scheduled monitoring.
1 keyword × 50 products~2–350The standard research run.
3 keywords × 100 products~9–15up to 300Multiplies by keyword — check the arithmetic first.
Category sweep, maxItemsPerSearch: 0, 10 pagesup to 10unboundedSet maxTotalChargeUsd.
Blocked run (datacenter proxy)retries0 usefulWorst value on this page.

Keeping runs predictable:

  1. First run: one keyword, maxItemsPerSearch: 5. Confirm rows come back with prices.
  2. Prefer /dp/ URLs for monitoring — a fixed ASIN list is arithmetic; a search is a forecast.
  3. Do the keyword multiplication before you run, not after.
  4. Always set maxTotalChargeUsd when maxItemsPerSearch is 0 or in the hundreds.
  5. Schedule small and often rather than one huge sweep — cheaper, and it builds the price history a single run cannot.
  6. Free Apify plans get 2 products per search — a connectivity check, not a data pull.

🛠️ Troubleshooting

Most problems are the proxy, a marketplace mismatch, or the per-source caps — not parser bugs.

#Symptom you seeMost likely causeFix
1SUCCEEDED but the dataset is emptyNo keywords and no start URLs — the schema doesn't enforce itRead the log for Nothing to scrape. Exiting. and supply a source.
2Empty or very thin results with retry lines in the logAmazon is blocking — datacenter IP or a challenged poolUse RESIDENTIAL, keep the country pinned (it is by default), lower volume, retry later.
3Log: 0 product cards found …Layout change, or a block with an unknown markerOpen the debug-listing-<page> record in the run's key-value store. Tiny/garbled body = encoding; robot/captcha text = proxy.
4Prices are in the wrong currencyamazonDomain doesn't match your startUrlsOne marketplace per run — the domain sets the currency for every row.
5Start URLs get blocked far more than keywordsThe exit country is pinned to amazonDomain, not to the URLSet amazonDomain to the URLs' marketplace.
6price is null on some rowsThe listing displays no priceExpected — exclude those rows rather than treating them as 0.
7position and searchName are nullThose products came from direct /dp/ URLsExpected — rank only exists for search-sourced rows.
8Fewer products than maxItemsPerSearchAmazon stopped serving results, or pages ran outRaise maxPagesPerSearch, or accept Amazon's own ceiling.
9A product matched two keywords but appears onceFirst-touch attribution + URL de-duplicationRun the keywords in separate runs if you need rank for both.
10productDetails is missing the key you wantedKeys vary by category and are localized per marketplaceProbe several spellings (e.g. Item Weight / Artikelgewicht) or read the whole object.
11features is emptyThat page has no bullet listExpected for some categories; description and productDetails may still be populated.
12Sponsored products polluting your rank analysisThey aren't flaggedTreat position as placement, not organic rank.
13Rows aren't in rank orderThey're written as each product finishesSort on position within searchName.
14Run far bigger/longer than expectedmaxItemsPerSearch: 0, or several keywordsCap it and set maxTotalChargeUsd.
15Only 2 products per searchFree plan capUpgrade; the log says Free plan detected — capping results to 2 ….
16Hundreds of connector calls fireddeliveryMode defaults to perProduct and is uncappedSwitch to summary or none.
17Slack / Notion received nothingDelivery needs both mcpConnector and mcpToolSet both. Every dataset row is still saved.
18Connector message fields are blankfeatures / categories / productDetails aren't placeholdersUse the scalar placeholders, or read the dataset.
19Log: APIFY_MCP_PROXY_URL is not setRan locally; connectors only resolve on the platformapify push and run on the platform.
20HTTP 401 / 403 from the Apify APIMissing, expired or malformed APIFY_TOKENRegenerate in Console → Settings → API & Integrations.
21HTTP 429 / 408 from the Apify APIApify rate limits / the sync endpoint's time ceilingBack off (2s → 4s → 8s), or switch to async POST /runs + polling.

Diagnostic checklist before opening an issue

  1. Confirm a source is setsearchKeywords or startUrls.
  2. Confirm the proxy is residential and that amazonDomain matches any URLs you passed.
  3. Baseline run: one keyword, maxItemsPerSearch: 5, maxPagesPerSearch: 1, deliveryMode: "none".
  4. Open the debug-listing-* record in the run's key-value store if a page returned no cards.
  5. Open the same URL in a browser — if Amazon shows you a robot check too, it's the IP.
  6. Check the log's startup line — it echoes the marketplace, source counts and caps actually in effect.

If the issue survives all six, open an Issues ticket (or email support) with the run ID, the input you used, and what you expected.


❓ FAQ

Do I need an Amazon account, Associates membership or API key?

No. The Actor reads publicly visible product pages. You need an Apify account and API token; you need no Amazon credentials of any kind.

Is this the official Amazon API?

No. This is an independent Actor and is not affiliated with, endorsed by, or sponsored by Amazon.com, Inc.

Why not just use the Product Advertising API?

Because it's gated: you need an approved Associates account and you keep access only while driving qualifying sales. It also doesn't expose search rank, and its field set is fixed rather than the listing's own detail table. If you qualify and its fields answer your question, use it.

Do I need a paid Apify plan?

In practice, yes. Amazon blocks datacenter IPs hard, and the residential proxy groups this Actor defaults to require a paid plan.

Can I plug it into Claude, Cursor, or a LangChain agent?

Yes — it is a native MCP tool: claude mcp add --transport http apify "https://mcp.apify.com?tools=techforce.global/amazon-scraper"

What can I put in startUrls?

Search result pages, category/browse listings, and direct product pages (/dp/… or /gp/product/…). Listing pages are crawled and their products enqueued; product pages are scraped directly.

Does amazonDomain apply to my start URLs?

Not to the fetching — your URLs are used as given. But it does set the currency stamped on every row and the proxy's exit country. A co.uk URL scraped while amazonDomain is www.amazon.in comes back labelled INR and requested from an Indian IP. Run one marketplace per run.

How many products will I get?

maxItemsPerSearch (default 100) applies per keyword and per listing URL, so three keywords is up to three times that. 0 means unlimited — and it also removes the crawl's internal request ceiling, so pair it with maxTotalChargeUsd.

How do I scrape one specific product?

Put its /dp/ URL in startUrls. That's the cheapest and most predictable shape — one request, no listing crawl — and it's the right pattern for scheduled price monitoring.

Can I compare marketplaces in one run?

Not reliably, because currency and proxy country are set per run. Run each marketplace separately and join the datasets on asin.

Why is price null?

The listing displayed no price — usually an unavailable item or a variant-gated one. Null is not zero and not free; exclude those rows from averages rather than coercing them.

What are searchName and position?

searchName is the keyword or listing URL that produced the row; position is its 1-based rank in those results. Both are null for products passed directly as /dp/ start URLs. Sponsored placements are counted in position and are not flagged.

A product matched two of my keywords — why does it appear once?

Because the same product URL is de-duplicated within a run, and the row keeps the searchName and position of whichever search reached it first. Run the keywords in separate runs if you need per-keyword rank for both.

Why are productDetails keys different from what I expected?

They mirror the listing's own table, so they vary by category — and they are localized: amazon.de returns German keys such as Artikelgewicht rather than Item Weight. Probe several spellings, or read the whole object.

Are the prices real-time?

They are a snapshot at scrape time, for the country the proxy exits from. Amazon personalises and moves prices constantly, so treat each run as a timestamped observation and schedule the Actor to build history.

Can I get review text, seller names or the buy-box winner?

No. Only reviewsCount is returned — the reviews themselves, reviewer identities, seller lists and offer/buy-box data are all out of scope.

Which delivery mode should I use, and does it work locally?

summary for one digest of the run; perProductthe default — sends one connector call per product with no cap, so a 500-product run is 500 calls; none for dataset-only runs. Delivery only works on the Apify platform; locally you'll see APIFY_MCP_PROXY_URL is not set and the dataset saves as normal.

What does it cost, and what do I get on the free plan?

Usage-based: you pay for the platform usage a run consumes, not per row. Because every product is its own request, the product count is the cost driver. Free Apify plans return 2 products per search / start URL. Pass maxTotalChargeUsd for a hard per-run ceiling.


🔍 Companion machine-readable files

FileWhat it defines
.actor/input_schema.jsonEvery input, its type, default, bounds and the marketplace enum
.actor/dataset_schema.jsonAll 17 output fields with nullability, and the three Console views
.actor/output_schema.jsonWhere the run's output is exposed
.actor/actor.jsonActor identity and storage wiring

If this page and the schema files disagree, the schema files win. They are what the platform validates against at run time; this page is documentation and can lag a release.


ActorBest forWhy pair it with this one
Flipkart ScraperProduct listings, prices and ratings from FlipkartIndia's other major marketplace — run it alongside amazon.in for price coverage neither side gives you alone
Etsy ScraperListings from Etsy's handmade and vintage marketplaceA different supply side to the same categories: small sellers, handmade and vintage pricing
Quince ScraperCatalogue and pricing from QuinceA direct-to-consumer brand storefront, where marketplace dynamics and Amazon pricing don't apply

Pipeline patterns: cross-retailer price comparison — the same product set through this Actor plus Flipkart or Etsy, matched on brand and model, to see where a category is actually cheapest · price monitoring — fixed ASIN list on a schedule, join on asin, alert on a delta via MCP · category intelligence — keyword sweep, rank by position, track share of the first two pages over time · marketplace vs. direct — Amazon listings against the brand's own Quince storefront pricing · listing QA — your own ASINs on a schedule, watching availability, priceRaw and rating for regressions.

Browse all Actors by Techforce Global at scraper.techforce.global.


🔐 Compliance & Data Privacy

Trademark & affiliation. This is an independent Actor. It is not affiliated with, endorsed by, or sponsored by Amazon.com, Inc. Amazon™ and the marketplace names are trademarks of Amazon.com, Inc. or its affiliates.

  • Public product pages only. Everything returned is visible to any signed-out shopper. No account login, no order or cart data, no seller dashboards, no credentials of any kind.

  • Almost no personal data — by design. Product listings are commercial content. This Actor collects no review text, no reviewer names and no reviewer profiles, only the review count. That keeps a straightforward GDPR/CCPA position for most uses, and it is the main reason to prefer it over review-scraping tools when you only need catalogue and pricing data.

  • Prices and availability are observations, not facts about the market. Amazon personalises results and offers by country, account and time. What you capture is what that page showed to that proxy at that moment. Publishing "the price of X" from a single run — or comparing runs taken from different countries — produces numbers that look authoritative and aren't.

  • Rank is placement, not merit. position includes sponsored slots and is not de-duplicated against advertising. Presenting it as organic ranking misrepresents it.

  • Listing content belongs to its owners. Titles, images, bullet points and descriptions are the brand's or Amazon's copyrighted material. Internal analysis, monitoring and research sit on far safer ground than republishing scraped listings as your own catalogue, and image URLs point at Amazon's CDN rather than to files you own.

  • Amazon's Conditions of Use prohibit scraping and automated access, and the sanctioned route is the Product Advertising API via the Associates programme. This Actor does not remove that risk — it is a risk you accept by running it. Repeated large-scale crawling is what draws enforcement; keep volumes proportionate to the question you're answering.

  • Competition-law caution for price data. Using scraped competitor prices to monitor a market is ordinary business intelligence; using them to coordinate or align pricing with competitors is not. If your use touches automated repricing, take advice.

  • Attribution over mirroring. Every row carries url and asin. Link back to the listing rather than presenting Amazon's catalogue as your own.


🆘 Support & Custom Pipeline Engineering

Need automated multi-city scheduled feeds, webhook enrichment, or enterprise data warehouse syncs?



🏷️ Structured data for search & AI discovery

SoftwareApplication describes the Actor; FAQPage wraps the FAQ above so those answers are eligible for rich results, matching it question-for-question.

{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Amazon Product Scraper",
"alternateName": "Amazon Products Scraper",
"applicationCategory": "BusinessApplication",
"applicationSubCategory": "Web Scraping / E-commerce & Price Intelligence",
"operatingSystem": "Cloud (Apify platform)",
"description": "Scrapes Amazon product data from search keywords, category and search result pages, or direct product URLs, across seven marketplaces (India, US, UK, Germany, Canada, Australia, UAE) — without an Amazon account, Associates approval or Product Advertising API key. Each row carries ASIN, title, brand, numeric and raw price, currency, star rating, review count, availability, feature bullets, description, breadcrumb categories, thumbnail, the listing's own key-value detail table, and the search keyword and 1-based rank that produced it. Residential proxy with the exit country auto-pinned to the marketplace, automatic bot-challenge handling, and optional delivery into Notion, Slack, Linear, Airtable or any MCP connector.",
"url": "https://apify.com/techforce.global/amazon-scraper",
"author": {
"@type": "Organization",
"name": "Techforce Global",
"url": "https://www.techforceglobal.com"
},
"provider": {
"@type": "Organization",
"name": "Apify",
"url": "https://apify.com"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"category": "Pay per platform usage",
"description": "Usage-based: billed for the compute time and resources a run consumes, not per row. Roughly one request per product plus the listing pages. Current rates are shown on the Actor's Apify Store page.",
"url": "https://apify.com/techforce.global/amazon-scraper"
},
"featureList": [
"No Amazon account, Associates approval or PA-API key required",
"Search keywords, category/search URLs and direct product URLs in one run",
"Seven marketplaces: India, US, UK, Germany, Canada, Australia, UAE",
"Full detail-page extraction, not just the search card",
"Numeric price for arithmetic plus the raw displayed price string",
"Marketplace-authoritative currency instead of guessing from an ambiguous symbol",
"Search rank (position) and source keyword (searchName) on every search-sourced row",
"Feature bullets, description, breadcrumb categories and the listing's own detail table",
"Residential proxy with the exit country auto-pinned to the marketplace",
"Automatic retry on CAPTCHA pages and automatic bot-manager challenge handling",
"Raw HTML saved to the key-value store when a listing yields no cards, for diagnosis",
"Rows saved as they are scraped, so aborted runs keep their partial data",
"Optional MCP delivery to Notion, Slack, Linear, Airtable and more",
"Three Console dataset views covering products, pricing/ranking and full detail"
],
"isAccessibleForFree": false,
"softwareRequirements": "Apify account and API token; a paid plan for residential proxies",
"keywords": "Amazon product scraper, Amazon price scraper, Product Advertising API alternative, scrape Amazon search results, ASIN data extraction, price monitoring, competitor price tracking, keyword rank tracking, ecommerce product data, MCP connector"
}
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do I need an Amazon account, Associates membership or API key?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. The Actor reads publicly visible product pages. You need an Apify account and API token; you need no Amazon credentials of any kind."
}
},
{
"@type": "Question",
"name": "Is this the official Amazon API?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. This is an independent Actor and is not affiliated with, endorsed by, or sponsored by Amazon.com, Inc."
}
},
{
"@type": "Question",
"name": "Why not just use the Product Advertising API?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Because it's gated: you need an approved Associates account and you keep access only while driving qualifying sales. It also doesn't expose search rank, and its field set is fixed rather than the listing's own detail table. If you qualify and its fields answer your question, use it."
}
},
{
"@type": "Question",
"name": "Do I need a paid Apify plan?",
"acceptedAnswer": {
"@type": "Answer",
"text": "In practice, yes. Amazon blocks datacenter IPs hard, and the residential proxy groups this Actor defaults to require a paid plan."
}
},
{
"@type": "Question",
"name": "Can I plug it into Claude, Cursor, or a LangChain agent?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes — it is a native MCP tool: claude mcp add --transport http apify \"https://mcp.apify.com?tools=techforce.global/amazon-scraper\""
}
},
{
"@type": "Question",
"name": "What can I put in startUrls?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Search result pages, category/browse listings, and direct product pages (/dp/… or /gp/product/…). Listing pages are crawled and their products enqueued; product pages are scraped directly."
}
},
{
"@type": "Question",
"name": "Does amazonDomain apply to my start URLs?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Not to the fetching — your URLs are used as given. But it does set the currency stamped on every row and the proxy's exit country. A co.uk URL scraped while amazonDomain is www.amazon.in comes back labelled INR and requested from an Indian IP. Run one marketplace per run."
}
},
{
"@type": "Question",
"name": "How many products will I get?",
"acceptedAnswer": {
"@type": "Answer",
"text": "maxItemsPerSearch (default 100) applies per keyword and per listing URL, so three keywords is up to three times that. 0 means unlimited — and it also removes the crawl's internal request ceiling, so pair it with maxTotalChargeUsd."
}
},
{
"@type": "Question",
"name": "How do I scrape one specific product?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Put its /dp/ URL in startUrls. That's the cheapest and most predictable shape — one request, no listing crawl — and it's the right pattern for scheduled price monitoring."
}
},
{
"@type": "Question",
"name": "Can I compare marketplaces in one run?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Not reliably, because currency and proxy country are set per run. Run each marketplace separately and join the datasets on asin."
}
},
{
"@type": "Question",
"name": "Why is price null?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The listing displayed no price — usually an unavailable item or a variant-gated one. Null is not zero and not free; exclude those rows from averages rather than coercing them."
}
},
{
"@type": "Question",
"name": "What are searchName and position?",
"acceptedAnswer": {
"@type": "Answer",
"text": "searchName is the keyword or listing URL that produced the row; position is its 1-based rank in those results. Both are null for products passed directly as /dp/ start URLs. Sponsored placements are counted in position and are not flagged."
}
},
{
"@type": "Question",
"name": "A product matched two of my keywords — why does it appear once?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Because the same product URL is de-duplicated within a run, and the row keeps the searchName and position of whichever search reached it first. Run the keywords in separate runs if you need per-keyword rank for both."
}
},
{
"@type": "Question",
"name": "Why are productDetails keys different from what I expected?",
"acceptedAnswer": {
"@type": "Answer",
"text": "They mirror the listing's own table, so they vary by category — and they are localized: amazon.de returns German keys such as Artikelgewicht rather than Item Weight. Probe several spellings, or read the whole object."
}
},
{
"@type": "Question",
"name": "Are the prices real-time?",
"acceptedAnswer": {
"@type": "Answer",
"text": "They are a snapshot at scrape time, for the country the proxy exits from. Amazon personalises and moves prices constantly, so treat each run as a timestamped observation and schedule the Actor to build history."
}
},
{
"@type": "Question",
"name": "Can I get review text, seller names or the buy-box winner?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. Only reviewsCount is returned — the reviews themselves, reviewer identities, seller lists and offer/buy-box data are all out of scope."
}
},
{
"@type": "Question",
"name": "Which delivery mode should I use, and does it work locally?",
"acceptedAnswer": {
"@type": "Answer",
"text": "summary for one digest of the run; perProduct — the default — sends one connector call per product with no cap, so a 500-product run is 500 calls; none for dataset-only runs. Delivery only works on the Apify platform; locally you'll see APIFY_MCP_PROXY_URL is not set and the dataset saves as normal."
}
},
{
"@type": "Question",
"name": "What does it cost, and what do I get on the free plan?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Usage-based: you pay for the platform usage a run consumes, not per row. Because every product is its own request, the product count is the cost driver. Free Apify plans return 2 products per search / start URL. Pass maxTotalChargeUsd for a hard per-run ceiling."
}
}
]
}