# Amazon ASIN Scraper With Every Size, Color & Variant (`api-empire/amazon-asin-scraper`) Actor

Scrape Amazon ASINs with every available size, color, style, and product variant. Capture structured product data, prices, availability, SKUs, and variant details for catalog research, competitor analysis, pricing intelligence, and e-commerce insights.

- **URL**: https://apify.com/api-empire/amazon-asin-scraper.md
- **Developed by:** [API Empire](https://apify.com/api-empire) (community)
- **Categories:** Agents, E-commerce, Lead generation
- **Stats:** 27 total users, 6 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Amazon ASIN Scraper — Variants, Spec Tables and Media Inventory

Amazon ASIN Scraper turns a list of ASINs into complete catalogue records: the parent product, every child variant with its size, colour, style and pattern values, the full specification and product-details tables, every gallery image with the resolution Amazon itself states for it, product video URLs, and the rendered sold-by, ships-from, delivery and stock sentences. Every row is typed, normalized JSON with a fixed key set — no HTML, no selectors, no parsing. Paste ASINs, press Start, and export the whole variation family as JSON, CSV or Excel.

### ⚠️ Variant rows carry no per-child price or stock

This is the one limitation worth reading before your first run, because it is the thing an "every size and colour" scraper is most often assumed to do.

The Actor fetches **one page per input ASIN** — the parent detail page — and reads Amazon's twister payload off it. That payload states each child ASIN and its dimension values. It does **not** state each child's price, stock level or delivery date. So every entry in `variationMatrix`, and every row emitted by `variantsAsSeparateRows`, carries only what the parent page actually said about that child: `asin`, its dimension values, a joined `label`, `isSelected` and a product URL. Nothing is copied down from the parent, because a copied price would be wrong for most children.

Two further things to know:

- **Child URLs are always built on `amazon.com`.** `variationMatrix[].url` and the variant row's `url` are composed as `https://www.amazon.com/dp/<ASIN>` regardless of the `marketplaceDomain` you set. On a non-US storefront, rewrite the host yourself.
- **Books are the exception.** `bookVariations` comes from the format-swatch widget, where Amazon prints the price on each swatch — so those entries do carry a `priceText`.

If you need a real price and stock figure per child, take the ASINs out of `variationMatrix` and feed them back in as a second run. Each child then becomes its own product row, with its own `price`, `inStock`, `warehouseAvailability` and `deliveryDateText`, and still returns the whole family it belongs to.

### What is Amazon ASIN Scraper With Every Size, Color & Variant?

Amazon ASIN Scraper With Every Size, Color & Variant is an Apify Actor that takes ASINs and returns a full catalogue record for each one. It is record-driven, not search-driven: you supply the identifiers, and every input ASIN produces exactly one product row plus, optionally, one row per child variant.

No Amazon account, login or cookie is required. Every field it returns is visible to an anonymous visitor on the public detail page. The only credential you need is your Apify token.

- Scrape the **product record** for a parent or child ASIN — title, brand, price, ratings, description, features, breadcrumbs and bestseller ranks
- Scrape the **variation matrix** — parent ASIN, every dimension with its full value list, every child ASIN with its size, colour, style and pattern values, and which one Amazon is showing
- Scrape the **specification and product-details tables** as complete name/value lists, in both the table and bullet-list layouts Amazon uses
- Scrape the **media inventory** — every gallery image with its hi-res, large and thumbnail URLs and Amazon's own stated width x height, plus product video URLs, titles and durations
- Scrape the **rendered fulfilment strings** — sold by, ships from, delivery date, the "Only N left in stock" sentence and the "N bought in past month" badge, verbatim
- Export as JSON, CSV or Excel. No proxy management, no parsing

Nothing in the output is calculated. There is no fee schedule, no margin, no ROI and no sales estimate in this build — every value is a string or number Amazon rendered on the page or embedded in its own JSON, or a direct reformat of one. Missing data comes back as `null` or an empty list, never as an invented value.

### What data does Amazon ASIN Scraper collect?

Four entity types come out of a single page fetch: the product itself, its child variants, its specification tables, and its media inventory — plus the fulfilment strings Amazon printed in the buy box.

| Data Type | Key Fields | JSON Field Names |
| ----- | ----- | ----- |
| Product (parent ASIN) | Title, brand, price, list price, rating, review count, stock, breadcrumbs, bestseller ranks | `asin`, `title`, `brand`, `price`, `listPrice`, `stars`, `reviewsCount`, `inStock`, `breadCrumbs`, `bestsellerRanks` |
| Child variant (size / colour / style / pattern) | Child ASIN, dimension values, joined label, selected flag, parent identity | `variationMatrix`, `variationDimensions`, `variationDimensionNames`, `variationCount`, `selectedVariation`, `parentAsin`, `hasVariations`, `variationSource` |
| Specification table | Technical spec rows and the Product details block, as name/value pairs | `productSpecification`, `productDetails`, `attributes`, `productOverview` |
| Media inventory | Every gallery image with hi-res / large / thumbnail URLs and Amazon's stated resolution, plus product videos | `imageInventory`, `imageCount`, `imageResolutions`, `videoInventory`, `videoCount` |
| Fulfilment strings | Sold by, ships from, delivery text, stock sentence, bought-in-past-month badge | `soldBy`, `fulfilledBy`, `deliveryMessage`, `deliveryDateText`, `fastestDeliveryText`, `warehouseAvailability`, `pastSales` |
| Book / media editions | Format name, edition ASIN, printed price text, selected flag | `bookVariations` |
| Rich content | A+ modules, brand story cards, comparison table | `aPlusContent`, `brandStory`, `productComparison` |

#### Need more Amazon data?

If you are working from category and search pages rather than known ASINs, **Amazon Product Scraper** takes category or product URLs instead of identifiers. For demand-side work, **Amazon Today's Deals Scraper** covers the deals surface and **Amazon Trending Products Scraper** covers movers by category. This Actor is the one to reach for when you already have the ASIN and need everything the detail page states about it.

### How does Amazon ASIN Scraper differ from the official Amazon Product Advertising API?

Amazon's own programmatic surface for product data is the **Product Advertising API (PA-API 5.0)**. It returns the item resources Amazon documents, to callers Amazon has approved. Amazon ASIN Scraper reads the public detail page as an anonymous visitor and returns what that page states.

| Feature | Product Advertising API 5.0 | Amazon ASIN Scraper |
| ----- | ----- | ----- |
| Access requirement | Amazon Associates account in good standing | Apify account only |
| Ongoing eligibility | Tied to qualifying sales generated through your Associates links | ❌ No sales requirement |
| Data scope | The item resources Amazon documents for the API | What the storefront page renders to an anonymous visitor |
| Rendered delivery, stock and sold-by sentences | Not part of the documented item resources | ✅ `deliveryDateText`, `warehouseAvailability`, `soldBy`, `pastSales`, verbatim |
| On-page specification tables | Not returned as page tables | ✅ `productSpecification` and `productDetails` as name/value lists |
| Stated image resolutions per gallery image | Not exposed | ✅ `imageInventory[].width`, `.height`, `.statedRenditions` |
| Which variant is currently shown | Page state, not an item attribute | ✅ `isSelected` and `selectedVariation` |
| Setup | Associates application and approval | Paste ASINs and press Start |

Check the current [PA-API 5.0 documentation](https://webservices.amazon.com/paapi5/documentation/) for its exact resources, eligibility terms and request limits before choosing between them — those terms change and are not reproduced here.

Use the official API when you are an approved Associate, want Amazon's supported contract, and need documented item attributes. Use Amazon ASIN Scraper when you have no Associates account, or when you specifically need what the page says today: the live variation family with the selected child marked, the rendered delivery and stock text, and the specification tables as printed.

### Why do developers and teams scrape Amazon ASINs?

#### For AI engineers and agent builders

A product-research agent needs the variation family before it can answer anything useful about sizing or colourways. Index `title`, `variationDimensions`, `productSpecification` and `productDetails` into a vector store keyed by `asin`, and an agent can answer "which colours does this come in, and what is the stated fabric" from live catalogue data rather than a stale export. Because every response is typed JSON with a fixed key set, there is no HTML-parsing step inside the agent loop — the row goes straight into the context window or into a tool result.

#### For catalogue and merchandising teams

Rebuilding a supplier's option grid means reproducing all of it, not a summary. Turn on `variantsAsSeparateRows` and one run gives you a spreadsheet-shaped grid: one line per child ASIN with `size`, `color`, `style` and `pattern` in their own columns, `variantOfAsin` for the join back to the parent, and `isSelectedVariant` marking the default. Pair it with `imageInventory` and you get the media assets and their stated resolutions in the same pass, so you know which shots are large enough to reuse before anyone downloads them.

#### For pricing and market analysts

The fulfilment block is where competitive signal hides. `soldBy` and `fulfilledBy` tell you whether Amazon or a third-party merchant holds the buy box, `warehouseAvailability` carries the "Only N left in stock" sentence, and `pastSales` carries the "N bought in past month" badge — all as rendered, with nothing derived from them. Set `deliveryPostcode` and re-run the same ASINs for a second location, and `deliveryDateText` plus `warehouseAvailability` change with it, which is how you compare regional availability on identical inputs.

#### For developers building data products

Every run writes to an Apify dataset with a stable key set, so a scheduled job can append to a warehouse table without a migration each week. Fields never disappear when you switch a toggle off — `includeSpecificationTables: false` yields `productSpecification: []`, not a missing key — so downstream code never needs a presence check. Schedule the run in Apify, attach a webhook to the run-succeeded event, and pipe the dataset into BigQuery, S3 or an internal API without writing any scraping code.

### How to scrape Amazon ASINs (step by step)

Amazon ASIN Scraper runs on Apify. Start it from the Apify Console or call it through the Apify API.

1. Open Amazon ASIN Scraper on Apify and click **Try for free**
2. Paste your ASINs into **ASINs to map** (`asins`) — one per line, 10 alphanumeric characters each, taken from the product URL after `/dp/`. This is the only required input, and pointing it at a child ASIN still returns the whole family
3. Set the storefront: **Storefront domain** (`marketplaceDomain`, default `amazon.com`) and **Proxy exit country** (`exitCountry`). Match them — a US residential exit against a non-US Amazon domain is served a CAPTCHA shell
4. Choose your output shape: leave **Map every size, colour and variant** on for a nested matrix, or turn on **Emit each variant as its own row** for a flat grid, capped by **Variant rows per product cap**
5. Click **Start**, then download the dataset as JSON, CSV or Excel — or read it through the Apify API

The dataset ships with two views: the default **Variations, specs & media per ASIN** table, and a **One row per size / colour variant** view that shows the flat grid columns.

#### What to do when Amazon changes its structure

The Actor is maintained, and the variation reader already carries four independent strategies — Amazon's twister payload, `asinVariationValues`, a raw regex over the display-data blob, and the rendered twister widget — tried in order until one produces dimensions. The output key set stays the same whichever wins, so your integrations keep working while the extraction path underneath changes.

### ⬇️ Input

Every parameter below is read directly from the Actor's input schema. `asins` is the only required field; everything else has a default.

| Parameter | Required | Type | Description | Example Value |
| ----- | ----- | ----- | ----- | ----- |
| `asins` | Yes | array | One ASIN per line — 10 alphanumeric characters, e.g. `B07GBZ4Q68`. Take it from the product URL after `/dp/`. Point it at any child ASIN and you still get the whole family back. ASINs are fetched concurrently. | `["B0BSHF7WHW", "B08N5WRWNW"]` |
| `marketplaceDomain` | No | string | Which Amazon storefront to read the listing from, e.g. `amazon.com`, `amazon.co.uk`, `amazon.de`. Variation labels come back in that storefront's language. Free text, not a dropdown. Default `"amazon.com"`. | `"amazon.co.uk"` |
| `pageLanguage` | No | string | Language code sent as `?language=…` and in `Accept-Language`. Dimension labels (`Size`, `Color`) and spec-table keys are rendered in this language, so English gives the most predictable column names. Default `"en"`. One of `""`, `en`, `en_US`, `en_GB`, `de`, `fr`, `es`, `it`, `nl`, `pl`, `pt`, `pt_BR`, `sv`, `tr`, `cs`, `da`, `ja`, `zh_CN`, `zh_TW`, `hi`. | `"en"` |
| `deliveryPostcode` | No | string | Optional destination postcode (e.g. `10001`). Sets Amazon's delivery cookie before scraping, so the delivery date string and stock sentence you get back are the ones for that location. Default `""`. | `"10001"` |
| `includeVariationMatrix` | No | boolean | Read Amazon's twister payload and return `parentAsin`, `variationDimensions` (each dimension with its full value list and the selected value), and `variationMatrix` — one entry per child ASIN with its dimension values and `isSelected`. Default `true`. | `true` |
| `variantsAsSeparateRows` | No | boolean | In addition to the product row, push one row per child ASIN (`rowType: "variant"`) with `size`, `color`, `style`, `pattern`, `variantOfAsin` and the child's product URL. Default `false`. | `true` |
| `maxVariantRowsPerProduct` | No | integer | Upper bound on how many child rows a single product may emit when the option above is on. Apparel parents can carry hundreds of children. Minimum 1, maximum 200. Default `30`. | `50` |
| `onlyProductsWithVariations` | No | boolean | Drop any ASIN whose page shows no twister at all. Use it when you are hunting variation parents and single-variant listings are noise. Default `false`. | `false` |
| `includeSpecificationTables` | No | boolean | Return `productSpecification` (technical spec tables) and `productDetails` (the Product details block, in both its table and bullet-list layouts) as complete name/value lists. Default `true`. | `true` |
| `includeMediaInventory` | No | boolean | Return `imageInventory` — every gallery image with its hi-res, large and thumbnail URLs plus the width x height Amazon itself states — and `videoInventory` with product video URLs, titles and durations as given. Default `true`. | `true` |
| `includeFulfilmentFacts` | No | boolean | Return `soldBy`, `fulfilledBy`, `deliveryMessage`, `deliveryDateText`, `fastestDeliveryText`, `warehouseAvailability` (the "Only N left in stock" sentence) and `pastSales` (the "N bought in past month" badge) exactly as rendered. Default `true`. | `true` |
| `trimRichContent` | No | boolean | A+ modules, brand story and comparison tables dominate the size of an Amazon record. Turn this on to blank them and keep the dataset small. The variation matrix, spec tables and `imageInventory` are not affected. Default `false`. | `false` |
| `exitCountry` | No | string | Route requests through this country. Match it to the storefront domain — a US residential exit against a non-US Amazon domain is served a CAPTCHA shell. Default `"AUTO_SELECT_PROXY_COUNTRY"`. One of `AUTO_SELECT_PROXY_COUNTRY`, `US`, `GB`, `DE`, `FR`, `ES`, `IT`, `CA`, `AU`, `JP`, `IN`, `BR`, `MX`, `NL`, `PL`, `TR`, `SE`, `AE`. | `"GB"` |
| `proxyConfiguration` | No | object | Full proxy override — Apify groups or your own URLs. Overrides the exit country above. Most runs can leave this alone. Prefilled with Apify Residential. | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

**Accepted alias keys.** For backward compatibility with the base Amazon input shape, the Actor also reads `amazonDomain`, `language`, `zipCode` and `proxyCountry`, and each **takes priority** over its schema equivalent above. `asinList` and `productAsins` are accepted as alternatives to `asins`. Fee and profit inputs from an earlier build (`unitCost`, `inboundShippingCost`, `extraCostPerUnit`, `referralFeePercentOverride`, `fulfilmentFeeOverride`, `feeCategoryOverride`, `fulfilmentChannel`, `includeFeeBreakdown`, `onlyProfitableAsins`) and `useCaptchaSolver` are accepted and ignored, each with a log line explaining why — this build calculates nothing and ships no inline CAPTCHA solver.

`pageLanguage: ""` ("Marketplace default") behaves exactly like omitting the key: no `?language=` is appended to the product URL, `reviewsLink` and `unNormalizedProductUrl` lose their language suffix, and the `Accept-Language` header falls back to English.

#### Example input

```json
{
  "asins": ["B0BSHF7WHW", "B08N5WRWNW", "1250301696", "B00FLYWNYQ"],
  "marketplaceDomain": "amazon.com",
  "pageLanguage": "en",
  "deliveryPostcode": "10001",
  "includeVariationMatrix": true,
  "variantsAsSeparateRows": true,
  "maxVariantRowsPerProduct": 50,
  "onlyProductsWithVariations": false,
  "includeSpecificationTables": true,
  "includeMediaInventory": true,
  "includeFulfilmentFacts": true,
  "trimRichContent": false,
  "exitCountry": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

**Common pitfall:** turning `onlyProductsWithVariations` on while `includeVariationMatrix` is off. With the matrix off, `hasVariations` is `null` on every record, so the filter drops every row and the dataset comes back empty. The reverse combination is handled for you: if `variantsAsSeparateRows` is on and `includeVariationMatrix` is off, the Actor logs a warning and turns the matrix back on, because no variant row could otherwise exist.

The second most common mistake is a storefront typo. `marketplaceDomain` is free text and nothing validates it — a mistyped domain is fetched as typed, fails, and lands as an uncharged error row rather than an obvious input error.

### ⬆️ Output

Typed, normalized JSON with a fixed key set. Every product row carries the same **81 keys** on every run, whatever your toggles are set to — switching a feature off empties its fields rather than removing them, so downstream code never needs a presence check. Export as JSON, CSV or Excel, or read the dataset through the Apify API.

Alongside the dataset, the run writes an `OUTPUT` record to the default key-value store: an object keyed by ASIN holding every parsed record from the run, including ones the filter dropped and ones that errored.

**Toggle behaviour, exactly as implemented:**

| Toggle | What happens to the fields |
| ----- | ----- |
| `includeVariationMatrix: false` | `hasVariations: null`, `variationSource: null`, `parentAsin: null`, `variationDimensions: []`, `variationDimensionNames: []`, `variationMatrix: []`, `variationCount: 0`, `selectedVariation: null`, `bookVariations: []` |
| `includeSpecificationTables: false` | `productSpecification: []`, `productDetails: []` |
| `includeMediaInventory: false` | `imageInventory: []`, `imageCount: 0`, `imageResolutions: []`, `videoInventory: []`, `videoCount: 0` |
| `includeFulfilmentFacts: false` | `soldBy`, `fulfilledBy`, `deliveryMessage`, `deliveryDateText`, `fastestDeliveryText`, `warehouseAvailability`, `pastSales` all `null` |
| `trimRichContent: true` | `aPlusContent: null`, `brandStory: null`, `productComparison: null`, `galleryThumbnails: []`, `highResolutionImages: []` |

**Field-name quirks, preserved exactly.** `breadCrumbs` carries a capital C. `unNormalizedProductUrl` is spelled with that internal capital N. `videosCount` (the legacy image-block video counter) and `videoCount` (the length of `videoInventory`) are two different fields. `attributes`, `productOverview` and `variantAttributes` use `{"key", "value"}` pairs while `productSpecification` and `productDetails` use `{"name", "value"}`. `fulfilledBy` uses British spelling while `color` on variant rows uses American. None of this is tidied up on the way out — it is reproduced as it exists, so your field mapping matches what actually arrives.

#### Product row fields

Every key on a `rowType: "product"` row.

| Field | Type | Description |
| ----- | ----- | ----- |
| `rowType` | string | Always `"product"` on this row type |
| `asin` | string | The ASIN scraped, uppercased |
| `originalAsin` | string | The same ASIN as submitted |
| `title` | string | null | Product title |
| `brand` | string | null | Brand as printed in the byline or the overview table |
| `author` | string | null | Author, on book and media pages |
| `url` | string | `https://www.<domain>/gp/product/<asin>?smid=` |
| `unNormalizedProductUrl` | string | `https://www.<domain>/dp/<asin>`, plus `?language=` when a language is set |
| `input` | string | `https://www.<domain>/dp/<asin>` — the join key back to your input |
| `reviewsLink` | string | `https://www.<domain>/product-reviews/<asin>` |
| `visitStoreLink` | string | null | Absolute brand-store URL |
| `position` | integer | 1-based counter in the order records were built during the run |
| `isPinnedOffer` | boolean | `true` when `position` is 1 |
| `variantOfAsin` | null | Always `null` on a product row; populated on variant rows |
| `price` | object | null | `{"value": float, "currency": symbol}` |
| `listPrice` | object | null | Struck-through list price, same shape |
| `priceRange` | string | null | Displayed price range, as printed |
| `shippingPrice` | object | null | Same shape; `value` is `0.0` when the page says free |
| `inStock` | boolean | null | Read from the availability sentence |
| `inStockText` | string | null | The availability sentence itself |
| `condition` | string | null | New / used condition label |
| `stars` | float | null | Average rating |
| `starsBreakdown` | object | Rating histogram as fractions, e.g. `{"5star": 0.81, "4star": 0.1}` |
| `reviewsCount` | integer | null | Review count |
| `hasReviews` | boolean | `true` when `reviewsCount` is above zero |
| `answeredQuestions` | integer | null | Answered-questions count |
| `isAmazonChoice` | boolean | Amazon's Choice badge present |
| `amazonChoiceText` | string | null | The badge text |
| `monthlyPurchaseVolume` | string | null | The bought-in-past-month faceout text |
| `aiReviewsSummary` | object | null | `{"text", "keywords": [{"name", "sentiment", "text", "customersMentionedCount": {"total"}, "partialReviews": []}]}` |
| `description` | string | null | Product description |
| `bookDescription` | string | null | Book blurb, read only when `description` is empty |
| `features` | array of strings | The bullet feature list |
| `attributes` | array | `[{"key", "value"}]` from the spec tables and detail bullets |
| `productOverview` | array | `[{"key", "value"}]` from the product-overview table |
| `importantInformation` | string | null | The Important information block |
| `sustainabilityFeatures` | object | null | `{"summary", "certifications": []}` |
| `returnPolicy` | string | null | Return-policy text |
| `support` | string | null | Product-support text |
| `breadCrumbs` | string | null | Category path joined with `>` |
| `categoriesExtended` | array | `[{"name", "url", "node"}]` — one entry per breadcrumb, URL built on your storefront domain |
| `bestsellerRanks` | array | `[{"rank", "category", "url"}]` |
| `aPlusContent` | object | null | `{"title", "rawText", "rawImages": [{"name", "url"}], "rawVideos": [{"url", "previewImageUrl"}], "modules": [{"type", "title", "text", "video", "image", "items"}]}` |
| `brandStory` | object | null | `{"title", "image", "items": [{"title", "text", "url", "image", "items"}]}` |
| `productComparison` | object | null | `{"products": [{"asin", "title", "thumbnail", "price", "stars", "reviewsCount"}]}` |
| `galleryThumbnails` | array of strings | Legacy thumbnail URL list |
| `highResolutionImages` | array of strings | Legacy hi-res URL list |
| `thumbnailImage` | string | null | Main image URL |
| `videosCount` | integer | Video count from the legacy image-block parse |
| `hasVariations` | boolean | null | `true` when a twister was found, `false` for a genuine single-variant product, `null` when the matrix is switched off |
| `variationSource` | string | null | Which strategy won: `twisterData`, `asinVariationValues`, `dimensionValuesDisplayData_regex` or `twisterDom` |
| `parentAsin` | string | null | Parent ASIN, when the payload states one |
| `variationDimensionNames` | array of strings | Raw dimension keys, e.g. `["size_name", "color_name"]` |
| `variationDimensions` | array | `[{"name", "label", "values": [], "valueCount", "selectedValue"}]` |
| `variationMatrix` | array | `[{"asin", "dimensions": {}, "label", "isSelected", "url"}]` — one entry per child ASIN |
| `variationCount` | integer | Length of `variationMatrix` — the full family size, never truncated |
| `selectedVariation` | object | null | The matrix entry Amazon is currently showing |
| `bookVariations` | array | `[{"format", "asin", "priceText", "url", "isSelected"}]` — book and media format swatches |
| `variantAsins` | array of strings | Child ASINs harvested from the raw page payloads |
| `variantDetails` | array | `[{"name", "thumbnail", "images": [], "asin", "price"}]` |
| `variantAttributes` | array | `[{"key", "value"}]` — the selected twister options as labelled on the page |
| `productSpecification` | array | `[{"name", "value"}]` from every technical specification table |
| `productDetails` | array | `[{"name", "value"}]` from the Product details block, table and bullet layouts |
| `imageInventory` | array | `[{"hiResUrl", "largeUrl", "thumbnailUrl", "variant", "width", "height", "resolution", "statedRenditions": [{"url", "width", "height"}]}]` |
| `imageCount` | integer | Length of `imageInventory` |
| `imageResolutions` | array of strings | Every non-null `resolution`, e.g. `"1500x1500"` |
| `videoInventory` | array | `[{"url", "title", "thumbnailUrl", "durationSeconds", "durationText", "group"}]` |
| `videoCount` | integer | Length of `videoInventory` |
| `soldBy` | string | null | Sold-by party, trimmed to the name Amazon printed |
| `fulfilledBy` | string | null | Ships-from / fulfilled-by party |
| `deliveryMessage` | string | null | The whole delivery block text |
| `deliveryDateText` | string | null | Just the bold delivery date |
| `fastestDeliveryText` | string | null | The fastest-delivery date |
| `warehouseAvailability` | string | null | The stock sentence, e.g. the "Only N left in stock" line |
| `pastSales` | string | null | The bought-in-past-month badge, verbatim |
| `seller` | object | null | `{"name", "id", "url", "reviewsCount", "averageRating"}`; `null` when nothing was found |
| `shipsFrom` | string | null | Ships-from string from the buy box |
| `delivery` | string | null | Legacy delivery string |
| `fastestDelivery` | string | null | Legacy fastest-delivery string |
| `locationText` | string | null | The location line in the page header |
| `loadedCountryCode` | string | null | Delivery country the page rendered for |

`price.currency` is the **symbol** the page used (`"$"`, `"£"`, `"€"`, `"zł"`, `"kr"`, `"AED"`), not an ISO code — the longest symbol is matched first, so `S$193.73` is not mislabelled as US dollars.

#### Scraped product record (nested variation matrix)

The default shape: one row per input ASIN, with the whole family nested inside it. Arrays are trimmed here for readability; a real record carries them in full.

```json
{
  "rowType": "product",
  "asin": "B0BSHF7WHW",
  "originalAsin": "B0BSHF7WHW",
  "title": "Hanes Men's Essentials Short Sleeve T-Shirt, Cotton Crewneck Tee",
  "brand": "Hanes",
  "url": "https://www.amazon.com/gp/product/B0BSHF7WHW?smid=",
  "unNormalizedProductUrl": "https://www.amazon.com/dp/B0BSHF7WHW?language=en",
  "input": "https://www.amazon.com/dp/B0BSHF7WHW",
  "price": { "value": 12.0, "currency": "$" },
  "listPrice": { "value": 16.0, "currency": "$" },
  "inStock": true,
  "inStockText": "In Stock",
  "stars": 4.5,
  "starsBreakdown": { "5star": 0.71, "4star": 0.17, "3star": 0.07, "2star": 0.02, "1star": 0.03 },
  "reviewsCount": 48211,
  "hasReviews": true,
  "breadCrumbs": "Clothing, Shoes & Jewelry > Men > Clothing > Shirts > T-Shirts",
  "hasVariations": true,
  "variationSource": "twisterData",
  "parentAsin": "B0BSHDJ8YV",
  "variationCount": 84,
  "variationDimensionNames": ["size_name", "color_name"],
  "variationDimensions": [
    {
      "name": "size_name",
      "label": "Size",
      "values": ["Small", "Medium", "Large", "X-Large", "XX-Large"],
      "valueCount": 5,
      "selectedValue": "Large"
    },
    {
      "name": "color_name",
      "label": "Color",
      "values": ["Black", "White", "Navy", "Heather Grey"],
      "valueCount": 4,
      "selectedValue": "Navy"
    }
  ],
  "variationMatrix": [
    {
      "asin": "B0BSHF7WHW",
      "dimensions": { "size_name": "Large", "color_name": "Navy" },
      "label": "Large / Navy",
      "isSelected": true,
      "url": "https://www.amazon.com/dp/B0BSHF7WHW"
    },
    {
      "asin": "B0BSHG2K4M",
      "dimensions": { "size_name": "Medium", "color_name": "Navy" },
      "label": "Medium / Navy",
      "isSelected": false,
      "url": "https://www.amazon.com/dp/B0BSHG2K4M"
    }
  ],
  "selectedVariation": {
    "asin": "B0BSHF7WHW",
    "dimensions": { "size_name": "Large", "color_name": "Navy" },
    "label": "Large / Navy",
    "isSelected": true,
    "url": "https://www.amazon.com/dp/B0BSHF7WHW"
  },
  "bookVariations": [],
  "productSpecification": [
    { "name": "Fabric type", "value": "60% Cotton, 40% Polyester" },
    { "name": "Care instructions", "value": "Machine Wash" },
    { "name": "Country of Origin", "value": "Imported" }
  ],
  "productDetails": [
    { "name": "Item model number", "value": "5280" },
    { "name": "Date First Available", "value": "January 24, 2023" },
    { "name": "ASIN", "value": "B0BSHF7WHW" }
  ],
  "imageCount": 7,
  "imageInventory": [
    {
      "hiResUrl": "https://m.media-amazon.com/images/I/71aBcDeFgHL._AC_SL1500_.jpg",
      "largeUrl": "https://m.media-amazon.com/images/I/71aBcDeFgHL._AC_SX679_.jpg",
      "thumbnailUrl": "https://m.media-amazon.com/images/I/71aBcDeFgHL._AC_US40_.jpg",
      "variant": "MAIN",
      "width": 1500,
      "height": 1500,
      "resolution": "1500x1500",
      "statedRenditions": [
        { "url": "https://m.media-amazon.com/images/I/71aBcDeFgHL._AC_SX679_.jpg", "width": 679, "height": 679 },
        { "url": "https://m.media-amazon.com/images/I/71aBcDeFgHL._AC_SL1500_.jpg", "width": 1500, "height": 1500 }
      ]
    }
  ],
  "imageResolutions": ["1500x1500", "1200x1200"],
  "videoCount": 1,
  "videoInventory": [
    {
      "url": "https://m.media-amazon.com/images/S/vse-vms-transcoding-artifact-us-east-1/abc123/default.jobtemplate.mp4",
      "title": "How the Essentials tee fits",
      "thumbnailUrl": "https://m.media-amazon.com/images/I/51xYzAbCdEL.jpg",
      "durationSeconds": 31,
      "durationText": "0:31",
      "group": "brand"
    }
  ],
  "soldBy": "Amazon.com",
  "fulfilledBy": "Amazon.com",
  "deliveryMessage": "FREE delivery Thursday, July 30 on orders shipped by Amazon over $35",
  "deliveryDateText": "Thursday, July 30",
  "fastestDeliveryText": "Tomorrow, July 26",
  "warehouseAvailability": "Only 8 left in stock - order soon.",
  "pastSales": "10K+ bought in past month",
  "seller": {
    "name": "Amazon.com",
    "id": null,
    "url": "https://www.amazon.com/",
    "reviewsCount": null,
    "averageRating": null
  },
  "categoriesExtended": [
    { "name": "Men", "url": "https://www.amazon.com/mens-clothing/b?node=7147441011", "node": "7147441011" }
  ],
  "bestsellerRanks": [
    { "rank": 3, "category": "Men's T-Shirts", "url": "https://www.amazon.com/gp/bestsellers/apparel/1045662" }
  ],
  "position": 1,
  "isPinnedOffer": true,
  "variantOfAsin": null,
  "loadedCountryCode": "US",
  "locationText": "Deliver to New York 10001"
}
```

#### Scraped variant row (exploded grid)

Set `variantsAsSeparateRows: true` and the product row above is followed by one row per child ASIN — a structurally different record with its own 17 keys, not a copy of the product row. This is the shape you paste straight into a sheet.

```json
{
  "rowType": "variant",
  "asin": "B0BSHG2K4M",
  "variantOfAsin": "B0BSHF7WHW",
  "parentAsin": "B0BSHDJ8YV",
  "title": "Hanes Men's Essentials Short Sleeve T-Shirt, Cotton Crewneck Tee",
  "brand": "Hanes",
  "url": "https://www.amazon.com/dp/B0BSHG2K4M",
  "variantLabel": "Medium / Navy",
  "variantDimensions": { "size_name": "Medium", "color_name": "Navy" },
  "size": "Medium",
  "color": "Navy",
  "style": null,
  "pattern": null,
  "isSelectedVariant": false,
  "variationSource": "twisterData",
  "breadCrumbs": "Clothing, Shoes & Jewelry > Men > Clothing > Shirts > T-Shirts",
  "input": "https://www.amazon.com/dp/B0BSHF7WHW"
}
```

`size`, `color`, `style` and `pattern` are looked up by the literal dimension keys `size_name`, `color_name`, `style_name` and `pattern_name`. When a storefront uses different dimension keys, those four columns come back `null` and the values are still present in full inside `variantDimensions` — nothing is lost, it just moves.

#### Uncharged error rows

When an ASIN cannot be fetched or cannot be parsed, the Actor writes a minimal row so the failure is visible in your dataset rather than being an absence you have to notice. These rows are pushed **without a charged event** — you are not billed for them.

```json
{ "asin": "B00FLYWNYQ", "error": "fetch_failed" }
```

```json
{ "asin": "B08N5WRWNW", "error": "parse_error: <message>" }
```

Filter them out on the way in. In Python:

```python
rows = [r for r in items if not r.get("error")]
products = [r for r in rows if r.get("rowType") == "product"]
variants = [r for r in rows if r.get("rowType") == "variant"]
```

Error rows carry no `rowType`, so a `rowType` check alone also separates real results from failures.

### How does Amazon ASIN Scraper compare to other variant scrapers?

Checked on the Apify Store on 25 July 2026. Of the three closest listings, only one targets Amazon: `junglee/amazon-asins-scraper`. `clearpath/shein-product-scraper` covers Shein by keyword search, and `s-r/free-google-shopping-variants` covers Google Shopping variants by SKU. Claims below are as stated on those listings on that date; where a listing does not document something, it is marked **not documented** rather than assumed absent.

| Feature | Amazon ASIN Scraper | Generic alternative |
| ----- | ----- | ----- |
| Full variation matrix per ASIN, with dimension value lists and a selected flag | ✅ `variationMatrix`, `variationDimensions`, `selectedVariation` | `junglee/amazon-asins-scraper`: not documented in its README. `s-r/free-google-shopping-variants` documents variants for Google Shopping SKUs, not Amazon ASINs |
| Choice of nested matrix or one row per variant | ✅ `variantsAsSeparateRows`, with a per-product cap | Not documented on any of the three |
| On-page specification and product-details tables as name/value lists | ✅ `productSpecification`, `productDetails` | `junglee/amazon-asins-scraper`: not documented. `clearpath/shein-product-scraper` documents size charts and attributes for Shein |
| Image resolutions as stated by the source site | ✅ `imageInventory[].width`, `.height`, `.statedRenditions` | Not documented on any of the three |
| Visible, structured error rows | ✅ `error` field, pushed uncharged | `junglee/amazon-asins-scraper` documents error items with an `error` field and an error-code reference table |
| Documented input surface | 14 schema parameters plus four accepted alias keys | `junglee/amazon-asins-scraper` documents ASINs plus store choice. `clearpath/shein-product-scraper` documents 8 fields. `s-r/free-google-shopping-variants` documents 6 |

If you are building an AI agent or a RAG pipeline, the output-format row is the decision-maker: parsing HTML inside an agent loop is a reliability failure mode, not a feature. And if what you actually need is a per-child price, read the constraint at the top of this page before choosing any variant scraper — it applies to anything that reads a single parent page.

### How many ASINs and variant rows can you scrape?

**There is no hard cap in the Actor itself.** `asins` has no maximum length in the schema, and there is no `maxItems` parameter. The row count is the number of valid, unique ASINs you supply, plus up to `maxVariantRowsPerProduct` extra rows per product when `variantsAsSeparateRows` is on.

The one ceiling is the variant-row cap, and it is worth being precise about what it limits. `maxVariantRowsPerProduct` (default `30`, minimum `1`, maximum `200`) caps **emitted variant rows only**. It is the Actor's limit, not Amazon's, and it does not touch the matrix read: `variationMatrix` and `variationCount` still carry the complete family. So a parent with 300 children returns all 300 inside `variationMatrix` and, at the default, 30 variant rows — the first 30 in the order Amazon's payload listed them. The remainder is dropped from the row stream and written to the run log, but nothing in the row itself flags the truncation, so compare `variationCount` against your row count if you need to know whether you got the full grid. Values above 200 are clamped to 200 even if the schema check is bypassed.

Input ASINs are uppercased, deduplicated and validated against a 10-character alphanumeric pattern. Anything that fails is skipped with a log warning before fetching starts and never reaches the dataset; if nothing valid remains, the run fails immediately with a message naming the `asins` input. Fetching runs at a fixed concurrency of 5 ASINs at a time with a 30-second request timeout — there is no concurrency input to raise.

### Integrate Amazon ASIN Scraper and automate your workflow

Amazon ASIN Scraper works with any language or tool that can send an HTTP request.

#### REST API integration

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("<YOUR_USERNAME>/amazon-asin-scraper-sizes-colors-variants").call(run_input={
    "asins": ["B0BSHF7WHW", "B08N5WRWNW"],
    "marketplaceDomain": "amazon.com",
    "variantsAsSeparateRows": True,
    "maxVariantRowsPerProduct": 50,
    "exitCountry": "US",
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("error"):
        continue
    if row["rowType"] == "product":
        print(row["asin"], row["title"], row["variationCount"], row["warehouseAvailability"])
    else:
        print("  ", row["asin"], row["size"], row["color"])
```

Works in Python, Node.js, Go, Ruby, cURL. Branch on `rowType` to route product rows and variant rows to different handlers, and skip anything carrying `error`.

#### Automation platforms (n8n, Make, LangChain)

In **n8n**, use the Apify node — or an HTTP Request node pointed at the Apify run endpoint with your token — and pass the same JSON input shown above; a Switch node on `rowType` then splits products from variants into separate branches. In **Make**, use the Apify module with run-and-wait and map the dataset output straight into a Google Sheets or Airtable step, which is the fastest way to get the exploded size/colour grid into a spreadsheet. In **LangChain**, wrap the run call as a tool that returns the dataset items; because every row is already typed JSON, the tool result needs no parsing before it reaches the model. Apify schedules and webhooks handle recurrence, so a weekly catalogue sweep needs no code at all.

### Is it legal to scrape Amazon product data?

Scraping publicly listed product data is broadly treated as permissible where the data is accessible without authentication, and Amazon ASIN Scraper collects only what an anonymous visitor already sees on the public detail page. No account, no cookie, no session, no login bypass.

What comes back is product-catalogue data: titles, prices, specification tables, image URLs, variation grids and the merchant names Amazon prints in the buy box. These are commercial business records, not personal data, so GDPR and equivalent personal-data regimes do not attach to this output the way they would to a profile scraper.

The obligations that do apply are contractual and database-related: Amazon's terms of service, and any local database-right or unfair-competition rules covering systematic reuse of a compiled catalogue. Consult legal counsel for commercial use cases — in particular before republishing extracted listings as a competing catalogue or reselling the data as a standalone product.

### ❓ Frequently asked questions

#### Does Amazon ASIN Scraper work without an Amazon account?

Yes. No Amazon account, login, cookie or session is used. Requests are anonymous, and every field returned is visible to any visitor on the public detail page. The only credential you need is your Apify token.

#### How often is the scraped data updated?

Every run fetches the live page. There is no cache and no stored snapshot — `price`, `warehouseAvailability`, `deliveryDateText` and the variation matrix are read from the HTML Amazon served during that run. To track change over time, schedule the run in Apify and diff consecutive datasets on `asin`.

#### What happens when an ASIN is invalid, delisted, or not available on the chosen marketplaceDomain?

It fails as a record, not as an empty search, and there are three distinct outcomes. An ASIN that does not match the 10-character alphanumeric pattern is dropped **before** fetching starts, with a log warning; if no valid ASIN remains, the run fails with an error naming the `asins` input. An ASIN that is valid in shape but returns 404 or 410 on your chosen storefront — the usual outcome for a delisted product, or one that simply does not exist on that marketplace — produces an uncharged `{"asin": "...", "error": "fetch_failed"}` row once the fetch gives up. A page that loads but breaks the parser produces `{"asin": "...", "error": "parse_error: ..."}`, also uncharged. Every other input in the same run continues normally.

A live ASIN with no twister on its page is not a failure: it returns a full product row with `hasVariations: false`, an empty `variationMatrix` and `variationCount: 0`. A single-variant product is reported as single-variant rather than dressed up as a one-row family.

#### Can I scrape login-gated Amazon content or review text?

No. Only publicly accessible page content is returned. Review **text** in particular is not part of the output: Amazon serves no review nodes on the logged-out detail page and the alternate review surfaces return a sign-in shell, so on-page review extraction was removed rather than left returning empty fields. What you do get is the review metadata the public page states — `stars`, `starsBreakdown`, `reviewsCount`, `answeredQuestions` and a `reviewsLink` you can follow yourself.

#### What am I charged for?

The Actor bills per pushed row through the `row_result` pay-per-event. One product row is one event; each variant row emitted by `variantsAsSeparateRows` is another, which is why `maxVariantRowsPerProduct` doubles as a cost control. Error rows are pushed with no charged event at all. Products dropped by `onlyProductsWithVariations` are fetched and parsed but never pushed, so they are never charged either — though they do still appear in the `OUTPUT` key-value store record, which is the easiest way to see what the filter removed.

#### Does Amazon ASIN Scraper work for AI agent workflows and LLM pipelines?

Yes. It is callable as a standard HTTP endpoint through the Apify API, so LangChain, CrewAI, n8n or a hand-written tool definition can invoke it and receive typed JSON directly. Every response is normalized JSON with a fixed key set — no parsing step before the data reaches a model, and no HTML in the payload.

#### How does Amazon ASIN Scraper handle Amazon's anti-bot system?

Through proxying, session handling and a retry ladder — there is no inline CAPTCHA solver in this build. Requests go out through Apify Proxy, defaulting to the residential group; picking a country in `exitCountry` pins the exit, and `proxyConfiguration` overrides it entirely if you need your own URLs. Each ASIN gets its own sticky Apify session on the first attempt, so a primed delivery cookie stays on one IP; every retry rotates to a fresh IP instead.

A response is treated as blocked when the body carries a CAPTCHA or robot-check marker, not only when the status is non-200 — so a soft block returning HTTP 200 is caught rather than parsed into an empty record. Failed attempts back off with jitter before retrying: three attempts by default, four when you pin a specific exit country. Choosing `US` adds a geo-verification pass — the Actor checks the page's own delivery country, location line, currency and marketplace ID, retries if the page did not render as US, and falls back to a best-effort response if it never does. A 404, 410 or proxy-auth failure stops the retries immediately, since none of those is worth another attempt. Requests carry a rotating desktop User-Agent and a full browser header set rather than a default HTTP client signature.

#### Can I use Amazon ASIN Scraper without managing proxies?

Yes. The proxy input is prefilled with Apify Residential and `exitCountry` defaults to auto-select, so a run works with no proxy setup at all — you never create a proxy account or rotate an IP. If Apify cannot create the proxy configuration for any reason, the run logs a warning and continues on a direct connection rather than failing, which is worth knowing because a direct connection to Amazon is far more likely to be blocked.

#### What does setting a delivery postcode actually change?

`deliveryPostcode` runs a one-off priming sequence before any product is scraped: the Actor loads the storefront, reads Amazon's anti-CSRF token from the address-selection endpoint, and posts your postcode to the glow address-change endpoint. The resulting cookie is attached to every product request in the run, so `deliveryMessage`, `deliveryDateText`, `fastestDeliveryText` and `warehouseAvailability` are the strings Amazon renders for that location. Leave it empty and no priming happens — requests still carry a fixed US-English locale cookie, so what you get is Amazon's default location for the proxy exit IP. If priming fails, the run logs a warning and carries on without it rather than aborting.

#### How does Amazon ASIN Scraper compare to other Amazon ASIN scrapers?

Checked on the Apify Store on 25 July 2026, `junglee/amazon-asins-scraper` is the most established Amazon ASIN Actor and the closest comparison — its README documents ASIN and offer data, an error-item structure with an error-code reference table, multiple export formats and platform integrations, and its JSON example shows a ten-field record built around title, brand, price, stars and breadcrumbs. It does not document a variation matrix, specification tables or per-image resolutions. The other two closest listings are on different platforms: `clearpath/shein-product-scraper` documents Shein size charts, size conversions, model measurements and fit from keyword searches, and `s-r/free-google-shopping-variants` documents variant data by Google Shopping SKU. What this Actor documents that they do not is the Amazon variation family itself — every child ASIN with its dimension values, which one is selected, a choice between nesting it or exploding it into rows, and the specification tables and stated image resolutions from the same single fetch.

#### Does Amazon ASIN Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with stable field names on every run. No HTML, no selectors, no parsing. Pass a row directly into an LLM context window, index it into a vector store, or route it through an agent tool. For RAG indexing, `title`, `productSpecification`, `productDetails` and `variationDimensions` carry the most descriptive text per record and chunk cleanly by `asin`.

#### What happens when Amazon changes its structure or blocks the scraper?

The scraper is maintained and the output schema stays stable — field names and types do not change on your end. The variation reader carries four independent strategies and falls through them in order, and the specification, media and fulfilment extractors each try several layouts, including the newer detail-page layouts where the classic selectors return nothing. A structural change on Amazon's side typically empties one field rather than failing a whole row, and a blocked request is retried through a fresh proxy session before it ever becomes an error row.

### 🔗 Related scrapers

| Scraper Name | What it extracts |
| ----- | ----- |
| Amazon Product Scraper | Product records from Amazon category and product URLs |
| Amazon Today's Deals Scraper | Deal listings from Amazon's Today's Deals surface |
| Amazon Trending Products Scraper | Trending and fast-moving products by category |
| Alibaba Scraper With Supplier Contact Leads | Alibaba product rows plus outreach-ready supplier records |

### 💬 Your feedback

Found a bug, or need a field that is on the Amazon detail page but not yet in the output? Open an issue on the Actor's Issues tab. Reports that include the exact ASIN, the `marketplaceDomain` you used and the input JSON are the fastest to reproduce and fix.

# Actor input Schema

## `asins` (type: `array`):

One ASIN per line — 10 alphanumeric characters, e.g. `B07GBZ4Q68`. Take it from the product URL after `/dp/`. Point it at any child ASIN and you still get the whole family back. ASINs are fetched concurrently.

## `marketplaceDomain` (type: `string`):

Which Amazon storefront to read the listing from, e.g. `amazon.com`, `amazon.co.uk`, `amazon.de`. Variation labels come back in that storefront's language.

The base input key `amazonDomain` is still accepted and takes priority.

## `pageLanguage` (type: `string`):

Language code sent as `?language=…` and in `Accept-Language`. Dimension labels (`Size`, `Color`) and spec-table keys are rendered in this language, so English gives the most predictable column names.

The base input key `language` is still accepted and takes priority.

## `deliveryPostcode` (type: `string`):

Optional destination postcode (e.g. `10001`). Sets Amazon's delivery cookie before scraping, so the delivery date string and stock sentence you get back are the ones for that location.

The base input key `zipCode` is still accepted and takes priority.

## `includeVariationMatrix` (type: `boolean`):

Read Amazon's twister payload and return `parentAsin`, `variationDimensions` (each dimension with its full value list and the selected value), and `variationMatrix` — one entry per child ASIN with its dimension values and `isSelected`.

## `variantsAsSeparateRows` (type: `boolean`):

In addition to the product row, push one row per child ASIN (`rowType: "variant"`) with `size`, `color`, `style`, `pattern`, `variantOfAsin` and the child's product URL. Handy for pasting a whole size/colour grid straight into a sheet.

Variant rows carry only what the parent page states about that child — no price or stock is copied down, because the parent page does not state them per child.

## `maxVariantRowsPerProduct` (type: `integer`):

Upper bound on how many child rows a single product may emit when the option above is on. Apparel parents can carry hundreds of children.

## `onlyProductsWithVariations` (type: `boolean`):

Drop any ASIN whose page shows no twister at all. Use it when you are hunting variation parents and single-variant listings are noise.

## `includeSpecificationTables` (type: `boolean`):

Return `productSpecification` (technical spec tables) and `productDetails` (the Product details block, in both its table and bullet-list layouts) as complete name/value lists.

## `includeMediaInventory` (type: `boolean`):

Return `imageInventory` — every gallery image with its hi-res, large and thumbnail URLs plus the width x height Amazon itself states — and `videoInventory` with product video URLs, titles and durations as given.

## `includeFulfilmentFacts` (type: `boolean`):

Return `soldBy`, `fulfilledBy`, `deliveryMessage`, `deliveryDateText`, `fastestDeliveryText`, `warehouseAvailability` (the "Only N left in stock" sentence) and `pastSales` (the "N bought in past month" badge) exactly as rendered.

## `trimRichContent` (type: `boolean`):

A+ modules, brand story and comparison tables dominate the size of an Amazon record. Turn this on to blank them and keep the dataset small. The variation matrix, spec tables and `imageInventory` are not affected.

## `exitCountry` (type: `string`):

Route requests through this country. Match it to the storefront domain — a US residential exit against a non-US Amazon domain is served a CAPTCHA shell.

The base input key `proxyCountry` is still accepted and takes priority.

## `proxyConfiguration` (type: `object`):

Full proxy override — Apify groups or your own URLs. Overrides the exit country above. Most runs can leave this alone.

## Actor input object example

```json
{
  "asins": [
    "B0BSHF7WHW",
    "B08N5WRWNW",
    "1250301696",
    "B00FLYWNYQ"
  ],
  "marketplaceDomain": "amazon.com",
  "pageLanguage": "en",
  "deliveryPostcode": "",
  "includeVariationMatrix": true,
  "variantsAsSeparateRows": false,
  "maxVariantRowsPerProduct": 30,
  "onlyProductsWithVariations": false,
  "includeSpecificationTables": true,
  "includeMediaInventory": true,
  "includeFulfilmentFacts": true,
  "trimRichContent": false,
  "exitCountry": "AUTO_SELECT_PROXY_COUNTRY",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per scraped ASIN: variation matrix, specification and product-details tables, image/video inventory, and rendered fulfilment text.

## `variants` (type: `string`):

Only present when 'Emit each variant as its own row' is enabled: one row per child ASIN with its size, colour, style and pattern values.

## `keyedOutput` (type: `string`):

The same records, keyed by ASIN, stored in the run's default key-value store under the OUTPUT key.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "asins": [
        "B0BSHF7WHW",
        "B08N5WRWNW",
        "1250301696",
        "B00FLYWNYQ"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-empire/amazon-asin-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "asins": [
        "B0BSHF7WHW",
        "B08N5WRWNW",
        "1250301696",
        "B00FLYWNYQ",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("api-empire/amazon-asin-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "asins": [
    "B0BSHF7WHW",
    "B08N5WRWNW",
    "1250301696",
    "B00FLYWNYQ"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call api-empire/amazon-asin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,api-empire/amazon-asin-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fidc6kND3zuUKta4f/builds/tG6oiEqdW9JYZ1mfr/openapi.json
