# Alibaba Products Scraper: Wholesale Prices, MOQ & Suppliers (`hyperbach/alibaba-scraper`) Actor

Scrape Alibaba.com product search results by keyword or URL: wholesale price range and currency, minimum order (MOQ), title, URL, images, certifications, sold count, and the supplier's name, country, years on Alibaba, verified badges and rating. Several searches per run, a max per search.

- **URL**: https://apify.com/hyperbach/alibaba-scraper.md
- **Developed by:** [Hyperbach](https://apify.com/hyperbach) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 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

## Alibaba Products Scraper: Wholesale Prices, MOQ & Suppliers

**The product listings of any Alibaba.com search, logged out: search words or search URLs in, one row per product out — the product's id and URL, title, price or price range and currency, minimum order with its quantity and unit, the main image and the gallery, certifications and the sold count where the listing shows them, the ad flag, and the supplier's name, id, country, years on Alibaba, store URL, verification badges with the auditor, and store rating with its review count — several searches in one run, a max per search.** One free `search` row per input carries a completeness verdict: COMPLETE (Alibaba's own end of the list), CAPPED (your limit), TRUNCATED (Alibaba's own depth limit, with its count) or PARTIAL. No login, no API key, no browser, proxies handled for you.

### Why this Alibaba scraper

- **Several searches in one run.** Give search words (`led strip light`) or search URLs from your browser (`https://www.alibaba.com/trade/search?SearchText=led+strip+light`, with the filters you set there): each search gets its own cap (`maxItemsPerQuery`), and the run's cap sits on top (`maxItems`).
- **The fields the listing shows.** The product's id and URL, title, price as shown (`$0.45-1.04`) with its low and high number and the currency, the minimum order (`Min. order: 5 meters`) with its quantity and unit, the main image and the gallery in full size, the certifications (CE, RoHS …) and the sold count where the listing shows them, the ad flag, and the supplier: name, company id, country, years on Alibaba, store and profile URLs, the Verified badge with its auditor (TÜV Rheinland, SGS …), the Verified Pro and Gold badges, and the store rating with its review count.
- **Deep searches, checked.** 48 products a page in Alibaba's own order, page after page, to Alibaba's own end of the list. Alibaba counts hundreds of thousands of results for a broad search but lists about 1,700 of them to a reader (about 36 pages, measured 2026-10-22); the free `search` row says so (TRUNCATED, with Alibaba's count). A product Alibaba repeats on a later page is delivered and charged once.
- **Honest runs.** A URL that is not a product search, or an empty query, is a free `invalid` row; a repeated search a free `duplicate` row. Every input gets a row; a product is charged once a run, also when two searches list it. Prices are the US view in US dollars on every row.
- **Fast.** Plain HTTP, the search page Alibaba serves to a browser: 180 products of three searches took 10 calls and 14 s on our test.

### Who it's for

- **Importers and sourcing teams** — a shortlist of suppliers for a product: prices, minimum orders, the supplier's country, years on Alibaba and verification, side by side for every search.
- **E-commerce and dropshipping sellers** — the price ranges and minimum orders of a product category, read again on a schedule to see what moved.
- **Researchers and data teams** — typed rows keyed by `product_id` and `supplier_id`, a free row per search with the verdict, and a run summary to check a pipeline against.

### Quick start

**The first 100 products of a search**

```json
{
  "searchQueries": [
    "led lights"
  ],
  "maxItemsPerQuery": 100
}
```

**Three searches, 50 products each**

```json
{
  "searchQueries": [
    "insulated water bottle",
    "cnc machine",
    "phone case"
  ],
  "maxItemsPerQuery": 50
}
```

**A search URL with its filters**

```json
{
  "startUrls": [
    "https://www.alibaba.com/trade/search?SearchText=solar+panel&verifiedSupplier=true"
  ],
  "maxItemsPerQuery": 100
}
```

### Output

One row per product (and one free search row per input):

| field | meaning |
|---|---|
| `row_type` | `product` (one product, charged) or `search` (the input's row with the walk's verdict; free). |
| `input_index` | The 1-based position of the input this row answers: `searchQueries` first, then `startUrls`. |
| `input_value` | The input as you gave it (the search words or the URL). |
| `input_kind` | Which input it came from: `query` (`searchQueries`) or `url` (`startUrls`). |
| `query` | The search's words (a URL's `SearchText`). |
| `search_url` | The search on Alibaba, as a URL you can open. |
| `status` | A search row: `ok`, `invalid`, `duplicate`, `failed` or `not_read` (see the FAQ). A product row: `ok`. |
| `status_detail` | Why a search row is not `ok`, in a sentence. |
| `scraped_at` | When the row was read (ISO 8601, UTC). |
| `position` | The product's place among this search's delivered products (1 = first), in Alibaba's order. |
| `page` | The search page the product was on (48 products a page). |
| `product_id` | Alibaba's product id (the number in the product URL). |
| `url` | The product's page on Alibaba. |
| `title` | The product's title as the listing shows it. |
| `price` | The price or price range as the listing shows it (`$0.45-1.04`, `$0.73`). |
| `price_min` | The lowest number of the price (the price itself when there is one). |
| `price_max` | The highest number of the price (the price itself when there is one). |
| `currency` | The price's currency: `USD` (every row is the US view). |
| `moq` | The minimum order as the listing shows it (`Min. order: 5 meters`). |
| `moq_quantity` | The minimum order's quantity (5). |
| `moq_unit` | The minimum order's unit (`meters`, `pieces`, `sets` …). |
| `image_url` | The product's main image, full size. |
| `images` | The listing's gallery, full size (up to six images). |
| `certifications` | The product certifications the listing shows (`CE`, `RoHS`, `FCC` …); empty when it shows none. |
| `orders` | How many units were sold, where the listing shows a sold count (`4,672 sold` = 4672); null otherwise. |
| `is_ad` | True for a sponsored listing (an ad in the search). |
| `supplier_name` | The supplier's company name. |
| `supplier_id` | Alibaba's company id of the supplier. |
| `supplier_country` | The supplier's country (ISO code: `CN`, `HK`, `US` …). |
| `supplier_years` | The supplier's years on Alibaba, as the listing shows them (`9 yrs` = 9). |
| `supplier_url` | The supplier's store on Alibaba. |
| `supplier_profile_url` | The supplier's company profile page on Alibaba. |
| `verified_supplier` | True when the listing shows the Verified badge (a third-party audit of the supplier). |
| `verified_by` | The auditor the Verified badge names (`TÜV Rheinland`, `SGS`, `Intertek` …); null without the badge. |
| `verified_pro` | True when the listing shows the Verified Pro badge. |
| `gold_supplier` | True when the listing shows the Gold Supplier badge (a paid Alibaba membership). |
| `supplier_rating` | The supplier's store rating out of 5, where it has reviews; null otherwise. |
| `review_count` | How many reviews the store rating rests on. |
| `products_count` | A search row: Alibaba's own count of results for the search (page 1); a reader is listed about 1,700 of them at most. |
| `products_delivered` | A search row: the product rows this search delivered in the run. |
| `pages_read` | A search row: the search pages read. |
| `repeats_skipped` | A search row: products skipped because an earlier page or another search of the run already delivered them. |
| `verdict` | A search row: COMPLETE (Alibaba's own end of the list), CAPPED (your limit), TRUNCATED (Alibaba's depth limit, below its own count) or PARTIAL (a refusal or the time limit). |
| `verdict_detail` | A search row: the verdict in a sentence: how many products from how many pages and why the walk stopped. |

Example record:

```json
{
  "row_type": "product",
  "input_index": 2,
  "input_value": "insulated water bottle",
  "input_kind": "query",
  "query": "insulated water bottle",
  "search_url": "https://www.alibaba.com/trade/search?SearchText=insulated+water+bottle",
  "status": "ok",
  "status_detail": null,
  "scraped_at": "2026-10-23T00:08:26Z",
  "position": 1,
  "page": 1,
  "product_id": "1600110762432",
  "url": "https://www.alibaba.com/product-detail/500ml-Business-Gift-Temperature-Display-Smart_1600110762432.html",
  "title": "500ml Business Gift Temperature Display Smart Water Bottles Double Walled Stainless Steel Vacuum Insulated Digital Cups",
  "price": "$1.98",
  "price_min": 1.98,
  "price_max": 1.98,
  "currency": "USD",
  "moq": "Min. order: 100 pieces",
  "moq_quantity": 100,
  "moq_unit": "pieces",
  "image_url": "https://s.alicdn.com/@sc04/kf/Hdf0575531be94aaab6a5e6d1905dc866R.jpg",
  "images": [
    "https://s.alicdn.com/@sc04/kf/Hdf0575531be94aaab6a5e6d1905dc866R.jpg",
    "https://s.alicdn.com/@sc04/kf/Hf0c02945ebcf4ec293045289238dbb48w.jpg",
    "https://s.alicdn.com/@sc04/kf/Hbad422a98cb64020a8d500a92280637dc.jpg",
    "https://s.alicdn.com/@sc04/kf/H962e1fef7e7f4aea9e7bf3d73db63210C.jpg",
    "https://s.alicdn.com/@sc04/kf/Hf526e390b896473a86907bf8824ea87bd.jpg",
    "https://s.alicdn.com/@sc04/kf/He1db3b1536d64662b0a15e0dc965ba58S.jpg"
  ],
  "certifications": [
    "CE"
  ],
  "orders": 343,
  "is_ad": true,
  "supplier_name": "Hangzhou Medo Import And Export Co., Ltd.",
  "supplier_id": "230538595",
  "supplier_country": "CN",
  "supplier_years": 11,
  "supplier_url": "https://medo.en.alibaba.com/",
  "supplier_profile_url": "https://medo.en.alibaba.com/company_profile.html",
  "verified_supplier": true,
  "verified_by": "SGS",
  "verified_pro": false,
  "gold_supplier": true,
  "supplier_rating": 4.8,
  "review_count": 59,
  "products_count": null,
  "products_delivered": null,
  "pages_read": null,
  "repeats_skipped": null,
  "verdict": null,
  "verdict_detail": null
}
```

### Pricing

**Pay for the products a run delivers**, plus one run start; no platform usage is billed to you. The product price falls with your Apify plan.

| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
| Product (`product`) | per 1,000 | $5.00 | $4.25 | $3.50 | $2.50 |
| Run start (`start`) | per run | $0.005 | $0.005 | $0.005 | $0.005 |

A product is **$5.00 per 1,000** on the Free plan ($0.005 a product). Each run that delivers a charged product also pays the **run start, $0.005 once**; a run that delivers no charged product pays nothing at all. So one search of 100 products costs $0.505 on the Free plan and $0.430 on Starter, and several searches in one run share one start. The free `search` row of every input, a value that is not a search (`invalid`), a repeated search (`duplicate`), a search left at the cap or the time limit (`not_read`) and a refusal the run could not pass (`failed`) are never charged. A product is charged once a run, also when several searches list it. A run that stops early (a timeout, an abort) is charged for the products it delivered. `maxItems` counts the charged rows; before the first request the log names the price of each row at your plan and the most the run can cost. Enterprise plans have their own rates: the Actor's Pricing tab shows the price for your plan.

### Usage patterns

- **Search words and search URLs** — `searchQueries` takes the words you would type in Alibaba's search box. `startUrls` takes an alibaba.com search URL as your browser shows it (`https://www.alibaba.com/trade/search?SearchText=…`); the filters it carries are kept. A product page, a supplier's store or a URL of another site is not read.
- **What a row is** — `row_type` = `product`: one product of the search, in Alibaba's order (`position`, and the `page` it was on). `row_type` = `search`: the free row of one input value — `products_count` (Alibaba's own count of results), `products_delivered`, `pages_read`, `repeats_skipped`, the `verdict` with its `verdict_detail`, and the `status` with its reason.
- **How far a search goes** — `maxItemsPerQuery` (default 100; 0 = every product the search lists) stops each search after that many new products. Alibaba lists about 1,700 products of a search to a reader (about 36 pages of 48), whatever its count says; a run that reaches that end says TRUNCATED with Alibaba's count. `maxItems` caps the charged rows of the whole run.

### Input configuration

| field | type | default | what it does |
|---|---|---|---|
| `searchQueries` | `array` |  | What to search for on Alibaba.com, one search a line (`led lights`), as you would type it in Alibaba's search box. Each search is read apart. Up to 100 searches a run (words and URLs together). An empty line gets a free `invalid` row, a search given twice a free `duplicate` row. |
| `startUrls` | `array` |  | alibaba.com search URLs, as your browser shows them: `https://www.alibaba.com/trade/search?SearchText=led+strip+light`, with the filters you set there (they are kept). A product page, a supplier's store or a URL of another site gets a free `invalid` row. |
| `maxItemsPerQuery` | `integer` | `100` | Stop each search after this many products (0 = every product the search lists). A product Alibaba repeats on a later page, or one an earlier search of the run already delivered, is skipped and not counted. Alibaba lists about 1,700 products of a search to a reader (about 36 pages of 48), whatever its own count says. |
| `maxItems` | `integer` | `0` | Stop the run after this many product rows across every search (0 = no limit). Search rows are free and not counted; a search left unread at the cap gets a free `not_read` row. |

### Errors

**A run does not fail because of your input.** When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends **Succeeded**, charges nothing, and says what to change:

- the status message starts with `INPUT REJECTED`;
- the dataset holds one row, `{"error": true, "code": "…", "message": "…"}`, and no results;
- the key-value store record `ERROR` holds the same object.

From code, check `error` on the first row before reading results.

A URL that is not an alibaba.com product search (a product page, a supplier's store, another site) is not an error: it gets one free `search` row with `status` invalid that says why, and the run goes on with the others. A run that ends **Failed** is a fault on our side, never your input; it charges nothing, and we are alerted.

### FAQ

**Which status is which?**

A search row's `status` is `ok` (products served), `invalid` (an empty query, or a URL that is not an alibaba.com product search), `duplicate` (the same search again in the input: read once), `failed` (Alibaba refused every try; free) or `not_read` (left at `maxItems`, the charge limit or the run's time limit). A product row's `status` is `ok`.

**Does it give the price tiers, the specifications and the supplier's full profile?**

No. The row carries what Alibaba's search listing shows: the price or price range, the minimum order, the images, the certifications, the sold count and the supplier's badges and rating. The price ladder by quantity, the SKUs, the specifications, the description and the supplier's full profile are on each product's own page, which this actor does not read.

**Which country's prices are these?**

The US view in US dollars, on every row (`currency` USD). Shipping to another country and other currencies are not read.

**Does it need an Alibaba account or API key?**

No. Everything is read from Alibaba's public search, logged out.

### Integration

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/alibaba-scraper').call({"searchQueries": ["led lights"], "maxItemsPerQuery": 100});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/alibaba-scraper').call(run_input={'searchQueries': ['led lights'], 'maxItemsPerQuery': 100})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### CLI

```bash
apify call hyperbach/alibaba-scraper --input '{"searchQueries": ["led lights"], "maxItemsPerQuery": 100}'
```

#### REST

```bash
curl -X POST "https://api.apify.com/v2/acts/hyperbach~alibaba-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' -d '{"searchQueries": ["led lights"], "maxItemsPerQuery": 100}'
```

### Support

apify@hyperbach.com

*This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.*

# Actor input Schema

## `searchQueries` (type: `array`):

What to search for on Alibaba.com, one search a line (`led lights`), as you would type it in Alibaba's search box. Each search is read apart. Up to 100 searches a run (words and URLs together). An empty line gets a free `invalid` row, a search given twice a free `duplicate` row.

## `startUrls` (type: `array`):

alibaba.com search URLs, as your browser shows them: `https://www.alibaba.com/trade/search?SearchText=led+strip+light`, with the filters you set there (they are kept). A product page, a supplier's store or a URL of another site gets a free `invalid` row.

## `maxItemsPerQuery` (type: `integer`):

Stop each search after this many products (0 = every product the search lists). A product Alibaba repeats on a later page, or one an earlier search of the run already delivered, is skipped and not counted. Alibaba lists about 1,700 products of a search to a reader (about 36 pages of 48), whatever its own count says.

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

Stop the run after this many product rows across every search (0 = no limit). Search rows are free and not counted; a search left unread at the cap gets a free `not_read` row.

## Actor input object example

```json
{
  "searchQueries": [
    "led lights"
  ],
  "maxItemsPerQuery": 50,
  "maxItems": 100
}
```

# Actor output Schema

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

All scraped records in the default dataset. One row per product (and one free search row per input):

## `runSummary` (type: `string`):

How the run went: product rows charged, free rows, inputs by status, the walk per search (products delivered, pages read, repeated products skipped, the verdict), the source counters (calls, served, refused, exits, rotations, bytes) and the memory watch.

# 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 = {
    "searchQueries": [
        "led lights"
    ],
    "maxItemsPerQuery": 50,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("hyperbach/alibaba-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 = {
    "searchQueries": ["led lights"],
    "maxItemsPerQuery": 50,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("hyperbach/alibaba-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 '{
  "searchQueries": [
    "led lights"
  ],
  "maxItemsPerQuery": 50,
  "maxItems": 100
}' |
apify call hyperbach/alibaba-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hyperbach/alibaba-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/zDpJxhWwpRfGWTu2T/builds/bDXm0cEaoX3K5g11k/openapi.json
