AliExpress Search
Find winning products for dropshipping, track how a keyword's prices and best sellers move, or feed a product research agent. Type keywords and get the AliExpress search results as one JSON row per product: title, price, original price and discount, units sold, rating, ship-from country, delivery estimate, ad flag and the position in the results.
Sample output
One row as the API returns it. Long text is shortened here; names inside text read [name].
| Field | Value |
|---|---|
| rowType | product |
| platform | aliexpress |
| productId | 1005007097199333 |
| title | Wireless LED Night Lights Motion Sensor Lights Closet Kitchen |
| url | https://www.aliexpress.com/item/1005007097199333.html |
| price | 0.33 |
| currency | USD |
| originalPrice | 5.36 |
| discountPercent | 93 |
| soldText | 100K+ sold |
| soldMin | 100,000 |
| soldCount | 241,114 |
Call it from code or from your agent
This is the request. Small runs answer in the same call; large ones return a run ID.
curl -X POST https://scrapers-api.arcadiumdata.io/v1/scrapers/aliexpress-search/runs \
-H "Authorization: Bearer $ARCADIUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"searchTerms": [
"phone case"
],
"maxResultsPerTerm": 30,
"sort": "relevance"
}
}'What each row holds
Every row says what it is in rowType: product rows are charged, coverage and error rows are free.
The product 44 fields
| Field | Type | What it holds |
|---|---|---|
| statedResults | validation_report rows: result count AliExpress states for the term across all pages, e.g. 48213; null when not stated. | |
| sampleSize | validation_report rows: product rows of this run the report is computed from (= delivered products for the term). | |
| sort | validation_report rows: sort order of the sample: relevance, orders, priceAsc or priceDesc. | |
| 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. | |
| newUserPromoShare | validation_report rows: share (0-1) of the sample that showed AliExpress' new-user promo price (promoType 'new_user'). | |
| discountStats | validation_report rows: { shareDiscounted (0-1, share of products with a discount), medianPercent (median discount in %) }. | |
| 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. | |
| salesConcentration | validation_report rows: share of the sample's units sold held by the top 1, 5 and 10 products (0-1) and the HHI (0-1; above 0.25 = a few listings own the demand). Search cards carry no seller id, so this is per product, not per seller. | |
| adShare | validation_report rows: share (0-1) of paid placements in the sample; null when includeAds was off. | |
| choiceShare | validation_report rows: share (0-1) of the sample showing the Choice badge. | |
| freeShippingShare | validation_report rows: share (0-1) of the sample showing free shipping. | |
| ratingStats | validation_report rows: { productsRated, ratedShare (0-1), mean, median, share45Plus, share40To45, shareBelow40 (0-1 of rated products) } on the 1-5 star scale. Null when no product is rated. | |
| shipFromMix | validation_report rows: warehouse countries [{ country, share (0-1) }], biggest first, over products that state one. | |
| deliveryMaxDaysMedian | validation_report rows: median of the slowest delivery estimate in days. | |
| trends | validation_report rows: 12-month Google Trends interest of the term { geo, timeRange, monthly [{ month 'YYYY-MM', value 0-100 }], average, slopePerMonth (index points per month), lastVsFirstQuarterPct, direction rising|flat|falling }; null unless trendsStatus is ok. | |
| trendsStatus | validation_report rows: ok, no_data (too few searches for Trends) or unavailable (Trends rate-limited the request; the rest of the report is complete). | |
| generatedAt | validation_report rows: ISO timestamp of the report. | |
| platform | string | Always 'aliexpress'. |
| productId | string | AliExpress item id (the 1005... number in the product URL). |
| title | string | Product title as listed. |
| url | string | Product page URL. |
| price | number | 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. |
| priceMax | Highest variant price in USD; equals price when there is one price; null with price. | |
| currency | string | Currency code of the prices, normally USD. |
| originalPrice | number | Struck-through list price in USD as the card shows it. |
| discountPercent | number | Discount off originalPrice in percent. Null on new-user promo cards (the shown discount is the promo's). |
| promoPrice | AliExpress' new-user welcome price shown to first-time visitors, e.g. 1.09 (USD). Set only when promoType is set; price then holds the struck-through regular price. | |
| promoType | 'new_user' when the card carries AliExpress' new-user / welcome-deal marker, else null. | |
| soldText | string | Units sold as shown on the site, e.g. '20K+ sold'. |
| soldMin | number | Number parsed from soldText. A lower bound when soldText ends in '+'. |
| soldCount | number | The site's exact unrounded sold counter, when the listing carries it. |
| rating | number | Average star rating, 1 to 5. |
| imageUrl | Main image URL. | |
| shipFrom | string | Warehouse country code (e.g. 'CN', 'US') when the listing states it. |
| freeShipping | True when shipping to the US is free. | |
| deliveryText | Delivery estimate as shown, e.g. a date range. | |
| deliveryMinDays | Fastest estimated delivery in days. | |
| deliveryMaxDays | Slowest estimated delivery in days. | |
| isChoice | True when the listing carries AliExpress' Choice label. | |
| isAd | boolean | True when the listing is a paid placement. |
| looseMatch | True when AliExpress found few or no real matches and listed loosely related products instead. | |
| searchTerm | string | The keyword that produced this row. |
| searchRank | number | 1-based position in the results for searchTerm, ads included. |
| scrapedAt | ISO timestamp of when the row was collected. |
Error rows, free 3 fields
| Field | Type | What it holds |
|---|---|---|
| input | Error and coverage rows: the input (URL, id or search text) the row is about. Example: 'https://www.example.com/page'. | |
| code | Error rows: machine-readable reason. One of invalid_input (fix the input), not_found (page does not exist), blocked (site refused, retry later), unavailable (temporary error, retry later), filter_unsupported (the filter cannot be applied on this site), no_match (name search found nothing). | |
| message | Error rows: short human-readable explanation. Do not parse it, use code. |
What it can't do
- It does not return seller contact details such as names, emails or phone numbers.
- Prices are what the site shows at run time, in the currency the site shows.
- It reads only what the site shows to a visitor without an account.
What you send
Every field is optional. The example request above fills the ones shown here.
| Field | Type | What it does |
|---|---|---|
| searchTerms | array | Keywords to search AliExpress for, for example "phone case". Each term is searched on its own and every product keeps the term and its position in the results. Also read from keywords, searchQueries or queries. |
| maxResultsPerTerm | integer | How many products to return per search term, for example 120. Default: 60. A results page holds about 60 products and AliExpress shows at most 60 pages, so 3,600 is the ceiling. Also read from maxItems, maxResults or maxProducts (other AliExpress actors' names; 0 = the ceiling). |
| sort | string (one of 8) | Best match (the site's default), most orders, or price, for example orders. Default: relevance. The other AliExpress actors' values default, price_asc and price_desc are accepted too, and rating is read as relevance (also under the name sortBy). |
| freeShipping | boolean | Only products that ship for free. Default: false. Also read from freeShippingOnly. |
More options (7)
| Field | Type | What it does |
|---|---|---|
| minPrice | number | Only products priced at or above this amount (in the shop currency, US dollars). Filtered result pages hold fewer products, so a run may need more pages to reach the maximum. Example: 2. Also read from priceMin. |
| maxPrice | number | Only products priced at or below this amount (US dollars), for example 10. Also read from priceMax. |
| shipFrom | string | Two-letter code of the warehouse country, for example CN or US. Leave empty for all. Also read from shipFromCountry. |
| includeAds | boolean | Sponsored products are part of the search results. Each row has an isAd flag; turn this off to drop them (they still count towards the position).Default true |
| includeValidationReport | boolean | Default off. On: one extra `validation_report` row per term, charged as its own event ($0.02 per report), computed from that term's product rows: stated result count, price p10/median/p90 per currency, sold-count distribution, sales concentration in the top products, ad, Choice and free-shipping shares, rating bands, and 12-month Google Trends interest with its slope. Use 300+ results per term for a stable picture.Default false |
| trendsGeo | string | Example: `US`. Two-letter country code for the Trends part of the validation report; empty = worldwide. Ignored when the report is off.Default "" |
| includeErrorRows | boolean | Adds a free row for every term that returned nothing or could not be read, so a failure is never silent.Default true |
Questions people ask before they top up
What does a run cost?
Each product costs $0.00125, which is $1.25 per 1,000. A run that delivers rows also pays a $0.001 start fee.
Validation report: $0.02 each.
A run that returns rows costs at least $0.005, start fee included. Failed runs, empty runs and duplicate rows cost $0. You set the most a run may cost, and it stops there.
Do you ever return personal data?
Not about reviewers or users. Reviewer names, profile links, photos, emails and phone numbers are not collected. When a name appears inside a review or a reply, it is replaced with [name].
Job titles and company sizes stay where a site shows them, because they describe a role rather than a person. On YouTube, channel names and URLs are the publisher labels YouTube shows publicly.
How fresh is the data?
Each run reads the live site when you start it, so rows are as current as the site itself.
More from E-commerce sourcing
Price tiers, minimum order, units sold, repurchase rate, supplier scores
$1.50per 1,000 products
Price, sale price, favorites, tags, materials, shipping
$3.50per 1,000 listings