# Amazon ASIN Scraper — Full Product Row per ASIN, Flat Fee (`steadyfetch/amazon-product-scraper`) Actor

Amazon product: any product by ASIN or URL as one finished row — price, buy box, stock, rating, reviews, variants, bestseller ranks, images and specs. From $3.00 per 1,000 products, one flat fee, no add-on events. Blocked or missing ASINs are never charged.

- **URL**: https://apify.com/steadyfetch/amazon-product-scraper.md
- **Developed by:** [Steadyfetch Team](https://apify.com/steadyfetch) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Amazon ASIN Scraper — Full Product Row per ASIN, Flat Fee

**One flat fee per product. Price, buy box, stock, rating, reviews, variants, bestseller ranks, images and the full specifications table all arrive in one row — there is no second event to pay for. Blocked or missing ASINs are never charged.**

**Using an AI agent?** Pin this actor in Apify's MCP server with one link: `https://mcp.apify.com?tools=steadyfetch/amazon-product-scraper`

- **Actor id:** `steadyfetch/amazon-product-scraper`
- **Input:** `{ "products": ["B0DN4BG1RW"] }` — the one field to set.
- **Cap the bill:** set `maxTotalChargeUsd` on the run (a run option, not Actor input), e.g. `0.50` — the run stops when it reaches it.
- **Price:** from **$3.00** per 1,000 products on Silver and above, $6.00 per 1,000 on the Apify Free plan — one priced event, `Product`, and nothing else. Price, buy box, stock, rating, reviews, variants, bestseller ranks, images and the full specifications table are columns on the one row you already paid for. No start fee, and a blocked or missing ASIN is never charged. Full ladder below.
- **How often it changes:** price, buy box and stock move through the day and review counts climb steadily, so the same ASIN read tomorrow is a different row — which is what makes this a scheduled job rather than a one-off. The specifications table and the variant list barely move at all. Every run fetches fresh, at the same flat fee per product.

Give it an ASIN or an Amazon product URL. Get the finished product object back.

**Just want to see it work?** Click **Start** with nothing set and the run fetches one real sample product (ASIN `B0DN4BG1RW` on `amazon.com`), charged like any run — $0.006 on the Apify Free plan, $0.003 on Business. Set only settings — a different **Marketplace**, a limit, a row-size switch — and leave **Products** empty, and that same sample runs under your settings on the store you picked, charged like any run. Put your own ASINs or URLs in **Products** for your own run.

![Amazon Product Scraper input form in the Apify console: the Products list prefilled with an ASIN and an amazon.de product URL, above the Marketplace picker](https://api.apify.com/v2/key-value-stores/wciMDNpNgBh87mGUp/records/amazon-product-scraper--input-form.png)

> **Unofficial.** This actor is not affiliated with, endorsed by, or sponsored by Amazon. "Amazon" and all related marks are trademarks of Amazon.com, Inc. or its affiliates. It reads only the public product pages an ordinary browser sees, and never signs in.

### Output

![Dataset table of a real run: one product row — JBL Vibe Beam 2 on amazon.com, 39.95 USD against a 64.95 list price, in stock, 4.1 rating, 6,803 reviews and the buy-box seller](https://api.apify.com/v2/key-value-stores/wciMDNpNgBh87mGUp/records/amazon-product-scraper--dataset-table.png)

One row per product. This is a real row from a verified run (ASIN `B0DN4BG1RW` on `amazon.com`), trimmed with `…` where a field is long:

```json
{
  "asin": "B0DN4BG1RW",
  "marketplace": "amazon.com",
  "url": "https://www.amazon.com/dp/B0DN4BG1RW",
  "title": "JBL Vibe Beam 2 - Noise Cancelling Earbuds - White",
  "brand": "JBL",
  "price": 39.94,
  "currency": "USD",
  "listPrice": 64.95,
  "inStock": true,
  "availability": "In Stock",
  "buyBoxSeller": "Electronics Expo (Authorized Dealer)",
  "buyBoxSellerId": "A1J7WSBJHTGUFA",
  "fulfilledByAmazon": false,
  "soldByAmazon": false,
  "buyBoxNote": null,
  "rating": 4.1,
  "reviewCount": 6717,
  "boughtInPastMonth": 2000,
  "images": ["https://m.media-amazon.com/images/I/41CpD7mn8tL._AC_SL1200_.jpg", "…"],
  "features": ["Bluetooth 5.3 …"],
  "variants": [{ "asin": "B0DBLMLM81", "attributes": { "color_name": "Blue" } }],
  "variantCount": 4,
  "categoryPath": ["Electronics", "Headphones, Earbuds & Accessories"],
  "bestSellersRank": [{ "rank": 63, "category": "Electronics" }],
  "specs": { "Brand Name": "JBL", "Model Number": "JBLVBEAM2WHT" },
  "deliveryTo": "US",
  "scrapedAt": "2026-08-27T00:00:00.000Z",
  "charged": true,
  "status": "ok"
}
```

**Rows arrive in the order you listed your products**, with uncharged misses on their own line rather than at the end, so the output reads straight back against the list you pasted. A list that mixes several Amazon stores is worked through store by store in rotation, to keep the request pace off any one site, and the rows follow that same sequence.

Prices and review counts are parsed in the page's own locale, so `4,4 von 5 Sternen` is a rating of 4.4 and `(4.295)` on amazon.de is four thousand reviews, not four.

**`price` can legitimately be `null`, and you should expect it.** Amazon does not always put a price on the page it serves. Some listings replace it with "add this item to your cart to see the price", and some have no live offer at all. On the European marketplaces, where Amazon withholds the price far more often than on amazon.com, a price-less product is automatically re-checked, so European rows carry the real local price — `49,00 €` on amazon.fr, `475,00 kr` on amazon.se, `139,00 zł` on amazon.pl — instead of `null`. When the re-check fails too, the row still ships with `price: null` and `priceNote` says what the page showed instead. It is measured behaviour, printed here rather than hidden — the row is charged because it is a real product row, so you should know this before you run a price-only job.

**The Sold-by cluster explains itself when Amazon withholds it.** `buyBoxSeller`, `buyBoxSellerId`, `fulfilledByAmazon` and `soldByAmazon` are read from whichever layout Amazon serves — the classic Sold-by block, the newer offer-display widget, the mobile "Sold by:" rows, or the Add-to-Cart form's own merchant id. When a served page names no seller at all (it happens — some renders ship the buy box empty), those four come back null and `buyBoxNote` says so on that row, so a null is never a silent gap. On Amazon's own device pages (Fire TV and kin) `specs` are read from the Technical-details grid, and `categoryPath` / `bestSellersRank` come back empty because Amazon renders neither on those pages — that is the page, not a parsing gap.

The last row of every run is a summary carrying `requested`, `ok`, `blocked`, `notFound`, `unavailableInMarketplace`, `chargedRows` and `unchargedRows` — so the invoice reconciles from the dataset itself, without opening the billing tab.

**A real dataset, not a mock-up:** [three products across amazon.com, amazon.co.uk and amazon.de plus the summary row](https://api.apify.com/v2/datasets/jKabo0Zptcb0LXdqK/items?clean=true\&format=json) — the untouched output of one verified run of the current code, Sold-by cluster populated on every row.

### For AI agents & LLMs — copy this block

```
Actor: steadyfetch/amazon-product-scraper
Input: { "products": ["B0DN4BG1RW", "https://www.amazon.de/dp/B0DBLN4C47"] }
Output: one row per product; charged rows have status "ok" and charged true.
Pricing: one priced event ("product"), all-inclusive, no start fee, no add-ons.
Misses: blocked / not_found / unavailable_in_marketplace / not_a_product / parse_failed /
        source_unavailable all ship as rows with charged:false — read `status`, never guess
        from an empty field.
Notes: omit an optional field or send it as null — both mean "use the default", the
       "marketplace" dropdown included. A marketplace that is not on the list is not
       silently swapped for amazon.com: the run returns one uncharged row naming the
       stores that work. "products" is the one field that must carry a real value.
       Limits are hard limits.
       Resuming or resurrecting a run never re-sends or re-bills a product it already delivered.
```

Works over the Apify API, MCP, n8n and Make. A bare **Start** with nothing set runs the one-product sample described at the top of this page, charged like any run, so you can see the exact output shape before wiring your own list — and setting only settings, with no products, runs that sample under them, with one uncharged row naming what you set.

**MCP**: pinned with the one link at the top of this page — or ask Apify's MCP server for "amazon product".

### Use it as an API endpoint (Standby)

You can also call this actor like an API: send a few ASINs or product links and get their full product rows back in the same response, with no run to start and no dataset to read. The address is `https://steadyfetch--amazon-product-scraper.apify.actor`, and the actor's **Endpoints** tab lets you try it from the browser.

```bash
curl -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  "https://steadyfetch--amazon-product-scraper.apify.actor/?products=B0DN4BG1RW,B07YYW1YH9"
```

Or POST the same input a run takes:

```bash
curl -X POST -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" -H "Content-Type: application/json" \
  -d '{"products": ["https://www.amazon.de/dp/B0DBLN4C47"], "includeSpecs": false}' \
  "https://steadyfetch--amazon-product-scraper.apify.actor/"
```

The answer is JSON: `rows` (one per product, with the same fields as a row in a run's dataset), `receipt` (the run's closing summary row), `delivered`, `charged`, and `notes` for anything you should know, in plain words. You are charged exactly as in a run — one `Product` per delivered product row — and a blocked, missing or unreadable product is never charged. If the charge for a request cannot be completed, its products are not sent.

Good to know: one request takes up to 10 products (3 on the Apify free plan); a longer list is a run's job. The endpoint keeps no memory between requests, exactly like a run: a product you ask for again is fetched fresh and charged again. It does not read a `datasetId` or a `resumeFromDatasetId` — it cannot see your Apify account. A request that runs out of time sends what it already has and lists the products it did not reach in the receipt's `resumeCursor`, uncharged.

### What one product costs

One priced event, `Product`, and nothing else. No start fee, no per-field fee, no delivery-location fee, no "detail" upcharge. The store header reads **from $3.00/1,000 products**.

| Your Apify plan | Price per product | Per 1,000 products |
|---|---|---|
| Apify Free plan | $0.006 | $6.00 |
| Bronze | $0.0035 | $3.50 |
| Silver | $0.003 | $3.00 |
| **Gold, Platinum, Diamond** | **$0.003** | **$3.00** |

The header shows the Gold price, which Silver pays too. The whole ladder is printed here because an actor whose promise is billing honesty cannot have an undisclosed tier ladder.

**What can fail, and what a failure costs you: nothing.** The two misses you will actually see are `blocked` (Amazon put a robot check in front of every route we tried) and `not_found` (no product page at that id on that marketplace). Both ship as real rows carrying `charged: false`, as do `unavailable_in_marketplace`, `not_a_product`, `parse_failed`, `source_unavailable` and `invalid_input`. A row is charged only if it is a product.

### What you give it

| Input | Example |
|---|---|
| ASIN | `B0DN4BG1RW` |
| Product URL | `https://www.amazon.com/dp/B0DN4BG1RW` |
| `/gp/product/` URL | `https://www.amazon.co.uk/gp/product/B0DBLN4C47` |
| A URL you copied from a search result | `https://www.amazon.de/Sony-WF-C510/dp/B0DBLN4C47/ref=sr_1_1?keywords=sony` |
| An Amazon short link | `https://amzn.to/…`, `https://a.co/d/…` |

Casing does not matter and `www.` is optional — chat apps and link shorteners rewrite URLs, and all of those shapes still resolve.

**Marketplaces: `amazon.com` plus nine European stores — `amazon.co.uk`, `amazon.de`, `amazon.fr`, `amazon.it`, `amazon.es`, `amazon.nl`, `amazon.pl`, `amazon.se`, `amazon.com.be`.** Every one is tested against real captured pages, prices arrive in the store's own currency (`€`, `£`, `kr`, `zł`), and numbers are read in the store's own locale. Other Amazon domains are refused with a clear message rather than half-working. A full product URL always decides its own marketplace; the `Marketplace` setting is only for bare ASINs. European marketplaces lean on an extra recovery route for the price (see the `price` note above) — like everything else here it can fail on a bad hour, and failed items are never charged.

### Error codes — what each uncharged row means

| `status` | What happened | Charged | Worth re-running |
|---|---|---|---|
| `ok` | Complete product row | yes | — |
| `blocked` | Amazon asked us to prove we are not a robot, on every route we tried | no | yes |
| `not_found` | No product page at that id on that marketplace | no | no |
| `unavailable_in_marketplace` | Amazon did not serve that id in that country's catalogue — it usually exists in another one | no | no, try another marketplace |
| `not_a_product` | The id is one of Amazon's own subscription plans, not a product listing — some of them rank in Best Sellers, so a category walk will hand you one | no | no |
| `parse_failed` | Amazon served a page in a layout we do not recognise. That one is on us | no | no |
| `source_unavailable` | Amazon dropped or throttled the request | no | yes |
| `invalid_input` | The value was not an ASIN or an Amazon product URL — the row says exactly why | no | no |
| `cap_reached` / `stopped_at_limit` | A limit you set stopped the run; earlier rows were delivered normally | no | see `resumeCursor` |
| `sample_note` | You set settings but no products, so the sample ran under them — the row names what you set | no | — |
| `input_note` | A limit you set was outside what this actor can do in one run, so the run continued at the nearest value it can — the row names your ask and the ceiling | no | — |

**Deliverability, stated honestly:** measured 94–97% of requested products delivered under normal conditions, and lower on amazon.com when Amazon is having a bad hour. The rest come back as uncharged rows saying which kind of miss they were. We would rather print that number than imply 100%.

### Limits are exact

**Asking for more than the ceiling is not an error.** `Max products` goes up to 5,000 per run and `Max run seconds` runs from 60 to 21,600 — ask outside either and the run continues at the nearest of those values, with one uncharged `input_note` row naming what you asked for and what bound. It is never refused and the run never fails to start.

`Max products`, `Max run seconds` and the run's own maximum total charge all stop the run *cleanly*: it still finishes as SUCCEEDED, the summary row names the one setting that stopped it, and `resumeCursor` lists what was left so a second run continues instead of repeating. The product limit is claimed at the moment a row is written, so a cap of 10 delivers 10 rows and bills 10 events even with several fetches in flight.

They hold across a restart too. Long runs get moved between servers by the platform, and a run can be resurrected with one click. When that happens the run reads back what it already delivered and continues from there: **already-delivered products are never sent twice and never billed twice**, a cap of 10 stays a cap of 10 rather than becoming 20, and `Max run seconds` counts seconds of the *run*, not of each restart.

### FAQ

**Is it legal to scrape Amazon?** Public product pages are public. This actor reads only what an ordinary browser sees, at a polite rate; it never signs in and never touches an account.

**Can I scrape Amazon without an API key?** Yes — that is what this is. No Amazon account, no PA-API keys, no seller credentials.

**How do I get Amazon product data into n8n or Make?** Run this actor and read its dataset. One row per product, stable column names, `charged` on every row.

**What does Amazon Product Scraper cost per 1,000 products?** From $3.00/1,000 on Silver and above; see the ladder above. Nothing else is billable.

**Why is my price null?** Amazon did not display one — see `priceNote` on that row.

**Why did an ASIN come back as `unavailable_in_marketplace`?** It exists in a different country's catalogue. Pass the product URL for that marketplace, or change the `Marketplace` setting.

### Honesty contract

Amazon changes its pages often. When an item can't be fetched or parsed we return it with an honest status and **never charge for it**.

This actor may fail when the platform changes things — failed items are never charged.

A product is charged once per run, and once only. That holds whether you sent it as an ASIN and again as a URL, or the run was migrated, restarted or resurrected part-way through.

If a field ever comes back empty that should not be, open an issue with the ASIN and it gets fixed.

### Steadyfetch Amazon suite

One actor per entry point, the same product row underneath. All-inclusive pay per event, no start fee,
charged only on delivery.

| What you paste | Actor |
|---|---|
| ASINs or product URLs | **this actor** |
| Search keywords | [Amazon Search Results Scraper — Full Product Row, Flat Fee](https://apify.com/steadyfetch/amazon-search-scraper) |
| A Best Sellers category | [Amazon Best Sellers Scraper — Top 60 Ranks, Full Product Row](https://apify.com/steadyfetch/amazon-bestsellers-scraper) |
| A seller ID or storefront | [Amazon Sellers Scraper — Profile + Live Listings, Flat Fee](https://apify.com/steadyfetch/amazon-seller-scraper) |

**The rest of the steadyfetch shelf** — same contract everywhere: all-inclusive pay per event,
no start fee, charged only on delivery.

| Family | Actors |
|---|---|
| Ad creative intelligence | [Facebook](https://apify.com/steadyfetch/facebook-ads-transcript-scraper) · [Google Ads video](https://apify.com/steadyfetch/google-ads-video-transcript-scraper) · [TikTok](https://apify.com/steadyfetch/tiktok-ads-transcript-scraper) · [LinkedIn](https://apify.com/steadyfetch/linkedin-ads-transcript-scraper) · [Google Ads text & OCR](https://apify.com/steadyfetch/google-ads-creative-text-scraper) |
| Trends & keywords | [Google Trends](https://apify.com/steadyfetch/google-trends-scraper) · [Trends Now](https://apify.com/steadyfetch/google-trends-now-scraper) · [Breakout keywords](https://apify.com/steadyfetch/breakout-keywords-scraper) · [Autocomplete keywords](https://apify.com/steadyfetch/google-keyword-suggest-scraper) · [Keyword volume & CPC](https://apify.com/steadyfetch/keyword-search-volume-scraper) · [Social trends](https://apify.com/steadyfetch/social-trends-scraper) |
| YouTube transcripts | [YouTube videos](https://apify.com/steadyfetch/youtube-transcript-scraper) · [YouTube channels](https://apify.com/steadyfetch/youtube-channel-transcripts) |
| Instagram | [Reel transcripts](https://apify.com/steadyfetch/instagram-reel-transcript-scraper) · [Profile posts](https://apify.com/steadyfetch/instagram-profile-posts) |
| Jobs | [Indeed](https://apify.com/steadyfetch/indeed-jobs-scraper) · [Career sites by domain](https://apify.com/steadyfetch/company-jobs-by-domain) · [Glassdoor](https://apify.com/steadyfetch/glassdoor-jobs-scraper) · [Multi-board](https://apify.com/steadyfetch/multi-job-board-scraper) · [Google Jobs](https://apify.com/steadyfetch/google-jobs-scraper) |
| **Amazon** | [Products](https://apify.com/steadyfetch/amazon-product-scraper) · [Search](https://apify.com/steadyfetch/amazon-search-scraper) · [Bestsellers](https://apify.com/steadyfetch/amazon-bestsellers-scraper) · [Sellers](https://apify.com/steadyfetch/amazon-seller-scraper) |
| Any media file | [Speech to Text · any link or file](https://apify.com/steadyfetch/media-transcriber) |

### Feedback & support

Found an issue? Open it on the **Issues tab** — we usually reply within a couple of hours, always within a day. Include the ASIN or URL you used. Fields that come back empty when they should not are treated as bugs, not as expected behaviour. If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

# Changelog

This Actor's version history is a separate document: https://apify.com/steadyfetch/amazon-product-scraper/changelog.md

# Actor input Schema

## `products` (type: `array`):

ASINs (B0DN4BG1RW) or Amazon product URLs (https://www.amazon.com/dp/B0DN4BG1RW), including /gp/product/ links and amzn.to or a.co short links, in any casing. A product Amazon blocked, one with no page at that id, and one we could not read are never charged — each comes back as a row naming which. A keyword belongs in steadyfetch/amazon-search-scraper, a Best Sellers link in steadyfetch/amazon-bestsellers-scraper, a seller id or storefront in steadyfetch/amazon-seller-scraper. Send the field as a list — leaving it out is fine, but this one field cannot be null. Every optional field below accepts null — the Marketplace dropdown included — and null there simply means "use the default". A dropdown value that is not on its list is answered with one uncharged row naming the values that work, never quietly swapped for the default. Leave this untouched and click Start to run a one-product sample (B0DN4BG1RW on amazon.com).

## `marketplace` (type: `string`):

Which Amazon store to look a bare ASIN up in. A full product URL always wins over this setting. Amazon runs a separate catalogue per country, so the same id can exist in one store and not another. The domain, the country code or the country name all work — amazon.co.uk, GB and United Kingdom are the same store. Null or empty means amazon.com; a store that is not on this list is answered with one uncharged row naming the stores that are. Pick a store with Products left empty and the one-product sample runs on that store.

## `maxItems` (type: `integer`):

Hard cap on delivered products for this run. 0 means every product you listed. Up to 5,000 per run — ask for more and the run continues at 5,000, with one uncharged row saying so.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly before this and reports what is left, instead of being killed by the platform timeout. Between 60 and 21,600 seconds — ask outside that and the run continues at the nearest of the two, with one uncharged row saying so.

## `includeVariants` (type: `boolean`):

Every colour, size or flavour of the product, with its own ASIN. Turn off for a smaller row; the price does not change.

## `includeSpecs` (type: `boolean`):

The product-details table (brand, model, dimensions, materials and so on). Turn off for a smaller row; the price does not change.

## Actor input object example

```json
{
  "products": [
    "B0DN4BG1RW",
    "https://www.amazon.de/dp/B0DBLN4C47"
  ],
  "marketplace": "amazon.com",
  "maxItems": 0,
  "maxRunSeconds": 3600,
  "includeVariants": true,
  "includeSpecs": true
}
```

# Actor output Schema

## `products` (type: `string`):

One row per product: price, currency, list price, stock, buy-box seller, rating, reviews, bought-last-month, variants, bestseller ranks, category path, images, bullet points and the specifications table. Every row carries `charged` and `status`, so the invoice reconciles from the dataset itself.

## `unchargedRows` (type: `string`):

Products that could not be delivered: blocked by Amazon, no product page, not in that marketplace's catalogue, one of Amazon's own subscription plans rather than a product, or a layout we could not read. Each says which it was, whether re-running is worth it, and none of them were charged.

## `summary` (type: `string`):

Products delivered, uncharged misses by kind, duplicates merged, what stopped the run, and the charged-event totals.

## `errors` (type: `string`):

Present only when Amazon blocked, throttled or dropped a request after every route was tried: the input and the reason. These are re-runnable, not permanent.

# 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 = {
    "products": [
        "B0DN4BG1RW",
        "https://www.amazon.de/dp/B0DBLN4C47"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/amazon-product-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 = { "products": [
        "B0DN4BG1RW",
        "https://www.amazon.de/dp/B0DBLN4C47",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("steadyfetch/amazon-product-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 '{
  "products": [
    "B0DN4BG1RW",
    "https://www.amazon.de/dp/B0DBLN4C47"
  ]
}' |
apify call steadyfetch/amazon-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyfetch/amazon-product-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/iBrxRadKJl4dKaPEy/builds/Mk7AfwQkfmMH0e1qI/openapi.json
