Amazon Product Scraper - Prices, Ratings & Search Rank
Pricing
from $8.70 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Share
Amazon Product Scraper - Prices, Ratings & Search Rank, with MCP Delivery to Notion, Slack & Airtable
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
| Credentials | None 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 scope | Public product pages only — what any signed-out shopper sees. No account data, no order history, no buyer identities. |
| Personal data | Essentially none. Product listings are commercial content; this Actor collects no reviewer names and no review text, only the review count. |
| ⚠️ Proxy is not optional | Amazon 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 honesty | Prices 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 / Capability | Official Product Advertising API | Amazon 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 exposed | ✅ position on every row, per keyword |
| Which keyword found the product | ❌ You track it yourself | ✅ searchName on every row |
| Full detail table | ⚠️ A fixed set of resources | ✅ productDetails — 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 productpages across 7 marketplaces - title, brand, price, rating, review count, availability,features, description, breadcrumbs and the listing's own detail table - plus the search rankthat 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 passesvalidation, 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 otherthings - the currency written onto every row, and the residential proxy exit country. Itdoes NOT rewrite startUrls. A start URL from a different marketplace is still fetched, butit will be labelled with the selected marketplace's currency and requested from the wrongcountry, 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, andsearchName names that search. A product matched by two keywords is scraped once, attributedto 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 localizedon non-English marketplaces (amazon.de returns German keys). Treat it as free-form; neverhard-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 pinnedto 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), andAmazon's bot-manager interstitial is followed automatically up to 3 times. Persistent blocksend 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 savedto 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, catalogueor 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, orto 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 scrapedproduct, with no cap. A 500-product run is 500 calls. Set "summary" or "none" unless youreally 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 upstreamoutage 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.
priceas a number for sorting and arithmetic,priceRawexactly as displayed with symbol and formatting intact — plus an authoritativecurrencytaken from the marketplace rather than guessed from an ambiguous$. -
Search rank, which the official API doesn't give you.
positionis the 1-based rank in the results, andsearchNamerecords 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
ABORTINGevent 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
| Scenario | Fit |
|---|---|
| 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)
-
Supply at least one of
searchKeywordsorstartUrls. Nothing is marked required in the schema, so a run with neither passes validation, logsNo search keywords or start URLs provided. Nothing to scrape. Exiting.and endsSUCCEEDEDwith an empty dataset. Never readitemCount: 0as a crash. -
amazonDomaindoes not rewrite your start URLs — but it does label them. It builds the search URLs forsearchKeywords, sets thecurrencywritten onto every row, and pins the proxy's exit country. Pass anamazon.co.ukstart URL whileamazonDomainiswww.amazon.inand you get a real UK page stampedINR, fetched from an Indian IP. Run one marketplace per run. -
maxItemsPerSearchis per keyword and per listing URL, not per run. Three keywords at100is up to 300 products.0means unlimited and removes the crawl's request ceiling — pair it withmaxTotalChargeUsd. -
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.
-
Keep the residential proxy. Default is
{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}, with the exit country pinned automatically. Datacenter IPs get CAPTCHA'd; the log warnsNo proxy configured. Amazon will very likely block requests.Residential needs a paid plan. -
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
SUCCEEDEDrun with a thin dataset — check the log, not the run status. -
pricecan benull. Unavailable listings and some variants display no price. Null is not zero — exclude those rows rather than treating them as free. -
positionandsearchNameare first-touch. A product matched by two keywords is scraped once, attributed to whichever search reached it first. Both arenullfor products passed directly as/dp/start URLs. -
productDetailskeys are unstable. They mirror the listing's own table, so they vary by category and are localized on non-English marketplaces (amazon.dereturns German keys). Never hard-code a key path without a fallback. -
Sponsored results are not flagged.
positioncounts sponsored and organic placements alike — don't present it as organic rank. -
maxPagesPerSearchcaps your pagination, Amazon caps the rest. The input allows up to 20 pages, but Amazon itself stops serving useful results after a handful. -
deliveryModedefaults toperProduct— one connector call per product, with no cap. A 500-product run is 500 calls. Setsummaryornoneunless you want a record each. -
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: noneplatform: "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.
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
searchKeywords | array<string> | see note | — | Each keyword becomes its own search on amazonDomain |
startUrls | array | see note | — | Search, category or product URLs. Listing pages are crawled; /dp/ and /gp/product/ pages are scraped directly |
amazonDomain | string (enum) | ⬜ No | www.amazon.in | Marketplace for keyword searches. Also sets row currency and the proxy exit country |
maxItemsPerSearch | integer | ⬜ No | 100 | Per keyword / per listing URL. 0 = unlimited (also removes the request ceiling) |
maxPagesPerSearch | integer | ⬜ No | 5 | 1–20 listing pages per source |
proxyConfiguration | object | ⬜ No | Apify Residential | Country auto-pinned to the marketplace. Leave enabled. |
At least one of
searchKeywordsorstartUrlsmust be non-empty. Nothing isrequiredin the schema, so this is enforced at runtime.
Marketplaces
amazonDomain | Marketplace | Row currency | Proxy exit |
|---|---|---|---|
www.amazon.in | India (default) | INR | IN |
www.amazon.com | United States | USD | US |
www.amazon.co.uk | United Kingdom | GBP | GB |
www.amazon.de | Germany | EUR | DE |
www.amazon.ca | Canada | CAD | CA |
www.amazon.com.au | Australia | AUD | AU |
www.amazon.ae | United Arab Emirates | AED | AE |
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
| Shape | Example | What happens |
|---|---|---|
| Search results | https://www.amazon.in/s?k=laptop | Crawled and paginated; products enqueued |
| Category / listing | any browse or node listing URL | Same as a search page |
| Product page | https://www.amazon.com/dp/B0XXXXXXXX | Scraped directly; searchName and position are null |
Delivery (optional)
| Parameter | Type | Default | Description |
|---|---|---|---|
mcpConnector | string | "" | 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. |
deliveryMode | string (enum) | perProduct | perProduct (one call per product, uncapped) · summary (one call with all products) · none. |
mcpTool | string | "" | 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. |
mcpArguments | object | {} | Arguments for the tool. String leaves support {placeholder} tokens. |
mcpMessageTemplate | string | "" | Template rendered and exposed to mcpArguments as {message}. |
Placeholders by mode:
| Mode | Placeholders |
|---|---|
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".
| Field | Type | Nullable | Meaning |
|---|---|---|---|
asin | string | yes | Amazon's product ID. The stable key for joining runs and de-duplicating |
title | string | yes | Product title as listed |
brand | string | yes | Brand or manufacturer, from the byline or the detail table |
price | number | yes | Numeric price for sorting and arithmetic. Null when no price is shown |
priceRaw | string | yes | Price exactly as displayed, symbol and formatting intact |
currency | string | yes | From the marketplace table above, not guessed from the symbol |
rating | number | yes | Average stars out of 5. Null when the product has no ratings |
reviewsCount | integer | yes | Number of ratings/reviews. The reviews themselves are not scraped |
availability | string | yes | Stock or delivery text as displayed, e.g. In stock |
features | array | no | Feature bullets. [] when the page has none |
description | string | yes | Description text, when the page provides one |
categories | array | no | Breadcrumb trail, broadest first. [] when absent |
thumbnailUrl | string | yes | Main product image, hi-res when available |
productDetails | object | no | The listing's own key/value table. Keys vary by category and are localized |
url | string | no | Canonical product page URL |
searchName | string | yes | The keyword or listing URL that produced this row. Null for direct product URLs |
position | integer | yes | 1-based rank within that search. Null for direct product URLs |
Rank is first-touch. A product matched by two keywords appears once, carrying the
searchNameandpositionof whichever search reached it first. Sponsored placements are counted inpositionand 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
productDetailskeys are whatever that listing happened to publish; a different category, oramazon.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 productsper page, a[PRODUCT] Saved "<title>"per product, thenCrawl 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
| View | Shows |
|---|---|
| Products | Thumbnail, title, brand, price, currency, rating, reviews, availability, ASIN, link |
| Pricing & Ranking | Search name, rank, title, brand, numeric and raw price, rating, reviews, ASIN |
| Full Detail | ASIN, title, brand, price, availability, features, description, categories, detail table |
▶️ Invocation & Integration
Authenticate every call with Authorization: Bearer <APIFY_TOKEN>.
Apify Console
Open the Actor page → Input 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 osfrom apify_client import ApifyClientclient = 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' marketplacedeliveryMode: "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 limitcurl -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 SUCCEEDEDcurl -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 deliberately — perProduct 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.
| Condition | What you observe | Cause | Deterministic agent action |
|---|---|---|---|
NO_SOURCES_PROVIDED | SUCCEEDED, empty dataset; log: No search keywords or start URLs provided. Nothing to scrape. Exiting. | Both inputs empty — not caught by validation | Modify Input: supply keywords or URLs. |
NO_PROXY_CONFIGURED | Log: No proxy configured. Amazon will very likely block requests. | Proxy omitted or unusable | Modify Input: enable Apify Proxy, residential group. |
BLOCKED_CAPTCHA | Retries in the log, then a thin/empty dataset | Datacenter IP, or the residential pool is being challenged | Retry with residential, lower volume, and re-run off-peak. Persistent blocks are not a bug you can configure away. |
BM_VERIFY_NOT_CLEARED | Log: bot-manager (bm-verify) challenge not cleared after N attempt(s) | Amazon's JS interstitial survived 3 automatic attempts | Retry later with residential; that request is abandoned, the run continues. |
ZERO_CARDS_ON_LISTING | Log: 0 product cards found … + a debug-listing-<page> record in the key-value store | Layout change, or a block with an unknown marker | Inspect the saved HTML. Tiny/garbled body = encoding; robot/captcha text = proxy. |
WRONG_CURRENCY_ON_ROWS | Rows show a currency that doesn't match the page | amazonDomain ≠ the marketplace of your startUrls | Modify Input: one marketplace per run. |
REGION_REDIRECT_OR_BLOCK | Odd results or heavy blocking on start URLs | Exit country pinned to amazonDomain, not to the URL | Modify Input: set amazonDomain to match the URLs. |
NULL_PRICE | price / priceRaw null | Listing shows no price (unavailable, variant-gated) | Expected. Null ≠ zero — exclude from averages. |
NULL_RANK | position / searchName null | The product came from a direct /dp/ start URL | Expected. Rank only exists for search-sourced rows. |
DUPLICATE_KEYWORD_ATTRIBUTION | A product matched two keywords but appears once | First-touch attribution; the URL is de-duplicated | Expected. Run keywords separately if per-keyword rank matters for both. |
PRODUCT_DETAILS_KEY_MISSING | Your key path returns nothing | Keys vary by category and are localized per marketplace | Fix consumer: probe several key spellings, or read the whole object. |
FEWER_ITEMS_THAN_REQUESTED | Rows < maxItemsPerSearch | Amazon stopped serving results, or maxPagesPerSearch ran out | Expected. Raise pages, or accept the ceiling Amazon imposes. |
RUN_UNBOUNDED | Run grows far past expectations | maxItemsPerSearch: 0 removes the request ceiling | Abort, set a real cap, and use maxTotalChargeUsd. |
FREE_PLAN_CAPPED | 2 products per source; log: Free plan detected — capping results to 2 … | Free Apify plan | Upgrade the plan. |
CONNECTOR_CALL_STORM | Hundreds of connector calls | deliveryMode defaults to perProduct, uncapped | Modify Input: switch to summary or none. |
CONNECTOR_TOOL_NOT_FOUND | Log: 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_UNREACHABLE | Log: Could not reach the connector: … or APIFY_MCP_PROXY_URL is not set | Connector not authorised, or running locally | Authorise it, or apify push and run on the platform. Data already saved. |
AUTH_INVALID | HTTP 401 | Missing or malformed APIFY_TOKEN | Abort & prompt user for a valid token. |
RATE_LIMITED_APIFY | HTTP 429 | Apify API rate / concurrency limits — not Amazon | Retry: exponential backoff (2s, 4s, 8s). |
SYNC_TIMEOUT | HTTP 408 on the sync endpoint | Run exceeded the synchronous ceiling | Reconfigure: 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… | Intent | Constructed 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 monitoring | 20 /dp/ start URLs on a schedule; join runs on asin |
| "What's the cheapest X?" | Price ranking | Keyword 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-market | Two runs — www.amazon.com and www.amazon.co.uk — joined on asin |
| "Everything in this category" | Bulk catalogue | Category URL, maxItemsPerSearch: 0 plus maxTotalChargeUsd |
| "Only well-reviewed products" | Quality filter | Scrape, then filter rating >= 4 and reviewsCount >= 100 |
| "Is it in stock?" | Availability check | /dp/ URL, read availability |
| "What are the specs?" | Detail table | Read productDetails and features |
| "Send price drops to Slack" | Scrape + deliver | Above, plus mcpConnector, mcpTool, deliveryMode: "summary" |
| "It returned nothing" | Empty result | Check 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.
| Choice | Effect on cost |
|---|---|
maxItemsPerSearch | The main lever — it is the product count, and products are the requests. |
| Number of keywords / start URLs | Multiplies it: 3 keywords × 100 is 300 products, not 100. |
maxItemsPerSearch: 0 | Removes the internal request ceiling entirely. Never run it without maxTotalChargeUsd. |
maxPagesPerSearch | A few extra listing requests; minor next to the product count. |
Direct /dp/ URLs | The cheapest shape — no listing crawl at all. |
| Being blocked | Retries burn requests and return nothing. A datacenter proxy is the most expensive setting on this page. |
Worked examples — relative run shape
| Scenario | Listing requests | Product requests | Notes |
|---|---|---|---|
Probe — 1 keyword, maxItemsPerSearch: 5 | 1 | 5 | Baseline. Confirms proxy and marketplace. |
| 20 tracked ASINs, no search | 0 | 20 | Cheapest per row; ideal for scheduled monitoring. |
| 1 keyword × 50 products | ~2–3 | 50 | The standard research run. |
| 3 keywords × 100 products | ~9–15 | up to 300 | Multiplies by keyword — check the arithmetic first. |
Category sweep, maxItemsPerSearch: 0, 10 pages | up to 10 | unbounded | Set maxTotalChargeUsd. |
| Blocked run (datacenter proxy) | retries | 0 useful | Worst value on this page. |
Keeping runs predictable:
- First run: one keyword,
maxItemsPerSearch: 5. Confirm rows come back with prices. - Prefer
/dp/URLs for monitoring — a fixed ASIN list is arithmetic; a search is a forecast. - Do the keyword multiplication before you run, not after.
- Always set
maxTotalChargeUsdwhenmaxItemsPerSearchis0or in the hundreds. - Schedule small and often rather than one huge sweep — cheaper, and it builds the price history a single run cannot.
- 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 see | Most likely cause | Fix |
|---|---|---|---|
| 1 | SUCCEEDED but the dataset is empty | No keywords and no start URLs — the schema doesn't enforce it | Read the log for Nothing to scrape. Exiting. and supply a source. |
| 2 | Empty or very thin results with retry lines in the log | Amazon is blocking — datacenter IP or a challenged pool | Use RESIDENTIAL, keep the country pinned (it is by default), lower volume, retry later. |
| 3 | Log: 0 product cards found … | Layout change, or a block with an unknown marker | Open the debug-listing-<page> record in the run's key-value store. Tiny/garbled body = encoding; robot/captcha text = proxy. |
| 4 | Prices are in the wrong currency | amazonDomain doesn't match your startUrls | One marketplace per run — the domain sets the currency for every row. |
| 5 | Start URLs get blocked far more than keywords | The exit country is pinned to amazonDomain, not to the URL | Set amazonDomain to the URLs' marketplace. |
| 6 | price is null on some rows | The listing displays no price | Expected — exclude those rows rather than treating them as 0. |
| 7 | position and searchName are null | Those products came from direct /dp/ URLs | Expected — rank only exists for search-sourced rows. |
| 8 | Fewer products than maxItemsPerSearch | Amazon stopped serving results, or pages ran out | Raise maxPagesPerSearch, or accept Amazon's own ceiling. |
| 9 | A product matched two keywords but appears once | First-touch attribution + URL de-duplication | Run the keywords in separate runs if you need rank for both. |
| 10 | productDetails is missing the key you wanted | Keys vary by category and are localized per marketplace | Probe several spellings (e.g. Item Weight / Artikelgewicht) or read the whole object. |
| 11 | features is empty | That page has no bullet list | Expected for some categories; description and productDetails may still be populated. |
| 12 | Sponsored products polluting your rank analysis | They aren't flagged | Treat position as placement, not organic rank. |
| 13 | Rows aren't in rank order | They're written as each product finishes | Sort on position within searchName. |
| 14 | Run far bigger/longer than expected | maxItemsPerSearch: 0, or several keywords | Cap it and set maxTotalChargeUsd. |
| 15 | Only 2 products per search | Free plan cap | Upgrade; the log says Free plan detected — capping results to 2 …. |
| 16 | Hundreds of connector calls fired | deliveryMode defaults to perProduct and is uncapped | Switch to summary or none. |
| 17 | Slack / Notion received nothing | Delivery needs both mcpConnector and mcpTool | Set both. Every dataset row is still saved. |
| 18 | Connector message fields are blank | features / categories / productDetails aren't placeholders | Use the scalar placeholders, or read the dataset. |
| 19 | Log: APIFY_MCP_PROXY_URL is not set | Ran locally; connectors only resolve on the platform | apify push and run on the platform. |
| 20 | HTTP 401 / 403 from the Apify API | Missing, expired or malformed APIFY_TOKEN | Regenerate in Console → Settings → API & Integrations. |
| 21 | HTTP 429 / 408 from the Apify API | Apify rate limits / the sync endpoint's time ceiling | Back off (2s → 4s → 8s), or switch to async POST /runs + polling. |
Diagnostic checklist before opening an issue
- Confirm a source is set —
searchKeywordsorstartUrls. - Confirm the proxy is residential and that
amazonDomainmatches any URLs you passed. - Baseline run: one keyword,
maxItemsPerSearch: 5,maxPagesPerSearch: 1,deliveryMode: "none". - Open the
debug-listing-*record in the run's key-value store if a page returned no cards. - Open the same URL in a browser — if Amazon shows you a robot check too, it's the IP.
- 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; 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.
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
| File | What it defines |
|---|---|
| .actor/input_schema.json | Every input, its type, default, bounds and the marketplace enum |
| .actor/dataset_schema.json | All 17 output fields with nullability, and the three Console views |
| .actor/output_schema.json | Where the run's output is exposed |
| .actor/actor.json | Actor 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.
🔗 Related Actors by Techforce Global
| Actor | Best for | Why pair it with this one |
|---|---|---|
| Flipkart Scraper | Product listings, prices and ratings from Flipkart | India's other major marketplace — run it alongside amazon.in for price coverage neither side gives you alone |
| Etsy Scraper | Listings from Etsy's handmade and vintage marketplace | A different supply side to the same categories: small sellers, handmade and vintage pricing |
| Quince Scraper | Catalogue and pricing from Quince | A 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.
positionincludes 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
urlandasin. 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?
- Email: bhavin.shah@techforceglobal.com
- Custom Enterprise Integrations: Book a 15-Minute Technical Consultation
- Maintained by: Techforce Global — Specialists in High-Performance Web Scrapers and Agentic Workflows.
🏷️ 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."}}]}