Check an AliExpress product idea: prices, sales and shipping in one run
Before you order samples or list a product, you want to know what it sells for on AliExpress, how much of it sells, and whether it ships from a warehouse near your buyers. Scrolling search pages gives an impression, not numbers.
arcadium/aliexpress-search returns the search results for your keywords as rows, and with the validation report adds one summary per keyword: price percentiles, sold-count statistics, ship-from mix, ad share and Google Trends interest.
Cost of this example on the Apify Free plan: 60 × $0.00225 + 1 × $0.02 = $0.155 ($0.11 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts.
What you need
- An Apify account and API token.
- One or more keywords in English, as a shopper would type them.
Step 1: Run it in the Apify Store (no code)
- Open arcadium/aliexpress-search on the Apify Store and sign in (a free Apify account works).
- Enter the keywords in Search terms.
- Set Max results per term to 60 (about one results page) and Sort by to most orders.
- Turn on Add a market validation report per term for the per-keyword summary.
- Optional: set a maximum cost per run in the run options as a hard cap.
- Click Start. Rows appear in the Output tab; export them as JSON, CSV or Excel.
The same input as JSON (paste it in the JSON tab of the input form):
{
"searchTerms": [
"silicone baking mat"
],
"maxResultsPerTerm": 60,
"sort": "orders",
"includeValidationReport": true,
"trendsGeo": "US"
}
Step 2: Call it over the Apify API
One HTTP call runs the actor and returns its rows. It suits runs up to about five minutes; for longer runs start the run asynchronously and read the dataset when it finishes.
curl -X POST "https://api.apify.com/v2/acts/arcadium~aliexpress-search/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms":["silicone baking mat"],"maxResultsPerTerm":60,"sort":"orders","includeValidationReport":true,"trendsGeo":"US"}'
Step 3: Run it from Python
With apify-client 3.x, call() returns a Run object: read the dataset id as run.default_dataset_id (older examples use run["defaultDatasetId"], which no longer works).
# pip install "apify-client>=3"
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/aliexpress-search").call(run_input={
"searchTerms": ["silicone baking mat"],
"maxResultsPerTerm": 60,
"sort": "orders",
"includeValidationReport": True,
"trendsGeo": "US",
})
rows = list(client.dataset(run.default_dataset_id).iterate_items()) # apify-client 3.x
for rep in (r for r in rows if r.get("rowType") == "validation_report"):
print("price bands:", rep.get("priceBands"))
print("ship from:", rep.get("shipFromMix"), "ad share:", rep.get("adShare"))
products = [r for r in rows if r.get("rowType") == "product" and not r.get("isAd")]
for p in sorted(products, key=lambda r: r.get("soldCount") or r.get("soldMin") or 0, reverse=True)[:10]:
print(p["price"], p.get("soldText"), p.get("shipFrom"), p["title"][:70], p["url"])
Step 4: Run it from JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/aliexpress-search').call({
"searchTerms": [
"silicone baking mat"
],
"maxResultsPerTerm": 60,
"sort": "orders",
"includeValidationReport": true,
"trendsGeo": "US"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Step 5: Ask an AI assistant (MCP)
Apify’s hosted MCP server turns the actor into one tool. Add it to Claude, Cursor, VS Code or any MCP client:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/aliexpress-search",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}Then ask, for example:
Use arcadium/aliexpress-search with the validation report to check "silicone baking mat" on AliExpress sorted by orders. Give me the median price, the price range of the top sellers and the share shipping from outside China.
More clients and the local setup on the MCP page.
Searching by photo
This actor searches by keyword. Searching AliExpress by product photo is not part of it; describe the product in words, or start from the listing title of a competitor.
Output fields
Every row has a rowType; filter on it first. Failed inputs come back as free rows with a code and message. The fields this tutorial uses, from the actor’s dataset schema:
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. Values: 'product': one product (charged). 'validation_report': one market summary per search term, only with includeValidationReport (charged as validation-report). 'error': an input could not be read; see code and message (free). |
productId | AliExpress item id (the 1005... number in the product URL). |
title | Product title as listed. |
url | Product page URL. |
price | Regular sale price in USD (lowest when the product has variants). On a new-user promo card it is the struck-through regular price of the listed variant; null only when such a card shows no struck-through price. The promo (see promoPrice) is never put here. |
originalPrice | Struck-through list price in USD as the card shows it. |
soldText | Units sold as shown on the site, e.g. '20K+ sold'. |
soldCount | The site's exact unrounded sold counter, when the listing carries it. |
rating | Average star rating, 1 to 5. |
shipFrom | Warehouse country code (e.g. 'CN', 'US') when the listing states it. |
freeShipping | True when shipping to the US is free. |
isAd | True when the listing is a paid placement. |
priceBands | validation_report rows: per currency { currency, products, min, p10, median, p90, max } of the regular sale price, e.g. USD 2.10 / 4.99 / 12.50 (p10 / median / p90). New-user promo prices are never included. |
soldStats | validation_report rows: units sold per product { productsWithSold, totalSoldMin, min, p10, median, p90, max, share100Plus, share1000Plus (0-1 of the sample) }; counts are lower bounds ('10,000+ sold' = 10000). Null when no product shows sales. |
shipFromMix | validation_report rows: warehouse countries [{ country, share (0-1) }], biggest first, over products that state one. |
adShare | validation_report rows: share (0-1) of paid placements in the sample; null when includeAds was off. |
All fields: AliExpress Search Scraper guide.
Cost per run
Pay per event: you pay for the rows delivered, at the actor’s live Apify price on 2026-11-02. Error, coverage and summary rows are free.
| What | Rows | Price per row (Free plan) | Subtotal |
|---|---|---|---|
| Product: 60 products | 60 | $0.00225 | $0.135 |
| Validation report: 1 validation report | 1 | $0.02 | $0.02 |
Cost of this example on the Apify Free plan: 60 × $0.00225 + 1 × $0.02 = $0.155 ($0.11 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts. Higher Apify plans pay less per row. The Store page always has the current price.
Limitations
- The search page does not name the store, so this tutorial gives you products and prices, not seller contacts. Open the product
urlto see the store. - Sold counts are what AliExpress shows; many listings show a rounded band (
soldText) rather than an exact number. - Public search results only. Nothing behind a login.
- Prices are in US dollars, in the US storefront. Other currencies and shipping destinations are not available. Every request asks for the US storefront explicitly, so the ship-from filter and the prices do not depend on the country of the proxy IP.
- AliExpress shows anonymous visitors a new-user welcome price (often $1.09) on many listings, up to most of a page. Those rows carry it in
promoPricewithpromoType: "new_user";priceholds the struck-through regular price of the listed variant, which can differ from the cheapest variant on the product page. When a promo listing shows no struck-through price,priceis empty and the report's price bands skip it. AliExpress's own price filter (minPrice/maxPrice) matches the promo price, so in a filtered search promo rows can show a regularpriceabove your maximum; filter onpriceafterwards if you need the regular price in range. - The search page does not show the store, so there is no store name or id. Delivery and ship-from are missing on some listings; those fields are empty, never guessed.
- A price filter makes AliExpress return fewer products per page, so a filtered run reads more pages for the same number of rows, and the site may run out of matches before your limit.
- The results shown for a keyword are what the site decides to show at that moment: rank and ads change from run to run.
- The same product found by two keywords is returned once per keyword (its rank is different). Within one keyword it appears once.
- A keyword AliExpress cannot match gets loosely related products; those rows have
looseMatch: true. - The validation report describes the products of this run, so it follows your
sort, filters andmaxResultsPerTerm. Sold counts are the rounded bands the site shows. Google Trends is best effort: when Google rate-limits the request the report comes withtrendsStatus: "unavailable"and is charged the same.
Links
- AliExpress Search Scraper: fields, price table and sample output
- How to use AliExpress Search Scraper: every input field, n8n, LangChain
- arcadium/aliexpress-search on the Apify Store
- All tutorials