Amazon ASIN Scraper By Country & Marketplace avatar

Amazon ASIN Scraper By Country & Marketplace

Pricing

$19.99/month + usage

Go to Apify Store
Amazon ASIN Scraper By Country & Marketplace

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

Scraper Engine

Maintained by Community

Actor stats

0

Bookmarked

25

Total users

0

Monthly active users

5 days ago

Last modified

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 CategoryPublicly AvailableBehind 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 identityAmazon serves logged-out shells on review surfaces
Buyer identity, order and payment historyAccount
Seller inventory, fees, internal sales figuresSeller Central
Historical price series, and Amazon's own cross-marketplace FX rateAmazon 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 NameDescription
asinThe ASIN, uppercased and normalized from your input
originalAsinSame value, kept for parity with single-marketplace Amazon Actors
marketplaceStorefront domain this row was priced on, e.g. amazon.de
marketplaceCountryISO-3166 alpha-2 country of the storefront; null for a domain outside the built-in map
marketplaceCurrencyISO-4217 currency the storefront natively quotes in, from the built-in map
priceValueBuy-box price as a number, in the storefront's own currency
priceCurrencyDisplay symbol detected on the page (, £, S$, , …)
currencyCodeISO-4217 code detected on the page; null when the page showed no currency token
priceIsNativeCurrencytrue when currencyCode matches marketplaceCurrency — the flag that catches an Amazon-converted price
priceNested { "value", "currency" } object for the same buy-box price
listPriceNested { "value", "currency" } strike-through price, null when equal to price
priceRangePrice range string when Amazon shows a range instead of one price
priceUsdpriceValue converted to USD for ranking; null when no rate was available
fxRateToUsdThe rate used for this row's currency, as returned by the reference feed
fxRatesDateDate the feed itself reports for that rate set
priceComparisonBasisHow this ASIN's storefronts were ranked: usd_ecb_reference, usd_ecb_reference_partial, same_currency or none
priceRank1-based cheapest-first rank of this storefront for this ASIN; null if unpriced
isCheapestMarketplacetrue on the rank-1 row, null when this row was not ranked
cheapestMarketplaceDomain of the cheapest storefront for this ASIN in this run
cheapestPriceUsdpriceUsd of that cheapest row; null when the ranking ran without FX
priceGapPercentHow much more expensive this row is than the cheapest, in percent
marketplacesComparedNumber of storefronts configured for the run
marketplacesPricedNumber of those storefronts that produced a comparable price
isAvailabletrue / false / nullnull means undetermined, not unavailable
availabilityStatusReason behind isAvailable; one of nine values listed below
inStockRaw stock boolean parsed from Amazon's availability block
inStockTextAmazon's own availability wording, in the storefront's language
titleProduct title as rendered on that storefront
brandBrand or byline name
authorAuthor, for book and media listings
descriptionProduct description text
bookDescriptionBook/editorial description, populated only when description is empty
features"About this item" bullet list
attributesSpec and detail rows as { "key", "value" } pairs
productOverviewAmazon's product-overview table as { "key", "value" } pairs
breadCrumbsCategory path joined with >
thumbnailImageMain product image URL
galleryThumbnailsGallery thumbnail URLs
highResolutionImagesFull-resolution image URLs
videosCountNumber of product videos detected
variantAsinsSibling variant ASINs found on the page
variantDetailsVariants as { "name", "thumbnail", "images", "asin", "price" }
variantAttributesSelected variant dimensions as { "key", "value" } pairs
starsAverage star rating
starsBreakdownRating histogram keyed 5star1star, values as 0–1 fractions
reviewsCountNumber of ratings
hasReviewstrue when reviewsCount is above zero
reviewsLinkConstructed link to the storefront's review page
answeredQuestionsAnswered-questions count when Amazon renders one
monthlyPurchaseVolumeAmazon's "N bought in past month" wording, as displayed
bestsellerRanksList of { "rank", "category", "url", "categoryNodeId" }
isAmazonChoiceAmazon's Choice badge flag
amazonChoiceTextBadge label, normalized when Amazon renders a long blob
seller{ "name", "id", "url", "reviewsCount", "averageRating" }, or null when nothing was found
shipsFromFulfilment source from the buy box
shippingPriceNested { "value", "currency" }; 0.0 when shipping reads as free
deliveryPrimary delivery promise text
fastestDeliveryFastest delivery promise text
conditionNew / used condition label
returnPolicyReturn-policy text
supportProduct-support text
importantInformationIngredients, 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
urlCanonical product URL on this storefront
unNormalizedProductUrl/dp/ URL, carrying ?language= when a language was set
inputThe /dp/ URL this row was fetched from
visitStoreLinkBrand store link on this storefront
locationTextAmazon's delivery-location header text
loadedCountryCodeDelivery country Amazon actually applied to the page
pageLanguageTag<html lang> of the served page — proof of which locale Amazon returned
localeStrategyThe currency mode this row was fetched under
localeCookieSentThe exact locale cookie string sent, or null when none was sent
buyBoxDegradedtrue when Amazon served an unqualified buy box, so a missing price is a page state and not a parse failure
hasCorePriceDisplaytrue when a core price container was present at all
fetchOutcomeok, not_listed, blocked, fetch_failed or parse_error
httpStatusHTTP status of the last attempt
responseBytesSize of the response body — the signal used to detect a CAPTCHA shell
usedProxyWhether the successful attempt went through a proxy
proxyCountryUsedExit country actually used, after any storefront override; null when unproxied
positionSequence number of this parsed page within its storefront
scrapedAtUTC run timestamp, identical on every row of the run
errorPresent 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.

  1. Open Amazon ASIN Scraper By Country & Marketplace on Apify and click Try for free
  2. 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
  3. 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 only amazon.com is scraped
  4. Leave Currency mode on Storefront local currency and Proxy exit country on Match each storefront — that pairing is what returns a real local price
  5. 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 priceGapPercent and cheapestMarketplace per asin, filters to rows where priceIsNativeCurrency is true, and gets a ranked arbitrage list without a currency spreadsheet.
  • 🌍 An expansion manager assessing a new country pulls isAvailable and availabilityStatus for their catalogue on the target storefront and treats not_listed_in_marketplace rows as the whitespace list — the absences are the finding.
  • 📦 A reseller sourcing stock compares priceUsd against stars and reviewsCount for the same ASIN across storefronts, using shipsFrom and delivery to weigh landed cost against lead time.
  • 🏷️ A brand protection lead auditing distribution checks seller and shipsFrom per 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, features and attributes per marketplace into a vector store and keeps priceUsd, currencyCode and isAvailable as 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.

ParameterRequiredTypeDescriptionExample Value
asinsYesarrayASINs 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"]
marketplacesNoarrayStorefront 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"]
contentLanguageNostringPage 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 "".""
localeStrategyNostringCurrency 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"
convertPricesToUsdNobooleanFetch reference exchange rates once per run and fill priceUsd, fxRateToUsd and fxRatesDate. Default true.true
skipUnavailableStorefrontsNobooleanDrop every row whose isAvailable is not true before writing it. Default false.false
includeRichContentNobooleanKeep aPlusContent, brandStory, productComparison, aiReviewsSummary, highResolutionImages and galleryThumbnails populated. Set false and the keys stay present but emptied. Default true.true
deliveryPostalCodeNostringOne postal code, primed on every storefront through Amazon's delivery-address cookie before scraping. Empty uses each storefront's default location. Default ""."10115"
exitCountryNostringProxy 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"
proxyConfigurationNoobjectApify 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.

DomainCountryNative currencyDomainCountryNative currency
amazon.comUSUSDamazon.caCACAD
amazon.co.ukGBGBPamazon.com.mxMXMXN
amazon.deDEEURamazon.com.brBRBRL
amazon.frFREURamazon.co.jpJPJPY
amazon.itITEURamazon.inININR
amazon.esESEURamazon.com.auAUAUD
amazon.nlNLEURamazon.sgSGSGD
amazon.ieIEEURamazon.com.trTRTRY
amazon.seSESEKamazon.aeAEAED
amazon.plPLPLNamazon.saSASAR

How localeStrategy changes behaviour, option by option.

  • native (default) — each storefront receives i18n-prefs=<its currency>; lc-main=<its lc-main>; sp-cdn=L5Z9:<its country>; x-cdn=Cloudfront and that storefront's own Accept-Language. This is the pairing that makes amazon.de quote euros. A contentLanguage pick 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 receives i18n-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; priceIsNativeCurrency reads false on those rows.
  • noLocaleCookie — no locale cookie at all; Amazon decides from the exit IP. Accept-Language follows your contentLanguage if 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 ApifyClient
client = 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.

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.

Scraper NameWhat it extracts
Amazon Product Scraper By Bestseller & Demand FilterProducts from category or product URLs, filtered on monthly purchases and bestseller rank
Amazon Today's Deals Scraper With Star Ratings & Deal BadgesToday's Deals listings with deal badges, savings and star histograms
Amazon Top Rated Products ScraperKeyword-search results filtered by minimum rating and review count, with review insights
Alibaba ScraperB2B 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.