# Amazon Dropshipping Product Finder: Margin, Weight & Demand (`amazonscrapers/amazon-dropshipping-finder`) Actor

Find Amazon products worth sourcing. One row per product with price, price per unit, weight, dimensions, how many sellers are already on the listing, and how many people bought it last month. 19 marketplaces. You only pay for rows that arrive with a price.

- **URL**: https://apify.com/amazonscrapers/amazon-dropshipping-finder.md
- **Developed by:** [Amazon Scrapers](https://apify.com/amazonscrapers) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 products with a prices

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 dropshipping product finder: margin, weight, demand and competition

Give it a category, a bestseller list or a search term. Get back the four numbers
that decide whether a product is worth selling: what it sells for, what it
weighs, how many people bought it last month, and how many sellers are already on
it.

Twenty-six fields per product, nineteen marketplaces, and a price that comes from
Amazon's own buy box data rather than from anywhere else on the page.

### The four numbers, and why most tools give you two

Product research tools are good at price and rating. Those are on the search
page, so they are cheap to collect and everybody has them. They are also the two
that tell you least.

**What it weighs.** `weight` and `dimensions`. This is the number that decides
whether a product is a business. A twelve dollar item that weighs four pounds is
a different proposition from a twelve dollar item that weighs four ounces, and
the difference is your entire margin. It is on the product page and nowhere near
the search page.

**How much actually sells.** `boughtInPastMonth` is Amazon's own figure, the one
printed as "10K+ bought in past month". `estimatedMonthlySales` and
`estimatedMonthlyRevenue` turn it into money. Rank fifteen in a category where
everyone sells two hundred a month is a different business from rank two where
the leader sells four.

**How crowded it is.** `otherSellersCount` is how many sellers are already on the
listing. Four hundred reviews at 4.8 stars with nine sellers is a wall. The same
product with one seller is an opening.

**What the real price picture is.** `price` with `listPrice`, `savingsAmount`,
`discountPercent` and `pricePerUnit`. A product permanently at forty percent off
has a list price that is decoration, and the per-unit price is what a customer is
really comparing.

### Every field it returns

Twenty-six per product, chosen for one question: can I make money on this.

#### Price and offer

| Field | What it holds |
| --- | --- |
| `price` | Current price from Amazon's own buy box data **(this is what you are charged for)** |
| `listPrice` | The struck-through price, when Amazon shows one |
| `savingsAmount` | How much is off in money |
| `discountPercent` | How much is off as a percentage |
| `currency` | Three-letter code, from the page itself |
| `pricePerUnit` | Price per count, ounce, litre, whatever Amazon uses |
| `otherSellersCount` | How many other sellers offer it |

#### Demand and rank

| Field | What it holds |
| --- | --- |
| `boughtInPastMonth` | Units bought last month as a number |
| `estimatedMonthlySales` | Units, derived from the line above |
| `estimatedMonthlyRevenue` | Units times price |
| `bestsellerRanks` | Every rank with its category, not just the first |
| `rating` | Average stars, read in every shop language |
| `reviewCount` | How many ratings, as a number |

#### Stock and delivery

| Field | What it holds |
| --- | --- |
| `inStock` | True, false, or null when Amazon does not say |
| `isPrime` | Prime delivery on this offer |

#### Identity and catalogue

| Field | What it holds |
| --- | --- |
| `asin` | The product id |
| `title` | Full product title, shortened only past 1000 characters |
| `brand` | Brand name |
| `marketplace` | Which shop this row came from |
| `url` | The page this was read from |
| `scrapedAt` | Timestamp of the read |

#### Description, media and variants

| Field | What it holds |
| --- | --- |
| `image` | Main image at the largest size Amazon offers |
| `category` | The most specific category |

#### Specifications, pulled apart

| Field | What it holds |
| --- | --- |
| `weight` | Weight with its unit |
| `dimensions` | Package or product dimensions |
| `unitCount` | How many units in the pack |

### A real row

```
asin                     B0BZYCJK89
title                    Owala FreeSip Stainless Steel Water Bottle 24 oz
brand                    Owala
price                    27.99
currency                 USD
listPrice                34.99
discountPercent          20
pricePerUnit             null
otherSellersCount        3
boughtInPastMonth        30000
estimatedMonthlySales    30000
estimatedMonthlyRevenue  839700
bestsellerRanks          #1 in Water Bottles, #12 in Sports Water Bottles
rating                   4.7
reviewCount              89412
weight                   1.02 pounds
dimensions               3.5 x 3.5 x 10 inches
unitCount                1
isPrime                  true
inStock                  true
```

Thirty thousand units a month at twenty-eight dollars, one pound, three other
sellers, and eighty-nine thousand reviews. Three of those numbers say yes and one
says the door is closed. That is the whole job of this Actor: putting them on one
row so you can see both at once.

### How to read the estimates honestly

`boughtInPastMonth` is Amazon's own number and it is rounded: "10K+" becomes
10000, "50+" becomes 50. It only appears on listings with enough recent volume,
which is roughly the top of a category. An empty value means Amazon did not print
it, not that nothing sold.

`estimatedMonthlySales` is derived from that figure and inherits its roundness.
`estimatedMonthlyRevenue` is that number times the current price, which assumes
every unit sold at today's price. On a product that was on deal last week, it is
an overestimate.

Neither is a forecast and neither is a substitute for Amazon's own reports. They
are there so a category sorted by revenue puts the interesting rows near the top,
which is what you actually want from a research pass.

Reading `boughtInPastMonth` correctly took a repair worth mentioning: Amazon
splits the figure across two separate page elements, so an earlier version found
it on one product in six. It now finds it wherever Amazon prints it.

### It will not guess a price

Amazon puts up to nine price-shaped numbers on a product page. Measured on this
engine: prices read from the markup were correct zero times out of six, prices
from the buy box data Amazon itself uses were correct nine out of nine.

So the price comes from that data and nowhere else. When it is absent you get no
price rather than a wrong one, and the row still arrives with the weight, the
rank and the demand figure.

On a research pass that matters twice over: a wrong price does not just mislead
you about one product, it corrupts `estimatedMonthlyRevenue` and moves that
product up your sorted list.

**You are not charged for a row without a price.**

### What to put in

**A category or bestseller link.** This is the main way in. Paste
`https://www.amazon.com/gp/bestsellers/kitchen` or any category link and it walks
the list.

**A search term.** `insulated water bottle` becomes an Amazon search and every
result gets the full read.

**A filtered search URL.** Build the search in your browser with the price band
and the filters you want, paste the address, and this Actor continues from there.
That is usually how a real research pass starts: under twenty-five dollars, four
stars and up, Prime only.

**ASINs**, when you already have a shortlist and want the full picture on it.

### Settings worth knowing about

| Setting | What it does |
| --- | --- |
| `marketplace` | One of nineteen. Read the marketplace note below before researching a European shop. |
| `proxyCountry` | Leave empty and it follows the marketplace. |
| `maxItems` | Hard ceiling on delivered products. Zero means no ceiling. Worth setting on a research pass so a broad search cannot run away with your budget. |
| `maxItemsPerList` | How many products to take from each search or category. Prefilled at ten so your first click is quick and cheap; raise it for a real pass. |
| `maxListPages` | How deep to walk each list. |
| `lanes` | How many products are read at once. Eight by default. Sixteen roughly halves the run time and costs a few prices. |
| `maxAttempts` | Attempts per product, each from a different address. Twelve by default. |
| `residentialFallback` | Off by default. On product pages it buys almost nothing: measured 2026-08-26, it cost roughly six times as much and returned two more products out of sixty. On the search and category pages this Actor starts from, it is a different story. Measured 2026-08-30, during hours when Amazon refused every listing page with a two kilobyte stub, twenty datacenter retries returned nothing and residential returned a full page in eight attempts. Turn it on if a run comes back empty. |
| `economical` | Off by default. It would hang up before the weight arrives, which is the field you came here for. |

### How it works, in plain terms

A research pass is two jobs. First it walks the list you gave it, which is a
search page or a category page, and collects the ASINs. Then it opens every one
of those products and reads it properly.

That second half is why the weight is here and not on the search page. It is also
why this takes minutes rather than seconds: sixty products is sixty page reads,
each of which Amazon refuses roughly six times in ten on a fresh address.

So every product gets up to twelve attempts, each from a different exit address,
and the same address is never used twice in a row. Addresses that work are
remembered for the run and tried first. When refusals climb the runner slows
down. Anything still refused goes into a second pass at half speed.

The listing page gets the same treatment, and it needs it: a refused listing page
costs you every product inside it. On 26 August 2026 a category run came back
with zero products because Amazon answered the bestseller link with four
kilobytes and no error code, and the engine read that as an empty category. It
now recognises a refusal without an error code and retries it.

### Reading the run log

```
Done: 16 charged (+3 delivered without a price, free), 1 refused by Amazon, 0 other. 1055 KB per charged result, 223 attempts in total.
Exit addresses: 184 used, 2 proven good, 14 burned.
Attempts by outcome: {"refused by Amazon":146,"page did not carry the field this Actor needs":56,"http_500":3,"ok":16,"network error":2}
```

`charged` is products that came back with a price. The bracketed number arrived
complete without one and cost you nothing. On a broad search that second number
is normally a handful: searches turn up subscription pages, apps and listings
Amazon does not price.

If a run ever delivers rows and charges for none of them, the log says so in
capitals at the bottom.

### Reliability, measured

Three consecutive runs of twelve products on 26 August 2026, at the default
settings:

```
run 1   12 of 12 delivered, 7 with a price
run 2   10 of 12 delivered, 6 with a price
run 3   10 of 12 delivered, 8 with a price
```

And one run of sixty products the same day: 28 delivered,
23 with a price, in 6.0 minutes.

One thing is worth reading out of that, and it is not the one you would expect.
The sixty product run delivered 28, which sounds worse than the 32 of 36 above
until you notice what it was asked for: a category page, and Amazon only offered
28 products on it that day. A list Actor is bounded by what the list holds, so
"delivered" here means "everything that was there", not "everything we wanted".

The second is the residential switch, and the honest version is less dramatic
than it sounds. Measured 26 August on the same sixty products, twice: with the
switch off, fifty-one came back with the field this Actor charges on, for $0.0205
of platform usage. With it on, fifty-three came back, for $0.1192. Two more
products for roughly six times the cost.

That is why it is off by default. It is in your input form, so if a marketplace
is refusing almost everything you can turn it on and pay for the difference.

### What you can build with it

**A sourcing shortlist.** Walk a category, sort by revenue, filter to products
under a pound with fewer than five sellers, and you have a week of work narrowed
to an afternoon.

**A margin model.** `price`, `weight` and `dimensions` are the three inputs every
freight and fulfilment calculator asks for. Export to a spreadsheet and the model
is one formula.

**A saturation map.** `otherSellersCount` across a whole category tells you where
the crowd already is. The interesting products are the ones with demand and
without a crowd.

**A competitor's catalogue.** Search a brand name and you have every product they
list, with volume and rank on each.

**A repeat pass.** Run the same category monthly into one dataset and you can see
which products are gaining sellers, which is the earliest sign a niche is
closing.

### Working it into your stack

Every run writes to a dataset you can download as CSV, JSON, Excel or XML, or
pull through the API. For research the spreadsheet export is usually the point:
the output is flat apart from `bestsellerRanks`, which is a list.

Schedules take a cron expression. A monthly pass on the same categories, into one
named dataset, turns a snapshot into a trend without any extra work.

### Marketplaces

Nineteen, from amazon.com to amazon.co.jp, read in their own language.

Prices do not travel everywhere, and for this Actor that matters more than for
most, because price feeds the revenue estimate. Measured on 2026-08-24:

| Marketplace | Products priced |
| --- | --- |
| amazon.com | 57 of 60 |
| amazon.ca | 5 of 5 |
| amazon.co.uk | 5 of 6 |
| amazon.fr | 4 of 5 |
| amazon.it | 1 of 5 |
| amazon.es | 1 of 5 |
| amazon.de | 0 of 8 |
| amazon.com.au | 0 of 5 |

Weight, rank, ratings and demand still arrive on all of them, and rows without a
price are free. If you are researching a European marketplace, run twenty
products first and see what you get.

### Pricing

Four dollars per thousand products with a price, plus three cents to start a run.

A research pass over five hundred products costs about two dollars. You are not
charged for rows without a price or for products that never arrived, and platform
usage is included, so there is no separate compute or proxy bill.

### The rest of this family

Eleven Actors on one engine. After a research pass:

- **Amazon Niche Research** when the question is whether a whole category is
  worth entering rather than which product in it to pick.
- **Amazon Price Tracker** on the shortlist, to watch what the competition does
  before you commit.
- **Amazon Product Specs** when you need the full catalogue detail to brief a
  manufacturer.
- **Amazon Variants Scraper** because a product that looks like one listing is
  often fourteen.
- **Amazon Bestsellers Scraper** for the same depth with all sixty-four fields.

### Questions people ask

**Why is boughtInPastMonth often empty.** Amazon only prints it on listings with
enough recent volume. Empty means it did not print, not that nothing sold.

**Are the sales estimates reliable.** They are Amazon's own rounded figure times
the current price. Good enough to sort a category by, not good enough to build a
forecast on. Nothing public is.

**Why is weight empty on some products.** Amazon prints it in a detail table that
not every listing carries, and electronics carry it least. Every Actor in this
family reads it the same way, so the specs Actor will not find it either; what it
adds is the raw specification table, where you can see what Amazon did print.

**Can I filter by price or rating.** Not in the input, but you can build the
filter into a search URL in your browser and paste that. Amazon's own filters are
better than anything this Actor could reimplement.

**How many products should a research pass cover.** Two to five hundred is
typical for one category. There is no built-in ceiling; on the measured run
28 products took 6.0 minutes, so sixty is around 13.

### What it does not collect

No review text, no reviewer names, no customer questions, no seller names. You
get the aggregate rating and the count, which are facts about a product rather
than about a person.

### Legal note

This Actor reads public pages and takes product facts: prices, weights, ranks,
demand figures, offer counts. Business information about an item, not information
about a person.

You are responsible for what you do with the output. Check Amazon's terms for
your own use case.

# Actor input Schema

## `search` (type: `array`):

Anything that lists products: a plain search term ("tower fan"), an Amazon search URL, a category link, or a bestsellers page. Each one is crawled and every product found is scraped. Use this when you do not know the ASINs up front.

## `productUrls` (type: `array`):

Amazon product URLs or bare ASINs, one per line. Leave empty if you are using Search instead. Duplicates are removed so you are never charged twice.

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

Which Amazon site to read. The currency of the price follows the marketplace and the proxy country.

## `proxyCountry` (type: `string`):

Which country the requests should appear to come from. Leave empty and it follows the marketplace: amazon.de is read from Germany, amazon.co.uk from the UK. This matters more than it looks -- Amazon shows different prices, currencies and even availability depending on where you appear to be.

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

Hard ceiling on delivered products. 0 means no ceiling: the Actor keeps going until the lists run out or your limits stop it.

## `maxItemsPerList` (type: `integer`):

Products to take from each search term or category link. Up to 10000.

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

Datacenter proxies were enough in testing: 30 out of 30 products returned with zero blocks. They are the cheaper option and the default. Switch to residential if you start seeing blocked pages at higher volume. Running without any proxy stops after roughly 85-120 products, because Amazon closes the door on a single IP address for over an hour.

## `lanes` (type: `integer`):

How many products to read at the same time. Each lane uses its own exit address, so more lanes never means asking one address more often. Eight is the tested default and the most accurate. Sixteen finishes the same sixty products in about half the time, but measured on 2026-08-24 it returned six more products without a price, because Amazon strips the buy box sooner under pressure. Raise it when speed matters more than the last few prices.

## `maxAttempts` (type: `integer`):

How often to retry a product Amazon refuses, each time from a different exit IP. A refusal is a property of one address, not of the product, and a refused attempt costs about 4 KB. Twelve tries is cheap insurance against a run that comes back short.

## `residentialFallback` (type: `boolean`):

After half the attempts have failed, retry through residential addresses instead of datacenter ones. Measured 2026-08-26: residential transfer was 90 percent of the bill on a sixty product run ($0.150 of $0.167) while a run that never touched it delivered all sixty anyway. Leave it off unless you are losing products; turn it on when a marketplace refuses everything.

## `economical` (type: `boolean`):

Hang up on each product page once the price is in, instead of reading it to the end. Roughly three times less traffic and about three times faster. Measured cost: over 30 products this lost 2 ratings, 4 review counts and 1 brand, because Amazon sometimes puts the rating below the price. Prices were identical either way. Leave this off unless you only need prices and are paying per gigabyte.

## `maxListPages` (type: `integer`):

Result pages to walk per list. Up to 100. Amazon itself stops earlier on most searches.

## `minDelayMs` (type: `integer`):

Pause between products. Measured 2026-08-23: at 1-2 seconds this returned 10 of 15 products; at 8-15 seconds it returned 12 of 15 on the same list. Pace turned out to matter more than anything else. The market leader waits about 14 seconds per product.

## `maxDelayMs` (type: `integer`):

Upper bound for the pause between products. The actual pause is random between the minimum and this value, which looks less mechanical than a fixed interval.

## `retryPauseMs` (type: `integer`):

How long to wait before trying a refused product again. Kept short because the retry already switches to a different exit IP, and waiting longer only makes the run more expensive.

## Actor input object example

```json
{
  "search": [
    "https://www.amazon.com/gp/bestsellers/electronics"
  ],
  "productUrls": [],
  "marketplace": "com",
  "maxItems": 0,
  "maxItemsPerList": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "lanes": 8,
  "maxAttempts": 12,
  "residentialFallback": false,
  "economical": false,
  "maxListPages": 5,
  "minDelayMs": 8000,
  "maxDelayMs": 15000,
  "retryPauseMs": 300
}
```

# Actor output Schema

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

One row per product: margin inputs, shipping weight, competition and demand. Rows without a price are delivered in full and never charged for.

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

Counts per outcome, exit addresses used, bytes per charged result.

# 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 = {
    "search": [
        "https://www.amazon.com/gp/bestsellers/electronics"
    ],
    "productUrls": [],
    "maxItemsPerList": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("amazonscrapers/amazon-dropshipping-finder").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 = {
    "search": ["https://www.amazon.com/gp/bestsellers/electronics"],
    "productUrls": [],
    "maxItemsPerList": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("amazonscrapers/amazon-dropshipping-finder").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 '{
  "search": [
    "https://www.amazon.com/gp/bestsellers/electronics"
  ],
  "productUrls": [],
  "maxItemsPerList": 10
}' |
apify call amazonscrapers/amazon-dropshipping-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,amazonscrapers/amazon-dropshipping-finder"
        }
    }
}

```

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/oBFmqAFiIMihgiocf/builds/kbUqsM5z7JVqzgqBS/openapi.json
