# 1688 Wholesale Scraper API (`dami_studio/1688-wholesale-scraper`) Actor

Scrape 1688.com wholesale listings: product ID, title, unit price, quantity price tiers, minimum order quantity, supplier company, sales counts, service rating, image and product URL.

- **URL**: https://apify.com/dami\_studio/1688-wholesale-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (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

Pay per event

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/platform/actors/running/actors-in-store#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

## 1688 Wholesale Scraper API

Search 1688.com — Alibaba's domestic Chinese wholesale marketplace — and get structured product rows
back: offer ID, title, unit price, the full quantity price ladder, minimum order quantity, the
supplier company, sales counts, the seller's service rating, product image and product URL.

No 1688 account, no cookies, no captcha solving, no proxy of your own. Type a search term, get rows.

### Price

**$0.35 per 1,000 products**, plus $0.001 to start a run.

That is the lowest price for 1688 product data on Apify. The cheapest other 1688 scraper charges
$0.45 per 1,000; the cheapest one with a real user base charges $0.63; the most-installed one charges
$4.99. You are charged per product row returned — a run that finds nothing costs only the start fee,
and diagnostic rows are never charged.

| Products | Cost |
|---|---|
| 500 | $0.18 |
| 2,000 | $0.70 |
| 10,000 | $3.50 |
| 100,000 | $35.00 |

### What a row looks like

A real row from a run on `手机壳` (phone case):

```json
{
  "offerId": "822216254820",
  "title": "适用苹果16PROMAX皮纹简约纯色手机壳iphone11/13防摔tpu保护套",
  "productUrl": "https://detail.1688.com/offer/822216254820.html",
  "price": 1.5,
  "priceMin": 1,
  "priceMax": 1.5,
  "currency": "CNY",
  "priceTiers": [
    { "minQuantity": 1,     "maxQuantity": 499,   "quantityLabel": "1~499",     "price": 1.5 },
    { "minQuantity": 500,   "maxQuantity": 99998, "quantityLabel": "500~99998", "price": 1.2 },
    { "minQuantity": 99999, "maxQuantity": null,  "quantityLabel": "≥99999",    "price": 1 }
  ],
  "minOrderQuantity": 1,
  "unit": "个",
  "salesCount": 14821,
  "repeatPurchaseRate": "13%",
  "rating": 4.5,
  "ratingBreakdown": { "goods": 3.67, "logistics": 3.57, "consultation": 4.5, "dispute": 4, "afterSales": 4 },
  "supplierName": "广州市艾尚数码科技有限公司",
  "supplierUrl": "https://m.1688.com/winport/b2b-2206457435068a76ea.html",
  "supplierProvince": "广东",
  "supplierCity": "广州市",
  "supplierYears": 7,
  "supplierId": "b2b-2206457435068a76ea",
  "businessType": "生产加工",
  "isFactory": true,
  "buyerProtections": ["7天包换", "48小时发货", "诚e赊"],
  "imageUrl": "https://cbu01.alicdn.com/img/ibank/O1CN01NThc6r1nJCEvpDbJH_!!2206457435068-0-cib.jpg",
  "isAd": false,
  "searchKeyword": "手机壳",
  "page": 1,
  "position": 2,
  "scrapedAt": "2026-08-09T06:33:01.546Z"
}
```

The price ladder is the reason most people scrape 1688: `price` is what one unit costs at the
smallest order, and `priceTiers` is the discount schedule as the order grows. `priceMin` and
`priceMax` are the ends of that ladder, so you can sort by best-case unit cost without unpacking it.

#### Field coverage

Measured over a real 500-row run, not estimated:

| Field | Present |
|---|---|
| `offerId`, `title`, `price`, `productUrl`, `minOrderQuantity`, `unit` | 100% |
| `salesCount`, `repeatPurchaseRate`, `rating`, `ratingBreakdown` | 100% |
| `supplierName`, `supplierId`, `supplierYears`, `imageUrl` | 100% |
| `buyerProtections` | 99% |
| `supplierProvince`, `supplierCity` | 98% |
| `businessType` | 85% |
| `priceTiers` | 74% |

`priceTiers` is empty on the rest because those sellers list a single price with no quantity breaks —
an empty array is the honest answer, so no tier is invented. Missing values are `null`, never a guess.

### Input

| Field | What it does |
|---|---|
| `searchTerms` | Search terms. Chinese terms match far more than English ones — `手机壳` returns a fuller catalogue than "phone case", though both work. |
| `startUrls` | Or paste 1688 search URLs. 1688 encodes its URLs as GBK rather than UTF-8, which this decodes correctly. |
| `maxItems` | Total products across all terms. Default 40. |
| `sortBy` | `relevance` (default), `priceAsc`, `priceDesc`. |
| `minPrice` / `maxPrice` | Price bounds in CNY. |
| `requestDelayMs` | Gap between requests. Default 1500; lower it to go faster. |

```json
{
  "searchTerms": ["手机壳", "连衣裙"],
  "maxItems": 2000,
  "sortBy": "priceAsc",
  "maxPrice": 50
}
```

Run it with no input and you get one labelled sample row, uncharged, so you can see the shape before
spending anything.

### Limits

Read this part before you build on it.

- **2,000 products per search term.** 1688 stops serving results at that depth no matter how you
  page through them. It reports "2,000 matches" for any broad term, which is a ceiling, not a count.
  To go wider, pass more terms — narrower ones return different products, not the same 2,000.
- **`sortBy: "booked"` is not offered.** 1688 accepts a best-selling sort and then returns
  `salesCount: 0` on every row it gives back — 100 of 100, against 96 of 100 on relevance. Shipping
  it would mean handing you a sales ranking whose sales figures are all zeroes.
- **Prices are CNY, ex-factory.** No shipping, no tax, no export handling. A 1688 price is what a
  domestic Chinese buyer pays at the warehouse door.
- **About 1–2% of rows are paid placements.** They are real listings and are marked `isAd: true`, so
  you can filter them rather than wonder about them.
- **No per-product detail fetch.** Everything above comes out of the search response, which is why a
  2,000-row pull is 40 requests instead of 2,040. Full specification tables and description images
  live on the product page and are not included.
- **Titles and supplier names are Chinese.** They are returned verbatim, untranslated.
- **`minOrderQuantity: 0`** means the seller stated no minimum, not that the field is missing.

### FAQ

**Do I need a 1688 or Alibaba account?**
No. Nothing to log in to, and nothing to solve.

**Do I need Chinese proxies?**
No — and this is the part most 1688 scrapers get wrong. See "How it works" below.

**How fast is it?**
1,941 products in 71 seconds in testing, on the default settings.

**What does it cost to scrape 1,000 products?**
$0.35, plus the $0.001 start fee.

**Can I search in English?**
Yes, and it returns real results. Chinese terms return substantially more of the catalogue, because
that is how sellers write their titles.

**Is 1688 the same as Alibaba.com?**
No. Alibaba.com is the English-language export site; 1688 is the domestic Chinese one, generally with
lower prices and lower minimum orders, aimed at buyers inside China.

**Can I export to CSV or Excel?**
Yes — Apify exports the dataset as JSON, CSV, Excel or XML, with a REST endpoint for the same data.

**Is this affiliated with 1688 or Alibaba?**
No. It reads public listing data. Check 1688's terms and your own local rules before using the output
commercially.

### How it works

1688's website sits behind Alibaba's "punish" gate, and it is unusually aggressive. A US datacenter
address is challenged on the first request. Renting mainland-Chinese addresses does not fix it
either: five Guangdong addresses tested against the search page ran clean for two or three requests
each and then returned a challenge page on everything afterwards, still blocked half an hour later.
This is why 1688 scrapers are typically expensive — they pay for headless browsers and residential
Chinese bandwidth to fight that gate, and pass the cost on.

This scraper does not touch the website. It talks to the JSON API behind 1688's mobile site, which is
a different gate entirely — the same addresses that were permanently blocked on the search page
answer it normally, and an ordinary datacenter address runs forty-plus pages without a challenge. No
browser is launched, no Chinese IP is rented, and no residential bandwidth is billed.

That is the whole reason this can be the cheapest 1688 scraper on the platform and still be
profitable: the expensive part of the problem is avoided rather than paid for.

# Actor input Schema

## `searchTerms` (type: `array`):

What to look for on 1688, one term per line. Chinese terms match far more inventory than English ones — "手机壳" returns millions of offers where "phone case" returns a few thousand. Both work.

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

Optional. Paste 1688 search pages, for example https://s.1688.com/selloffer/offer\_search.htm?keywords=phone%20case. The keyword is read out of the URL. Works alongside the field above.

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

Hard cap on rows returned across all terms (1-1000). 1688 itself stops paginating at 1,000 offers per term. You are charged per product returned.

## `sortBy` (type: `string`):

How 1688 should order the results before the actor reads them.

## `minPrice` (type: `string`):

Optional. Only return offers at or above this yuan price, for example 5.

## `maxPrice` (type: `string`):

Optional. Only return offers at or below this yuan price, for example 20.

## `requestDelayMs` (type: `integer`):

1688 rate-limits hard. The actor already spreads requests across several hosts and exit addresses; raise this if a run stops early with a BLOCKED row.

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

Optional. The actor ships with its own egress addresses; leave this alone unless you want to run through your own proxies (useful for high-volume runs, since 1688's per-address quota refills slowly).

## Actor input object example

```json
{
  "searchTerms": [
    "手机壳"
  ],
  "startUrls": [],
  "maxItems": 40,
  "sortBy": "relevance",
  "requestDelayMs": 1500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "searchTerms": [
        "手机壳"
    ],
    "startUrls": [],
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/1688-wholesale-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 = {
    "searchTerms": ["手机壳"],
    "startUrls": [],
    "maxItems": 40,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/1688-wholesale-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 '{
  "searchTerms": [
    "手机壳"
  ],
  "startUrls": [],
  "maxItems": 40,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dami_studio/1688-wholesale-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/1688-wholesale-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/XAMUGycrOObBoTwZN/builds/cbWYO29FdY2O97qxw/openapi.json
