Amazon ASIN Scraper By Country & Marketplace
Pricing
$19.99/month + usage
Amazon ASIN Scraper By Country & Marketplace
The Amazon ASIN Scraper actor extracts ASINs, product titles, prices, ratings, and URLs from Amazon search results or category pages. It automates large-scale product data collection for market research, competitor analysis, and pricing insights. Ideal for e-commerce and data intelligence tasks.
Pricing
$19.99/month + usage
Rating
0.0
(0)
Developer
Scraper Engine
Maintained by CommunityActor stats
0
Bookmarked
25
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
Amazon ASIN Scraper — Prices, Currency and Availability by Country
Amazon ASIN Scraper By Country & Marketplace prices a list of ASINs across many Amazon storefronts in a single run and returns one row per ASIN and marketplace: priceValue with currencyCode in that storefront's own currency, an added priceUsd for ranking, plus priceRank, cheapestMarketplace, priceGapPercent, isAvailable and availabilityStatus. Everything comes back as typed JSON with a stable schema — no HTML parsing, no selectors. Add your ASINs, pick the storefronts, start the run.
What is Amazon ASIN Scraper By Country & Marketplace?
It is an Apify Actor that takes one ASIN list and prices it on every Amazon country storefront you name. Each storefront is fetched with its own locale cookie and Accept-Language, so amazon.de answers in euros and amazon.co.uk in pounds instead of an Amazon-converted USD figure — and every row records which cookie was sent, in localeCookieSent, so the currency is auditable rather than assumed.
No Amazon account, login, cookie or Product Advertising API key is required. Every field returned is what an anonymous shopper on that country's product page already sees.
It is built for pricing and arbitrage analysts, marketplace expansion teams, procurement and reselling operations, and developers piping cross-border product data into an internal tool or an agent.
What Amazon product data is publicly available to scrape?
Amazon renders the full commercial offer on a /dp/ product page before any login: title, buy-box price in the storefront's currency, availability, rating, review count, bestseller rank and A+ marketing content. What is gated is account-level and seller-level data, not product data.
| Data Category | Publicly Available | Behind an Amazon account / Seller Central |
|---|---|---|
| Title, brand, images, feature bullets, specs | ✅ Public | — |
| Buy-box price, list price, currency, shipping message | ✅ Public | — |
| Availability and stock wording | ✅ Public | — |
| Star rating, review count, rating histogram percentages | ✅ Public | — |
| Bestseller ranks, Amazon's Choice badge, monthly purchase wording | ✅ Public | — |
| A+ content, brand story, product comparison table, AI review summary | ✅ Public | — |
| Individual review text and reviewer identity | ❌ | Amazon serves logged-out shells on review surfaces |
| Buyer identity, order and payment history | ❌ | Account |
| Seller inventory, fees, internal sales figures | ❌ | Seller Central |
| Historical price series, and Amazon's own cross-marketplace FX rate | ❌ | Amazon publishes neither |
Amazon ASIN Scraper By Country & Marketplace only returns publicly visible data — what any visitor to that country's product page sees. Nothing behind a login wall.
What data can I extract with Amazon ASIN Scraper By Country & Marketplace?
A successfully parsed row carries 85 keys, spanning cross-marketplace pricing and ranking, the product record itself, ratings and demand signals, rich marketing content, and per-request run accounting.
| Field Name | Description |
|---|---|
asin | The ASIN, uppercased and normalized from your input |
originalAsin | Same value, kept for parity with single-marketplace Amazon Actors |
marketplace | Storefront domain this row was priced on, e.g. amazon.de |
marketplaceCountry | ISO-3166 alpha-2 country of the storefront; null for a domain outside the built-in map |
marketplaceCurrency | ISO-4217 currency the storefront natively quotes in, from the built-in map |
priceValue | Buy-box price as a number, in the storefront's own currency |
priceCurrency | Display symbol detected on the page (€, £, S$, zł, …) |
currencyCode | ISO-4217 code detected on the page; null when the page showed no currency token |
priceIsNativeCurrency | true when currencyCode matches marketplaceCurrency — the flag that catches an Amazon-converted price |
price | Nested { "value", "currency" } object for the same buy-box price |
listPrice | Nested { "value", "currency" } strike-through price, null when equal to price |
priceRange | Price range string when Amazon shows a range instead of one price |
priceUsd | priceValue converted to USD for ranking; null when no rate was available |
fxRateToUsd | The rate used for this row's currency, as returned by the reference feed |
fxRatesDate | Date the feed itself reports for that rate set |
priceComparisonBasis | How this ASIN's storefronts were ranked: usd_ecb_reference, usd_ecb_reference_partial, same_currency or none |
priceRank | 1-based cheapest-first rank of this storefront for this ASIN; null if unpriced |
isCheapestMarketplace | true on the rank-1 row, null when this row was not ranked |
cheapestMarketplace | Domain of the cheapest storefront for this ASIN in this run |
cheapestPriceUsd | priceUsd of that cheapest row; null when the ranking ran without FX |
priceGapPercent | How much more expensive this row is than the cheapest, in percent |
marketplacesCompared | Number of storefronts configured for the run |
marketplacesPriced | Number of those storefronts that produced a comparable price |
isAvailable | true / false / null — null means undetermined, not unavailable |
availabilityStatus | Reason behind isAvailable; one of nine values listed below |
inStock | Raw stock boolean parsed from Amazon's availability block |
inStockText | Amazon's own availability wording, in the storefront's language |
title | Product title as rendered on that storefront |
brand | Brand or byline name |
author | Author, for book and media listings |
description | Product description text |
bookDescription | Book/editorial description, populated only when description is empty |
features | "About this item" bullet list |
attributes | Spec and detail rows as { "key", "value" } pairs |
productOverview | Amazon's product-overview table as { "key", "value" } pairs |
breadCrumbs | Category path joined with > |
thumbnailImage | Main product image URL |
galleryThumbnails | Gallery thumbnail URLs |
highResolutionImages | Full-resolution image URLs |
videosCount | Number of product videos detected |
variantAsins | Sibling variant ASINs found on the page |
variantDetails | Variants as { "name", "thumbnail", "images", "asin", "price" } |
variantAttributes | Selected variant dimensions as { "key", "value" } pairs |
stars | Average star rating |
starsBreakdown | Rating histogram keyed 5star … 1star, values as 0–1 fractions |
reviewsCount | Number of ratings |
hasReviews | true when reviewsCount is above zero |
reviewsLink | Constructed link to the storefront's review page |
answeredQuestions | Answered-questions count when Amazon renders one |
monthlyPurchaseVolume | Amazon's "N bought in past month" wording, as displayed |
bestsellerRanks | List of { "rank", "category", "url", "categoryNodeId" } |
isAmazonChoice | Amazon's Choice badge flag |
amazonChoiceText | Badge label, normalized when Amazon renders a long blob |
seller | { "name", "id", "url", "reviewsCount", "averageRating" }, or null when nothing was found |
shipsFrom | Fulfilment source from the buy box |
shippingPrice | Nested { "value", "currency" }; 0.0 when shipping reads as free |
delivery | Primary delivery promise text |
fastestDelivery | Fastest delivery promise text |
condition | New / used condition label |
returnPolicy | Return-policy text |
support | Product-support text |
importantInformation | Ingredients, safety and legal disclaimer block |
sustainabilityFeatures | { "summary", "certifications" } from Climate Pledge blocks |
aPlusContent | { "title", "rawText", "rawImages", "rawVideos", "modules" } |
brandStory | { "title", "image", "items" } brand-story carousel |
productComparison | { "products": [ { "asin", "title", "thumbnail", "price", "stars", "reviewsCount" } ] } |
aiReviewsSummary | { "text", "keywords" } from Amazon's review-insights widget |
url | Canonical product URL on this storefront |
unNormalizedProductUrl | /dp/ URL, carrying ?language= when a language was set |
input | The /dp/ URL this row was fetched from |
visitStoreLink | Brand store link on this storefront |
locationText | Amazon's delivery-location header text |
loadedCountryCode | Delivery country Amazon actually applied to the page |
pageLanguageTag | <html lang> of the served page — proof of which locale Amazon returned |
localeStrategy | The currency mode this row was fetched under |
localeCookieSent | The exact locale cookie string sent, or null when none was sent |
buyBoxDegraded | true when Amazon served an unqualified buy box, so a missing price is a page state and not a parse failure |
hasCorePriceDisplay | true when a core price container was present at all |
fetchOutcome | ok, not_listed, blocked, fetch_failed or parse_error |
httpStatus | HTTP status of the last attempt |
responseBytes | Size of the response body — the signal used to detect a CAPTCHA shell |
usedProxy | Whether the successful attempt went through a proxy |
proxyCountryUsed | Exit country actually used, after any storefront override; null when unproxied |
position | Sequence number of this parsed page within its storefront |
scrapedAt | UTC run timestamp, identical on every row of the run |
error | Present only on rows where no product record could be parsed |
Cross-marketplace pricing and ranking fields
These are the reason this Actor exists. priceValue, priceCurrency and currencyCode are read from the page as served; marketplaceCurrency is what that storefront is supposed to quote in; priceIsNativeCurrency compares the two, so a row where Amazon quietly served a converted price is visible instead of silently wrong. priceUsd, priceRank, cheapestMarketplace, cheapestPriceUsd and priceGapPercent are computed per ASIN across the storefronts of the same run, and priceComparisonBasis records which method produced the ranking. marketplacesCompared and marketplacesPriced tell you how many storefronts were asked versus how many answered with a usable price.
Availability fields
isAvailable is deliberately three-valued. availabilityStatus says why: in_stock, out_of_stock, listed_price_shown, not_listed_in_marketplace, listed_no_buy_box, unknown_degraded_buy_box, unknown_blocked, unknown_fetch_failed or unknown_no_data. The three unknown_* values mean the Actor could not establish availability — a blocked page or a transport failure is never reported as "not sold here", because for cross-market analysis those are opposite conclusions.
Product, rating and rich-content fields
title, brand, description, features, attributes and the image arrays describe the product on that storefront and arrive in that storefront's language. stars, starsBreakdown, reviewsCount, bestsellerRanks and monthlyPurchaseVolume are the demand signals, and they differ per country for the same ASIN — often the most interesting part of a cross-market dataset. aPlusContent, brandStory, productComparison and aiReviewsSummary are the heavy nested blocks; they dominate record size and are largely identical across storefronts, so includeRichContent: false empties them for a lean price dataset.
🤖 Add-on: Need additional Amazon data?
Three companion Actors cover the jobs this one deliberately does not. Amazon Product Scraper By Bestseller & Demand Filter starts from category or product URLs and filters on demand rather than taking a fixed ASIN list. Amazon Today's Deals Scraper With Star Ratings & Deal Badges works the deals surface and returns discount and badge data. Amazon Top Rated Products Scraper runs keyword searches with rating and review-count thresholds.
Why not build this yourself?
Amazon's Product Advertising API exists, but it requires an approved Associates account with qualifying sales, so it is not openly available to anyone who simply wants prices — which leaves scraping. The costs are not in parsing a title.
Locale is the hard part. Amazon obeys the i18n-prefs / lc-main cookie you send it. Send a US cookie to amazon.de and Amazon answers with a converted USD figure and no euro sign anywhere on the page — a US price wearing a German URL. Getting a real German price means the right cookie, a matching Accept-Language, and a check afterwards that the page actually came back in the expected currency. This Actor ships a map of 20 storefronts with their country, native currency, lc-main value and Accept-Language, and reports the cookie it sent on every row.
Currency detection is the second trap. A naive symbol list that puts bare $ first labels a Singapore-dollar price S$193.73 as US dollars. The token table here is sorted longest-first so S$, C$, MX$ and US$ win over the $ they contain, and kr — shared by SEK, NOK and DKK — is resolved from the storefront rather than guessed.
Then there is geography. A residential US exit pointed at a non-US Amazon domain does not fail cleanly; the Actor's source records it answering HTTP 200 with a roughly 3.8 KB CAPTCHA shell on every attempt tested. So you need per-storefront exit countries, a size-aware block detector rather than a status check, session rotation, an unproxied last attempt, backoff, and a delivery-address priming call per storefront. That is infrastructure to run and pay for before a single price is compared.
How to use Amazon ASIN Scraper By Country & Marketplace
The Actor runs on Apify. Start it from the Apify Console or call it through the Apify API.
- Open Amazon ASIN Scraper By Country & Marketplace on Apify and click Try for free
- Paste your ASINs into ASINs to price worldwide — the only required input. Full
/dp/and/gp/product/URLs are accepted and reduced to the ASIN automatically - List the domains you want in Country storefronts to compare, one per line, e.g.
amazon.com,amazon.de,amazon.co.uk. Leave it empty and onlyamazon.comis scraped - Leave Currency mode on Storefront local currency and Proxy exit country on Match each storefront — that pairing is what returns a real local price
- Click Start, then download the dataset as JSON, CSV or Excel
How to scale to bulk ASIN extraction
There is no per-run item cap in this Actor: the row count is exactly your ASIN count multiplied by your storefront count, before any filtering. Two ASINs on three storefronts is six rows; fifty ASINs on ten storefronts is five hundred.
Both asins and marketplaces are lists, and each entry is additionally split on whitespace, commas and semicolons — so a single pasted line holding several ASINs works. Duplicate ASINs are removed before the run, and so are duplicate domains. Pages are fetched concurrently with an internal limit of five requests in flight; that limit is set by the Actor and is not exposed as an input, so size very large jobs by splitting the ASIN list across scheduled runs rather than by tuning concurrency.
What can you do with Amazon cross-marketplace price data?
- 💱 A pricing analyst hunting cross-border gaps reads
priceGapPercentandcheapestMarketplaceperasin, filters to rows wherepriceIsNativeCurrencyistrue, and gets a ranked arbitrage list without a currency spreadsheet. - 🌍 An expansion manager assessing a new country pulls
isAvailableandavailabilityStatusfor their catalogue on the target storefront and treatsnot_listed_in_marketplacerows as the whitespace list — the absences are the finding. - 📦 A reseller sourcing stock compares
priceUsdagainststarsandreviewsCountfor the same ASIN across storefronts, usingshipsFromanddeliveryto weigh landed cost against lead time. - 🏷️ A brand protection lead auditing distribution checks
sellerandshipsFromper storefront for one ASIN, spotting the markets where the buy box is not held by the brand or by Amazon. - 🤖 An AI engineer building a sourcing agent indexes
title,description,featuresandattributesper marketplace into a vector store and keepspriceUsd,currencyCodeandisAvailableas structured filters, so the agent can answer "where is this ASIN cheapest and actually in stock" against live data.
How does Amazon ASIN Scraper By Country & Marketplace handle rate limits and blocking?
Requests go out over Apify Residential proxies by default, with the exit country pinned to each storefront's own country. A desktop User-Agent is picked per request from a five-entry pool, and a full navigation header set is sent alongside the storefront's locale cookie.
Blocking is detected by size, not by status code. Amazon answers a blocked request with HTTP 200 and a small shell, so a 200 response under 120,000 bytes that also lacks a productTitle element is treated as a block, as is any body carrying CAPTCHA or robot-check markers. Each ASIN-storefront cell gets four attempts: the first on a sticky session keyed to the ASIN and domain, later attempts on fresh sessions, with exponential backoff plus jitter between them. If a shell was seen, the final attempt drops the proxy entirely and tries direct. A 404 or 410 short-circuits immediately — that is not a block, it is the ASIN not being listed on that storefront, and it is recorded as such.
There is no CAPTCHA solving. A legacy useCaptchaSolver input is accepted for compatibility and logged as a no-op; nothing solves a challenge. A cell that cannot be recovered is still written to the dataset, with fetchOutcome set to blocked or fetch_failed, isAvailable: null, and no charge.
⚠️ Row counts, caps and known trade-offs
One row per ASIN per marketplace. Not one row per ASIN. This is the single most common misreading of the output, and it drives your row count, your cost and every GROUP BY you write.
skipUnavailableStorefronts silently shortens your dataset. With it on, every row whose isAvailable is not exactly true is dropped before it reaches the dataset — including unknown_blocked and unknown_fetch_failed rows. You lose the distinction between "not sold there" and "we could not tell", and your row count no longer equals ASINs × storefronts. Surviving rows still report marketplacesCompared for the whole run, so that field is your check on what was dropped. Default is off, which keeps the absences visible.
exitCountry is resolved per storefront and overridden when it conflicts. For any storefront in the built-in map, a requested country that is not that storefront's own is replaced with the storefront's country, logged as a warning, and reported in proxyCountryUsed. In practice only MARKETPLACE_MATCH, NO_PROXY, and a country that already matches the storefront are honoured. NO_PROXY applies to the whole run, not to one marketplace.
deliveryPostalCode is one value applied to every storefront. There is no per-marketplace postcode input. The code is primed once per storefront through Amazon's delivery-address endpoint before scraping; if a storefront rejects it, a warning is logged and that storefront is scraped without it. A US ZIP will not be meaningful on amazon.de.
Legacy input keys take priority over the documented ones. The Actor still reads the base Actor's key names, and they win: amazonDomain overrides marketplaces and forces a single-storefront run, language overrides contentLanguage, zipCode overrides deliveryPostalCode, proxyCountry overrides exitCountry, and asinList / productAsins / storefronts are accepted as aliases. If you call the Actor over the API, send only the documented keys.
Silent defaults an API caller will not see in the Console. Omit proxyConfiguration and the run still uses Apify Residential — that is a hardcoded fallback, not "no proxy". Omit marketplaces and you get amazon.com only. Send an unrecognised localeStrategy and it falls back to native with a warning rather than failing.
Domains outside the built-in map still work, with less. A domain the map does not know is fetched with no locale cookie and no pinned exit country, and returns marketplaceCountry: null, marketplaceCurrency: null and priceIsNativeCurrency: false.
Field presence differs between full and error rows. A row where no product record could be parsed carries a small key set plus an error key — the product fields are absent, not null. Code reading rows should use .get() rather than indexing.
Preserved upstream quirks. breadCrumbs keeps its mid-word capital, unNormalizedProductUrl and the generic input key are inherited names, originalAsin duplicates asin, url on a full row ends in a trailing empty ?smid= while an error row's url is a plain /dp/ link, and seller.url is resolved against amazon.com even on other storefronts. seller.averageRating and seller.reviewsCount come from an English-language pattern, so they are usually null on non-English storefronts.
Malformed ASINs are dropped, not reported. An entry that is neither a ten-character alphanumeric token nor a recognisable Amazon product URL is logged and skipped, and produces no row at all. If nothing valid survives, the run fails immediately with Input 'asins' is required and must contain at least one valid ASIN.
⬇️ Input
Ten parameters, one of them required. Everything else has a working default.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
asins | Yes | array | ASINs to price, one per line. Full /dp/, /gp/product/, /gp/aw/d/ and /product/ URLs are accepted and reduced to the ASIN. Entries are also split on whitespace, commas and semicolons, uppercased and deduplicated. | ["B07GBZ4Q68", "B0CJ4V4TRP"] |
marketplaces | No | array | Storefront domains to price each ASIN on, one per line. Protocol and www. are stripped. Empty means amazon.com only. Prefilled with three domains in the Console. | ["amazon.com", "amazon.de", "amazon.co.uk"] |
contentLanguage | No | string | Page language override, sent as Amazon's ?language= parameter. One of 21 values: "" (storefront native) plus en, en_US, en_GB, de, fr, es, it, nl, pl, pt, pt_BR, sv, tr, cs, da, ja, zh_CN, zh_TW, hi, ar. Default "". | "" |
localeStrategy | No | string | Currency mode. native sends each storefront its own locale cookie, forceUsd sends a US cookie everywhere so Amazon converts, noLocaleCookie sends none and lets Amazon decide from the exit IP. Default "native". | "native" |
convertPricesToUsd | No | boolean | Fetch reference exchange rates once per run and fill priceUsd, fxRateToUsd and fxRatesDate. Default true. | true |
skipUnavailableStorefronts | No | boolean | Drop every row whose isAvailable is not true before writing it. Default false. | false |
includeRichContent | No | boolean | Keep aPlusContent, brandStory, productComparison, aiReviewsSummary, highResolutionImages and galleryThumbnails populated. Set false and the keys stay present but emptied. Default true. | true |
deliveryPostalCode | No | string | One postal code, primed on every storefront through Amazon's delivery-address cookie before scraping. Empty uses each storefront's default location. Default "". | "10115" |
exitCountry | No | string | Proxy exit country. One of MARKETPLACE_MATCH, NO_PROXY, US, GB, DE, FR, ES, IT, CA, AU, JP, IN, BR, MX, NL, PL, TR, SE, AE, SG. A value that conflicts with a known storefront is replaced with that storefront's own country. Default "MARKETPLACE_MATCH". | "MARKETPLACE_MATCH" |
proxyConfiguration | No | object | Apify Proxy settings. Overrides exitCountry; with your own proxyUrls the geo decision is entirely yours and no country correction is applied. Omitting it still uses Apify Residential. Prefilled {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}. | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
Storefronts with full locale mapping. Twenty domains have a country, native currency, lc-main cookie value and Accept-Language in the Actor's built-in map. Any other Amazon domain is still fetched, with reduced metadata.
| Domain | Country | Native currency | Domain | Country | Native currency |
|---|---|---|---|---|---|
amazon.com | US | USD | amazon.ca | CA | CAD |
amazon.co.uk | GB | GBP | amazon.com.mx | MX | MXN |
amazon.de | DE | EUR | amazon.com.br | BR | BRL |
amazon.fr | FR | EUR | amazon.co.jp | JP | JPY |
amazon.it | IT | EUR | amazon.in | IN | INR |
amazon.es | ES | EUR | amazon.com.au | AU | AUD |
amazon.nl | NL | EUR | amazon.sg | SG | SGD |
amazon.ie | IE | EUR | amazon.com.tr | TR | TRY |
amazon.se | SE | SEK | amazon.ae | AE | AED |
amazon.pl | PL | PLN | amazon.sa | SA | SAR |
How localeStrategy changes behaviour, option by option.
native(default) — each storefront receivesi18n-prefs=<its currency>; lc-main=<its lc-main>; sp-cdn=L5Z9:<its country>; x-cdn=Cloudfrontand that storefront's ownAccept-Language. This is the pairing that makesamazon.dequote euros. AcontentLanguagepick does not change the cookie or the header in this mode — it only adds?language=to the URL, which switches page text while leaving the currency signal intact. A domain outside the map gets no cookie.forceUsd— every storefront receivesi18n-prefs=USD; lc-main=en_US; sp-cdn=L5Z9:US; x-cdn=Cloudfront, so Amazon performs its own conversion and non-US storefronts answer in USD. Useful only when you specifically want Amazon's conversion;priceIsNativeCurrencyreadsfalseon those rows.noLocaleCookie— no locale cookie at all; Amazon decides from the exit IP.Accept-Languagefollows yourcontentLanguageif you set one, otherwise the storefront's own.- Any other value is logged as unknown and treated as
native.
Where the USD figures come from. With convertPricesToUsd on, the Actor makes one request at the start of the run to a keyless exchange-rate endpoint that the source identifies as an ECB reference feed (api.frankfurter.app, base USD). That single rate set is reused for every row in the run — rates are not refetched per storefront, per ASIN or per row. fxRateToUsd is the rate applied, and fxRatesDate is the date the feed itself reports for that set, which can be earlier than your run date; read it rather than assuming the number is intraday. priceUsd is priceValue divided by fxRateToUsd, rounded to four decimals.
Nothing is ever overwritten: priceValue, priceCurrency, currencyCode and marketplaceCurrency always keep the storefront's own figures, and priceUsd is an added column. If the feed is unreachable, returns a non-200, or publishes no rate for a row's currency, then priceUsd and fxRateToUsd come back null and the ranking falls back to same-currency storefronts only — the Actor never substitutes an invented rate. Treat priceUsd as a ranking aid, not a quotation: it is a daily reference rate, not the rate Amazon, a payment processor or a card issuer would apply, and the Actor performs no verification of the feed beyond the date the feed itself reports.
Example input
{"asins": ["B07GBZ4Q68","https://www.amazon.com/dp/B0CJ4V4TRP"],"marketplaces": ["amazon.com","amazon.de","amazon.co.uk"],"contentLanguage": "","localeStrategy": "native","convertPricesToUsd": true,"skipUnavailableStorefronts": false,"includeRichContent": false,"deliveryPostalCode": "10115","exitCountry": "MARKETPLACE_MATCH","proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
That input produces six rows: two ASINs across three storefronts.
⬆️ Output
Every ASIN-storefront pair is one dataset row. A parsed row carries the same 85 keys run after run, nested objects keep a fixed shape, and unfound values come back as null or as an empty list rather than under a renamed key. Export as JSON, CSV or Excel, or read the dataset through the Apify API. The run also writes an OUTPUT record to the default key-value store — the same rows nested as { asin: { marketplace: row } } — which is convenient when you want the matrix rather than a flat table.
Example output
{"asin": "B07GBZ4Q68","originalAsin": "B07GBZ4Q68","marketplace": "amazon.de","marketplaceCountry": "DE","marketplaceCurrency": "EUR","priceValue": 35.29,"priceCurrency": "€","currencyCode": "EUR","priceIsNativeCurrency": true,"price": { "value": 35.29, "currency": "€" },"listPrice": { "value": 44.99, "currency": "€" },"priceRange": null,"priceUsd": 41.0731,"fxRateToUsd": 0.8592,"fxRatesDate": "2026-07-24","priceComparisonBasis": "usd_ecb_reference","priceRank": 1,"isCheapestMarketplace": true,"cheapestMarketplace": "amazon.de","cheapestPriceUsd": 41.0731,"priceGapPercent": 0.0,"marketplacesCompared": 3,"marketplacesPriced": 3,"isAvailable": true,"availabilityStatus": "in_stock","inStock": true,"inStockText": "Auf Lager","title": "Logitech G502 HERO High Performance Gaming-Maus mit HERO 25K DPI Sensor, RGB","brand": "Logitech G","author": null,"description": "Der HERO 25K Sensor ist der leistungsstärkste Gaming-Sensor von Logitech.","bookDescription": null,"features": ["HERO 25K Sensor mit bis zu 25.600 DPI","11 programmierbare Tasten","Anpassbares Gewichtssystem mit fünf 3,6-g-Gewichten"],"attributes": [{ "key": "Marke", "value": "Logitech G" },{ "key": "Verbindungstechnologie", "value": "Kabelgebunden" },{ "key": "Artikelgewicht", "value": "121 g" }],"productOverview": [{ "key": "Marke", "value": "Logitech G" },{ "key": "Farbe", "value": "Schwarz" }],"breadCrumbs": "Computer & Zubehör > Zubehör > Mäuse","thumbnailImage": "https://m.media-amazon.com/images/I/61mpMH5TzkL._AC_SL1500_.jpg","galleryThumbnails": [],"highResolutionImages": [],"videosCount": 2,"variantAsins": ["B07GBZ4Q68", "B07GCKQD77"],"variantDetails": [{"name": "Schwarz","thumbnail": "https://m.media-amazon.com/images/I/31Y4a2mS9lL._SS36_.jpg","images": ["https://m.media-amazon.com/images/I/31Y4a2mS9lL._SS36_.jpg"],"asin": "B07GCKQD77","price": { "value": 39.99, "currency": null }}],"variantAttributes": [{ "key": "Farbe", "value": "Schwarz" }],"stars": 4.6,"starsBreakdown": { "5star": 0.81, "4star": 0.11, "3star": 0.04, "2star": 0.01, "1star": 0.03 },"reviewsCount": 55283,"hasReviews": true,"reviewsLink": "https://www.amazon.de/product-reviews/B07GBZ4Q68","answeredQuestions": null,"monthlyPurchaseVolume": "1.000+ Mal im letzten Monat gekauft","bestsellerRanks": [{"rank": 3,"category": "PC-Mäuse","url": "https://www.amazon.de/gp/bestsellers/computers/430168031","categoryNodeId": "430168031"}],"isAmazonChoice": true,"amazonChoiceText": "Amazon's Choice for \"gaming maus\"","seller": {"name": "Amazon","id": null,"url": "https://www.amazon.com","reviewsCount": null,"averageRating": null},"shipsFrom": "Amazon","shippingPrice": { "value": 0.0, "currency": "€" },"delivery": "Donnerstag, 30. Juli","fastestDelivery": "Mittwoch, 29. Juli","condition": "New","returnPolicy": "Rückgabe innerhalb von 30 Tagen ab Erhalt","support": null,"importantInformation": null,"sustainabilityFeatures": null,"aPlusContent": null,"brandStory": null,"productComparison": null,"aiReviewsSummary": null,"url": "https://www.amazon.de/gp/product/B07GBZ4Q68?smid=","unNormalizedProductUrl": "https://www.amazon.de/dp/B07GBZ4Q68","input": "https://www.amazon.de/dp/B07GBZ4Q68","visitStoreLink": "https://www.amazon.de/stores/LogitechG/page/1234ABCD","locationText": "Lieferung nach 10115","loadedCountryCode": "DE","pageLanguageTag": "de-de","localeStrategy": "native","localeCookieSent": "i18n-prefs=EUR; lc-main=de_DE; sp-cdn=L5Z9:DE; x-cdn=Cloudfront","buyBoxDegraded": false,"hasCorePriceDisplay": true,"fetchOutcome": "ok","httpStatus": 200,"responseBytes": 1728431,"usedProxy": true,"proxyCountryUsed": "DE","position": 1,"scrapedAt": "2026-07-25T09:14:02Z"}
The rich-content keys read null above because the example input set includeRichContent: false. With it on, aPlusContent returns { "title", "rawText", "rawImages", "rawVideos", "modules" }, brandStory returns { "title", "image", "items" }, productComparison returns { "products": [...] }, and aiReviewsSummary returns { "text", "keywords" }.
Rows where the product could not be read
When a storefront returns 404/410, a block, a transport failure or an unparseable page, the row is still written — with error present and the product fields absent rather than nulled:
{"asin": "B0CJ4V4TRP","originalAsin": "B0CJ4V4TRP","marketplace": "amazon.co.uk","marketplaceCountry": "GB","marketplaceCurrency": "GBP","priceValue": null,"priceCurrency": null,"currencyCode": null,"price": null,"title": null,"url": "https://www.amazon.co.uk/dp/B0CJ4V4TRP","error": "not_listed","isAvailable": false,"availabilityStatus": "not_listed_in_marketplace","fetchOutcome": "not_listed","httpStatus": 404,"responseBytes": 0,"usedProxy": true,"proxyCountryUsed": "GB","scrapedAt": "2026-07-25T09:14:02Z","priceUsd": null,"fxRateToUsd": null,"fxRatesDate": "2026-07-24","priceComparisonBasis": "usd_ecb_reference","priceRank": null,"priceGapPercent": null,"isCheapestMarketplace": null,"cheapestMarketplace": "amazon.de","cheapestPriceUsd": 41.0731,"marketplacesCompared": 3,"marketplacesPriced": 2}
Charged and uncharged rows. The Actor bills a row_result event per row and does not bill rows it could not read. A row is charged when fetchOutcome is ok or not_listed — a confirmed absence is a real answer, so it is billed like any other row. Rows with fetchOutcome of blocked, fetch_failed or parse_error are pushed to the dataset uncharged. There is no separate error-marker field beyond fetchOutcome and the error key, so filter on that:
charged = [r for r in rows if r["fetchOutcome"] in ("ok", "not_listed")]free = [r for r in rows if r["fetchOutcome"] not in ("ok", "not_listed")]
How does it work?
Each ASIN-storefront pair is one HTTP request to https://www.<domain>/dp/<ASIN>, sent through an Apify Residential exit in that storefront's own country, carrying that storefront's locale cookie and Accept-Language plus a desktop browser header set. When you supply a postal code, the Actor first walks Amazon's delivery-address flow on each storefront to collect a location cookie and replays it on the product requests.
Responses are validated before parsing: a body smaller than a real product page, or one containing CAPTCHA markers, is treated as a block and triggers a retry on a fresh session, with a final attempt made without any proxy. Parsing then reads both the rendered page and the JSON blocks Amazon embeds in it — image sets, variant maps, A+ video URLs — using several candidate selectors per field and falling back rather than failing, so a layout change degrades one field instead of the row. Prices are only accepted from inside the product's own buy-box containers, never from a recommendation carousel, so a neighbouring product's price cannot be reported as this ASIN's.
Only publicly visible product data is collected. Field names and types are held stable across Actor updates, so an integration reading priceValue and cheapestMarketplace keeps working when Amazon changes its front end.
Integrations
Amazon ASIN Scraper By Country & Marketplace is an Apify Actor, so it works with anything that can call the Apify API or consume a dataset — schedules, webhooks, storage exports and no-code automation platforms.
Calling it from Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/amazon-asin-scraper-by-country-marketplace").call(run_input={"asins": ["B07GBZ4Q68", "B0CJ4V4TRP"],"marketplaces": ["amazon.com", "amazon.de", "amazon.co.uk"],"localeStrategy": "native","convertPricesToUsd": True,"includeRichContent": False,"exitCountry": "MARKETPLACE_MATCH",})rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())for r in sorted(rows, key=lambda x: (x["asin"], x.get("priceRank") or 99)):print(r["asin"], r["marketplace"], r.get("priceValue"), r.get("currencyCode"),r.get("priceUsd"), r.get("priceGapPercent"), r["availabilityStatus"])
Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.
No-code tools (n8n, Make, Zapier)
In n8n, use the Apify node — or an HTTP Request node pointed at the Actor's run endpoint with your token — and pass the same JSON input shown above. In Make, use the Apify module and map the dataset rows straight into a Google Sheets or Airtable step, keying on asin plus marketplace so a repeat run updates rather than duplicates. Both handle scheduling, so a daily cross-market price sweep needs no code at all.
Is it legal to scrape Amazon product listings?
Scraping publicly listed product data is broadly treated as permissible where the data is accessible without authentication, and this Actor collects only what an anonymous visitor already sees on a country's product page — no account, no login, no session.
Prices, availability, titles, ratings and bestseller ranks are commercial business records, not personal data. The personal-data regimes that govern profile scraping — GDPR and its equivalents — do not attach to this output the way they would to a scraper that collects people. The obligations that do apply are contractual and database-related: Amazon's terms of service restrict automated access, which is a civil and contractual matter rather than a criminal one, and local database or unfair-competition rules can apply if you systematically reproduce a substantial part of Amazon's catalogue as a competing listing.
One narrow exception is worth naming: seller.name carries the buy-box merchant's trading name, and a small independent trader's trading name is sometimes their personal name. If you store that field at scale, treat it accordingly.
Consult legal counsel before republishing extracted listings as a competing catalogue, or before reselling the data as a standalone product.
❓ Frequently asked questions
What Amazon fields does Amazon ASIN Scraper By Country & Marketplace return?
The five that matter most for cross-market work are priceValue, currencyCode, priceUsd, cheapestMarketplace and isAvailable. A parsed row carries 85 keys in total, including priceRank, priceGapPercent, priceIsNativeCurrency, stars, reviewsCount, bestsellerRanks and the full product record — see the data fields table above.
Does it require an Amazon account or login?
No. No Amazon account, no login, no cookie of your own, and no Product Advertising API approval. The only credential you need is your Apify token.
How many rows will one run produce, and can I compare many ASINs at once?
Yes, and the arithmetic is exact: one row per ASIN per marketplace. Ten ASINs across five storefronts is fifty rows. asins and marketplaces are both lists with no Actor-imposed cap, and entries are split on whitespace, commas and semicolons then deduplicated, so a pasted block works. The only thing that changes the count is skipUnavailableStorefronts, which removes rows.
What happens if an ASIN does not exist in a given marketplace, or is unavailable there?
You still get a row, and the two cases are distinguishable. A storefront that answers 404 or 410 produces isAvailable: false with availabilityStatus: "not_listed_in_marketplace", fetchOutcome: "not_listed" and an error key of "not_listed" — the ASIN is simply not sold in that country. An ASIN that is listed but out of stock produces isAvailable: false with availabilityStatus: "out_of_stock" and a full product record. A page that was blocked or failed in transport produces isAvailable: null with an unknown_* status and is not charged — never false, because "we could not tell" and "not sold here" are opposite conclusions. Filter on availabilityStatus, not on a null price.
Where do the USD prices come from, and can I trust them?
From one request per run to a keyless exchange-rate endpoint that the Actor's source identifies as an ECB reference feed, with USD as the base. The whole run shares that single rate set; fxRateToUsd is the rate applied to a row, and fxRatesDate is the date the feed reports for it, which may be earlier than your run. Trust it for ranking storefronts against each other, which is what it exists for. Do not treat it as a quotation — it is a daily reference rate, not Amazon's conversion and not a card issuer's. The storefront's own priceValue, priceCurrency and currencyCode are always preserved alongside it, and if the feed is unreachable or carries no rate for that currency, priceUsd and fxRateToUsd are null and the ranking falls back to same-currency comparison — an invented rate is never substituted. priceComparisonBasis on every row tells you which of those happened.
Why is a non-US price coming back in USD?
Check localeStrategy and priceIsNativeCurrency. Under forceUsd, Amazon is asked to convert and will answer non-US storefronts in USD by design. Under native, each storefront gets its own currency cookie; if priceIsNativeCurrency is still false, compare currencyCode with marketplaceCurrency, then read localeCookieSent and pageLanguageTag on that row to see exactly what was sent and what Amazon served back.
Does it work with Claude, ChatGPT and other AI agent tools?
Yes. It is callable as a standard HTTP endpoint through the Apify API, so any agent framework that can make a request — LangChain, CrewAI, n8n or a custom tool definition — can invoke it and receive typed JSON directly.
How does it compare to other Amazon ASIN scrapers?
Checked on the Apify Store on 25 July 2026. junglee/amazon-asins-scraper is the most-used ASIN Actor by a wide margin and documents ASIN input with a store selector plus a clear error-item contract and error-code table; its README describes one Amazon store per run, and per-row cross-marketplace comparison is not documented. jaybird/amazon-product-data-scraper takes product URLs from any Amazon domain, returns one record per URL and documents an includeNotFound switch for dead listings; cross-storefront ranking is not documented. viralanalyzer/amazon-multi-country is the closest in intent — it documents seven marketplaces with locale-correct decimal parsing and per-country Prime filters — but it is keyword-search or URL driven, and a per-row cheapest-marketplace or USD-normalised rank is not documented. Where this Actor differs is that the comparison is the output: one ASIN list fans out across your storefronts, and every row carries priceRank, cheapestMarketplace, priceGapPercent, priceIsNativeCurrency, priceComparisonBasis and a three-valued isAvailable. Capabilities not stated in a competitor's README are described as "not documented" rather than assumed absent.
Does it return data in a format LLMs can use directly?
Yes. Typed, normalized JSON with the same key names on every run — no HTML, no selectors. Pass a row straight into a context window, index it into a vector store, or hand it to an agent tool. The OUTPUT key-value record additionally gives you the ASIN-by-marketplace matrix if that shape suits your prompt better than a flat table.
What happens when Amazon changes its layout or anti-bot system?
The Actor is maintained, and it is built to degrade rather than break: each field is read through a chain of candidate selectors with Amazon's embedded page data as a fallback, so a redesign usually costs one field rather than the row. Blocking is detected by response size instead of status code, which is what catches Amazon's HTTP 200 CAPTCHA shells. Your field names and types do not change on your end.
Can I use it without managing proxies or browser infrastructure?
Yes. Leave proxyConfiguration and exitCountry alone and the Actor runs on Apify Residential with the exit country pinned to each storefront, creates and rotates its own sessions, retries with backoff, and makes a final unproxied attempt when it has seen a block. There is no browser to run — requests are plain HTTP. There is no CAPTCHA solver, and the legacy useCaptchaSolver input is a logged no-op.
Which fields work best for AI training data and RAG indexing?
For RAG: title, description, features and attributes carry the most descriptive text per row and chunk cleanly, with marketplace and pageLanguageTag as the locale dimension so a retrieved chunk stays attributable to a country. For training data: priceValue, priceUsd, currencyCode, priceRank, priceGapPercent, stars, reviewsCount and isAvailable are the most structurally consistent fields across records. All of them arrive as typed primitives, so no normalization pass is needed before indexing.
🔗 Related scrapers
| Scraper Name | What it extracts |
|---|---|
| Amazon Product Scraper By Bestseller & Demand Filter | Products from category or product URLs, filtered on monthly purchases and bestseller rank |
| Amazon Today's Deals Scraper With Star Ratings & Deal Badges | Today's Deals listings with deal badges, savings and star histograms |
| Amazon Top Rated Products Scraper | Keyword-search results filtered by minimum rating and review count, with review insights |
| Alibaba Scraper | B2B product listings with prices, MOQ and supplier trust data |
Pick by the job: this Actor when you already know the ASINs and need them priced country by country; the bestseller and demand filter when you are still discovering which products matter; Today's Deals when the discount surface is the target; Top Rated when you are searching by keyword and thresholding on ratings.
💬 Your feedback
Found a bug, or need a storefront that is not in the built-in locale map? Open an issue on the Actor's Issues tab and it will be looked at. Reports that include the ASIN, the domain, and the fetchOutcome and proxyCountryUsed values from the affected row are the fastest to act on.