# 1688 Product Scraper - Prices, MOQ & Suppliers (`webdata_labs/1688-scraper`) Actor

Scrape 1688 by keyword, product URL or ID, and supplier shop. Get MOQ price tiers, English titles, supplier data, images, SKUs, and buying signals in API-ready output. No 1688 login required.

- **URL**: https://apify.com/webdata\_labs/1688-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 16 total users, 6 monthly users, 95.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 1688 product scrapeds

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/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 Product Scraper - MOQ Prices & Supplier Data

**Get sourcing-ready 1688 products with the full MOQ price ladder, supplier trust signals, and English titles - not a Chinese-only list with one misleading price.**

1688 is where most Western sourcing happens before it reaches Alibaba, but the data is hostile to anyone working from a spreadsheet. Titles are Chinese, the page shows a single "from" price that hides the quantity breaks you actually buy at, the minimum order quantity lives in a different block, and the supplier signals that decide whether a factory is worth an inquiry are spread across badges and tags. This Actor turns a keyword, a product URL, an offer ID, or a supplier shop into rows a sourcing agent can filter: every quantity break, the MOQ and unit, the supplier's province and city, the trust flags 1688 publishes, sold count, images, SKU variants, and a machine-translated English title next to the Chinese original.

No login. No proxy configuration. No start fee. You pay per product returned.

### ✅ What you get / ❌ What this isn't

| ✅ What you get | ❌ What this isn't |
| --- | --- |
| The **full MOQ price ladder** (`priceTiers`), every quantity break with its unit price | Not a single "from" price that collapses a three-tier ladder into one number |
| **English titles** (`titleEn`) alongside the Chinese original | Not a Chinese-only export you have to paste into a translator column by column |
| **Four entry modes**: keyword, offer URL, offer ID, supplier shop | Not a URL-only scraper that makes you find the products yourself first |
| **Sourcing filters**: price range, MOQ ceiling, supplier tier, province, city, sort | Not an unfiltered dump you pay for and then throw half of away |
| **Proxy handled for you** - CN residential sessions, included in the price | Not a form that asks you to pick a proxy country and fails when you guess wrong |
| **Zero credentials** - no login, no session cookie on the form | Not a scraper that asks for your 1688 account cookie before it will run |
| **No start fee**, billed per successfully returned product | Not a $0.0049-per-Start fee that doubles the bill on a 10-product lookup |
| **Filtered-out rows are free** - the filter runs before billing | Not a per-row charge for products that failed your own price or MOQ filter |
| Honest diagnostics in `OUTPUT` for every offer that could not be extracted | Not a silent partial run that hides what it failed to fetch |

### 🔎 Why use this 1688 scraper

- **The MOQ ladder is the product.** `priceTiers` returns every quantity break 1688 publishes, in order. A listing that shows "¥7.20" is really 20 pieces at ¥7.20, 1,000 at ¥7.00, and 10,000 at ¥6.80. Landed-cost maths on the headline price alone is wrong by the size of your order.
- **English titles for a Western spreadsheet.** `titleEn` is filled from 1688 when available and machine-translated otherwise, so the export is readable by a buyer who does not read Chinese. The Chinese `title` is kept, because that is what you paste back into 1688 or send to an agent.
- **Filters that match how sourcing actually works.** Budget ceiling (`priceMax`), MOQ ceiling (`minOrderQuantity`), supplier trust tier (`merchantType`), region (`province`, `city`), and candidate ranking (`sortBy`, including `bestSelling`). Every filter is applied before the row is billed.
- **Supplier trust signals, parsed not guessed.** `merchantSigns` exposes the flags 1688 sets on the offer page: factory-verified, 实力商家 (powerful merchant), 诚信通 (TrustPass), industry seller. `merchantTags` carries the visible badges such as 1688严选 and 深度验厂.
- **Proxy is not your problem.** 1688 serves an empty shell to traffic from outside China. The Actor always uses CN residential sessions and the cost is inside the per-product price, so there is no proxy control to misconfigure and no failure mode created by picking the wrong country.
- **Four entry modes, one output shape.** Keyword search, direct offer URL, bare offer ID, and supplier shop all produce the same row schema, so a monitoring workflow and an exploratory search can share downstream code.
- **Partial success is reported, not hidden.** Offers that hit verification or disappeared are listed in `OUTPUT.failedOffers` with a reason code and are never charged.

### 👥 Who it's for

Sourcing agents, importers, and marketplace sellers who need 1688 product economics in a spreadsheet, and developers building product-sourcing pipelines.

- Build a shortlist of suppliers for one product and compare real quantity-break pricing side by side.
- Check whether a target landed cost is reachable at your order size before you contact anyone.
- Filter a category down to factories in one province so a single freight consolidation covers the whole order.
- Refresh a tracked catalog of offer IDs on a schedule and watch price ladders and sold counts move.
- Feed normalized product rows into a catalog, an ERP, a pricing model, or an AI sourcing agent.

### Example tasks

Ready-to-run configurations. Open one, copy the input, and adapt it:

- [Find wholesale suppliers on 1688 by keyword](https://apify.com/webdata_labs/1688-scraper/examples/find-1688-wholesale-suppliers-by-keyword)
- [Search 1688 with Chinese keywords and get English titles](https://apify.com/webdata_labs/1688-scraper/examples/search-1688-with-chinese-keywords)
- [Check a 1688 product price and MOQ ladder](https://apify.com/webdata_labs/1688-scraper/examples/check-1688-product-price-and-moq)
- [Scrape all products from one supplier shop](https://apify.com/webdata_labs/1688-scraper/examples/scrape-1688-supplier-shop-products)
- [Find best-selling 1688 products under 50 CNY](https://apify.com/webdata_labs/1688-scraper/examples/best-selling-1688-products-under-50-cny)
- [Scrape verified 1688 factories only](https://apify.com/webdata_labs/1688-scraper/examples/scrape-verified-1688-factories-only)
- [Compare several 1688 offers by ID](https://apify.com/webdata_labs/1688-scraper/examples/compare-1688-supplier-offers)
- [Export 1688 SKU variants for catalog import](https://apify.com/webdata_labs/1688-scraper/examples/export-1688-sku-variants-for-catalog)
- [Source from Guangdong suppliers on 1688](https://apify.com/webdata_labs/1688-scraper/examples/source-from-guangdong-suppliers-on-1688)
- [Export 1688 products for a sourcing spreadsheet](https://apify.com/webdata_labs/1688-scraper/examples/export-1688-products-for-sourcing)

### ⚙️ How to scrape 1688 products

1. Enter what you want to scrape: search keywords, offer URLs, offer IDs, or supplier shop URLs. Any one of them is enough, and they can be combined in a single run.
2. Set the filters that describe your sourcing constraint: `priceMax` for the budget, `minOrderQuantity` for the largest MOQ you can accept, `merchantType` for the supplier tier, `province` or `city` for the region.
3. Set `maxProducts`. You are billed per returned product, so this is also your budget cap.
4. Click **Start**.
5. Open the **Output** tab and pick a view: **1688 products** for the overview, **MOQ price ladder** for quantity breaks, **Suppliers** for the trust and region columns, **SKU variants** when `includeSkuDetails` is on.
6. Export as JSON, CSV, or Excel, or pull the dataset through the API into your own workflow.

#### Chinese or English keywords? Run both

Both languages work, and the folklore that Chinese keywords always return more rows did not survive measurement. Measured on 2026-07-29 through CN residential sessions, five search pages per keyword, counting unique offer IDs, in two rounds a few minutes apart:

| Keyword | Unique offers, round 1 | Unique offers, round 2 |
| --- | ---: | ---: |
| 无线充电器 | 53 | 30 |
| wireless charger | 39 | 96 |
| 蓝牙耳机 | 20 | 25 |
| bluetooth earbuds | 38 | 38 |
| 瑜伽垫 | not measured | 44 |
| yoga mat | not measured | 45 |
| 手机壳 | not measured | 50 |
| phone case | not measured | 76 |

Round 1 says Chinese wins on 无线充电器 and round 2 says English wins on the same keyword by three times. The variance between sessions is larger than the difference between languages, because 1688's anonymous mobile search serves a partly randomized, ad-influenced slice of the catalog and recycles rows across pages.

The usable rule: **the two languages surface different offer sets, and neither is reliably larger.** For a thorough shortlist, run both and let offer-ID deduplication merge them. This is also why `translateTitles` defaults to `true`: search in whichever language you like, read the results in English.

#### Get a fresh list on a schedule

Save your input as a task, then attach a schedule to it. A weekly run over a `offerIds` list is the cheapest way to watch a tracked catalog: price ladders and `soldCount` move, and you can diff the dataset between runs. Because billing is per returned product and there is no start fee, a weekly 20-product refresh costs the same as running it once by hand.

### 📥 Input

```json
{
    "searchQueries": ["无线充电器"],
    "sortBy": "bestSelling",
    "priceMax": 50,
    "minOrderQuantity": 100,
    "merchantType": "superFactory",
    "province": "Guangdong",
    "translateTitles": true,
    "maxProducts": 20
}
```

Direct lookup by URL or ID, combined with a supplier shop:

```json
{
    "offerUrls": [{ "url": "https://detail.1688.com/offer/588600851175.html" }],
    "offerIds": ["927875250705"],
    "supplierUrls": [{ "url": "https://winport.m.1688.com/page/index.html?memberId=huanandzc" }],
    "includeSkuDetails": true,
    "maxProducts": 50
}
```

#### Entry modes

- `searchQueries` - product keywords, Chinese or English. Each query is paged through 1688's public mobile search, and the candidates are ranked by `sortBy` before any offer page is fetched.
- `offerUrls` - public product detail URLs, for example `https://detail.1688.com/offer/588600851175.html`.
- `offerIds` - bare numeric offer IDs. Use this to refresh a tracked catalog without storing URLs.
- `supplierUrls` - public `winport.m.1688.com` supplier URLs, taken from the `supplierUrl` field of any product row. The Actor follows the shop's mobile infinite-scroll pages until `maxProducts` is reached or the catalog is exhausted. Desktop `shop*.1688.com` pages redirect anonymous traffic to login and are not supported.

#### Filters

- `sortBy` - `relevance` (default), `bestSelling`, `priceAsc`, `priceDesc`. Ranking is applied by the Actor over the collected search candidates, using the transaction count and price printed on each search card, because 1688's anonymous search accepts a sort parameter and then ignores it.
- `priceMin` / `priceMax` - integer CNY bounds tested against the cheapest step of each offer's quantity ladder.
- `minOrderQuantity` - the **largest MOQ you will accept**. An offer whose minimum order quantity is above this number is dropped, and so is an offer that does not publish an MOQ at all.
- `merchantType` - `any` (default), `superFactory` (factory-verified sellers), `verifiedMerchant` (实力商家 / 诚信通 / 深度验厂 sellers).
- `province` / `city` - accepts Chinese (`广东`, `深圳`) or English (`Guangdong`, `Shenzhen`). Administrative suffixes are normalized, so `广东` matches `广东省`.

#### Output options

- `includeSkuDetails` - adds `skuVariants` (variant name, price, stock, image) and the raw `skuMatrix`. Off by default because most sourcing spreadsheets do not need the variant grid.
- `includeDescriptionHtml` - fetches the offer description document into `descriptionHtml`. One extra request per product and a large field, so it is off by default.
- `translateTitles` - fills `titleEn` with a best-effort machine translation when 1688 does not publish an English title. On by default.
- `maxProducts` - hard cap on returned products (1-500, default 20). This is your budget cap.

#### Input aliases

Input JSON written for other 1688 Actors validates here without edits:

- `keywords` and `queries` are accepted as aliases for `searchQueries` and merged with it.
- `maxResults` is accepted as an alias for `maxProducts` and takes precedence when both are present.

#### What is not on the form

- **Proxy.** There is no proxy control. 1688 requires CN residential sessions, that is a property of the target site rather than a user preference, and the cost is included in the per-product price.
- **Login.** There is no credential field on the form. Public offer pages, mobile search, and `winport` supplier pages are all readable anonymously. An advanced `sessionCookie` field exists for API callers who need a logged-in session for a restricted listing, but it is never required and is never written to logs or datasets.

### 📤 Output

| offerId | titleEn | priceMin | MOQ | priceTiers | companyName | city |
| --- | --- | ---: | ---: | --- | --- | --- |
| 588600851175 | QC3.0 charger wireless charging USB head 18W | 6.8 | 20 | 20 @ 7.20, 1000 @ 7.00, 10000 @ 6.80 | 深圳豪诺天电子有限公司 | 深圳市 |
| 773524241414 | 35W wireless charger, 30W round desktop charging | 11.5 | 2 | 2 @ 13.50, 200 @ 12.50, 1000 @ 11.50 | 深圳市雅菲电子有限公司 | 深圳市 |
| 761765041545 | Portable Wi-Fi battery charger | 8.4 | 10 | 10 @ 9.00, 1200 @ 8.80, 10000 @ 8.40 | 惠州市优仕通进出口有限公司 | 惠州市 |

#### One real product, in full

This is an unedited row (images and attributes trimmed for length, English title from the built-in translation), scraped on 2026-08-02:

```json
{
    "recordType": "product",
    "offerId": "927875250705",
    "url": "https://detail.1688.com/offer/927875250705.html",
    "title": "新款苹果18promax手机壳磁吸16防摔磨砂iphone17pm跨境保护壳批发",
    "titleEn": "New Apple 18 Pro Max phone case, magnetic, 16 shockproof matte iPhone 17 PM cross-border protective case wholesale",
    "descriptionUrl": "https://itemcdn.tmall.com/1688offer/icoss2449019772014ef5539443422d",
    "descriptionHtml": null,
    "currency": "CNY",
    "priceMin": 7.49,
    "priceMax": 7.99,
    "priceText": "7.49-7.99",
    "priceTiers": [
        {
            "minQuantity": 30,
            "price": 7.99
        },
        {
            "minQuantity": 500,
            "price": 7.79
        },
        {
            "minQuantity": 3000,
            "price": 7.49
        }
    ],
    "minimumOrderQuantity": 30,
    "unit": "个",
    "companyName": "佛山市南海区三丰手机配件有限公司",
    "sellerLoginId": "fssf06",
    "supplierUrl": "https://winport.m.1688.com/page/index.html?memberId=b2b-2850655109d72ea",
    "location": "广东省佛山市",
    "province": "广东省",
    "city": "佛山市",
    "merchantSigns": {
        "powerfulMerchant": true,
        "trustPass": true,
        "factory": true,
        "industrySeller": false
    },
    "merchantTags": [
        "1688严选",
        "镇店之宝",
        "实力商家",
        "诚信通",
        "工厂"
    ],
    "serviceScore": 4,
    "goodRate": 99.9,
    "reviewCount": 7785,
    "repurchaseRate": 67.79,
    "images": [
        "https://cbu01.alicdn.com/img/ibank/O1CN01zrqVrk1nbye1GPiPy_!!2850655109-0-cib.jpg"
    ],
    "videoUrl": "https://cloud.video.taobao.com/play/u/2850655109/p/2/e/6/t/1/538822573635.mp4",
    "soldCount": 258375,
    "skuVariants": [],
    "skuMatrix": [],
    "attributes": {
        "材质": "优质TPU",
        "工艺": "注塑",
        "款式": "后盖款",
        "品牌": "Apple/苹果",
        "功能": "防磨"
    },
    "source": "1688",
    "scrapedAt": "2026-08-02T20:12:44.019Z"
}
```

Read the ladder as: 30 pieces is the minimum order at ¥7.99 each, the price steps to ¥7.79 at 500 pieces, and to ¥7.49 at 3,000. A scraper that reports only "¥7.49" is quoting you a price you cannot buy at until you order 3,000 units.

#### Field by field

| Field | Type | What it is |
| --- | --- | --- |
| `recordType` | string | Always `product`. Lets you mix this dataset with other Actors' rows. |
| `offerId` | string | 1688 offer identifier. Stable, and the key to use for deduplication. |
| `url` | string | Canonical `detail.1688.com` offer URL. |
| `title` | string | Product title as published on 1688, in Chinese. |
| `titleEn` | string | English title from 1688 when present, otherwise a machine translation. |
| `descriptionUrl` | string | URL of the full description document referenced by the offer page. |
| `descriptionHtml` | string | Full description HTML. Populated only when `includeDescriptionHtml` is enabled. |
| `currency` | string | Always `CNY`. 1688 prices are RMB. |
| `priceMin` / `priceMax` | number | Cheapest and dearest step of this offer's own quantity ladder. Taken from `priceTiers`, so they are always prices you can actually order at. |
| `priceTiers` | array | The MOQ ladder: `{ minQuantity, price }` ordered by quantity. The most important field in the row. |
| `priceText` | string | Price range as 1688 displays it for the current SKU set, for example `7.49-7.99`. |
| `minimumOrderQuantity` | number | MOQ in `unit`s. |
| `unit` | string | Sale unit as 1688 states it (个, 件, 套, ...). |
| `companyName` | string | Supplier company name. |
| `sellerLoginId` | string | Supplier member/login ID, useful as a supplier key. |
| `supplierUrl` | string | Public `winport` shop URL. Feed it back in as `supplierUrls` to pull that supplier's catalog. |
| `location` | string | Raw location string from the offer page. |
| `province` / `city` | string | Location split into administrative parts, for grouping and freight consolidation. |
| `merchantSigns` | object | `powerfulMerchant`, `trustPass`, `factory`, `industrySeller` booleans parsed from the offer page. |
| `merchantTags` | array | Visible badges such as `1688严选` or `深度验厂`. |
| `images` | array | Full-resolution `cbu01.alicdn.com` image URLs, up to 30 per offer. |
| `videoUrl` | string | Product video URL when the offer has one. |
| `soldCount` | number | Transactions recorded on the offer. The main buying signal. |
| `repurchaseRate` | number | Percentage of buyers who ordered from this supplier again within three months. |
| `serviceScore` | number | Supplier service score out of 5, as published on the offer page. |
| `goodRate` | number | Positive review rate, in percent. |
| `reviewCount` | number | Number of buyer reviews on the offer. |
| `attributes` | object | Buyer-facing attribute name/value pairs (材质, 工艺, 适用型号, ...). |
| `skuVariants` | array | Normalized variants: `skuId`, `specAttrs`, `price`, `saleCount`, `stock`, `imageUrl`. Requires `includeSkuDetails`. |
| `skuMatrix` | array | Raw variant fragments as 1688 published them. Requires `includeSkuDetails`. |
| `source` | string | Always `1688`. |
| `scrapedAt` | string | ISO timestamp of extraction. |

Fields that a given listing does not publish come back as `null` or an empty array. The Actor does not invent values.

#### Run summary

Every run also writes an `OUTPUT` record to the key-value store:

```json
{
    "requested": 20,
    "candidates": 22,
    "products": 20,
    "filteredOut": 0,
    "errors": 0,
    "successRate": 1,
    "stoppedEarly": false,
    "filters": { "priceMax": 20, "merchantType": "any", "sortBy": "bestSelling" },
    "failedOffers": [],
    "failedDiscovery": []
}
```

`filteredOut` counts products that were fetched and then dropped by your filters. Those rows are not charged. `failedOffers` lists every offer that could not be extracted, with an error code (`SECURITY_CHALLENGE`, `PRODUCT_NOT_FOUND`, `FETCH_FAILED`, `INVALID_OFFER_URL_OR_ID`) so a failed pull is diagnosable instead of mysterious. `stoppedEarly` is `true` when the run stopped short of `maxProducts` because it was approaching its own run timeout - raise the run timeout, or lower `maxProducts`, and the rest will come back.

### 💵 How much does it cost to scrape 1688?

You pay **per successfully returned product**. Platform usage, including the CN residential proxy traffic that 1688 requires, is included in that price. There is **no Actor start fee**.

| Apify plan | Per product | Per 1,000 products |
| --- | ---: | ---: |
| Free | $0.003 | $3.00 |
| Bronze | $0.0025 | $2.50 |
| Silver | $0.002 | $2.00 |
| Gold and above | $0.0015 | $1.50 |

#### Worked example: a 10-product lookup

You want the price ladder for ten candidate offers.

| | This Actor | A competitor at $0.00499 + $0.0049 start |
| --- | ---: | ---: |
| Start fee | $0.00 | $0.0049 |
| 10 products | $0.03 | $0.0499 |
| **Total** | **$0.03** | **$0.0548** |

The start fee is 9% of that competitor's bill on a 10-product run and it is charged before a single row is returned. On a one-product spot check the gap is starker: $0.003 here against $0.0099 there, most of which is the fee for pressing Start. Small, frequent lookups are exactly what sourcing work consists of, so a start fee is the wrong shape of charge for this niche.

At 1,000 products the comparison is $3.00 against $53.89, and on a Gold plan it is $1.50 against the same $53.89, because that competitor's discount curve bottoms out at 80% of its Free price.

#### What a run costs you in practice

- Products that fail your `priceMax`, `minOrderQuantity`, `merchantType`, or region filter are **not billed**: the filter runs before the row is pushed.
- Offers that hit verification or turn out to be unavailable are **not billed**: they go to `OUTPUT.failedOffers`.
- Search pages, supplier pages, and pagination are **not billed**: only returned products are.
- `maxProducts` is a hard cap, so the maximum bill for a run is `maxProducts × your tier price`.

### 🔁 Run it on the Apify platform

Schedule recurring sourcing checks, call the Actor over REST from JavaScript, Python, or curl, and push results to Google Sheets, a database, or a webhook. Datasets export as JSON, CSV, Excel, XML, or RSS, and integrations with Make, Zapier, Airbyte, and n8n are available from the Actor's Integrations tab.

```bash
curl -X POST "https://api.apify.com/v2/acts/webdata_labs~1688-scraper/runs?token=YOUR_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"searchQueries":["无线充电器"],"sortBy":"bestSelling","priceMax":50,"maxProducts":20}'
```

#### Use with AI agents via MCP

Add Apify's MCP server to Claude Code, Claude Desktop, or Cursor, then ask the agent to run `webdata_labs/1688-scraper` with a keyword, an offer ID, or a shop URL and to analyze the returned dataset. A sourcing agent can chain it: search in Chinese, filter by MOQ and price, translate the titles, then compare the ladder against retail prices from a marketplace Actor. Keep your Apify token in the client's secret or environment-variable settings rather than in a prompt.

#### Use this Actor in n8n

Use an HTTP Request node against the run endpoint above, wait for the run to finish (or use the `run-sync-get-dataset-items` endpoint), then map the dataset items into your workflow. Store the Apify token in n8n credentials, never inside the workflow JSON. A typical n8n flow: schedule trigger, run the Actor over a tracked `offerIds` list, compare `priceTiers` against last week's values in a database node, and send a message when a supplier changes a quantity break.

### ⚠️ Limits and caveats

- **Search recall is capped by 1688's anonymous mobile search.** It returns 20 cards per page and recycles a large share of them across pages, so a single keyword typically yields 20-55 unique offers rather than hundreds. For large pulls, use several keywords, or supplier shops, or a list of offer IDs. `maxProducts` allows up to 500 but a single short keyword will not reach it.
- **1688 sometimes serves browser verification.** The Actor retries a challenged offer page, then falls back to a real browser. Offers that still fail are reported in `OUTPUT.failedOffers` and are not billed.
- **`sortBy` ranks candidates, it does not query a sorted index.** 1688's anonymous search echoes a sort parameter back without reordering results, so the Actor collects the candidate set and ranks it itself using the price and transaction count on each search card. On a small candidate pool this is a ranking of what search returned, not of the whole category.
- **Supplier catalog discovery is blocked by 1688 as of 2026-08-03.** Every public entry to a supplier's catalog - `winport.m.1688.com/page/offerlist.html`, `/page/index.html`, `m.1688.com/winport/<memberId>.html`, and the classic `shop*.1688.com/page/offerlist.htm` - currently answers with 1688's verification interstitial, for plain requests and for a real browser alike. Runs that pass `supplierUrls` get a `SECURITY_CHALLENGE` diagnostic in `OUTPUT` and **no billed rows**. Keyword search and offer URL/ID modes are unaffected. This is a change on 1688's side, not a configuration you can adjust; the Actor retries such pages in a browser automatically, so it will pick the mode back up when 1688 relaxes it.
- **Supplier trading history is not on the offer page.** 1688 publishes years active, transaction grade, and response rate on the supplier's own pages, not on the offer, so this Actor does not return them. What the offer page does publish - `repurchaseRate`, `serviceScore`, `goodRate`, `reviewCount`, `merchantSigns` - is returned instead. Missing values are `null`, never guessed.
- **`titleEn` is machine translation** when 1688 does not supply an English title. It is good enough for a shortlist and for search, not for customer-facing copy without review.
- **Price ladders reflect the page, including SKU ranges.** Some offers publish a per-SKU price range rather than a quantity ladder; there the tiers can share a minimum quantity and `priceMin`/`priceMax` carry the range. Struck-through list prices and prices belonging to 1688's recommendation modules are excluded.
- **Desktop shop pages are not supported.** `shop*.1688.com` redirects anonymous traffic to login. Use the `winport.m.1688.com` URL returned in `supplierUrl`.
- **Supplier catalogs load in batches of eight products.** The Actor follows the same cookie-bound `asyncView` pagination as the mobile infinite scroll, retries transient page/proxy failures, and stops when a page is empty, repeats existing offer IDs, or has enough candidates. It keeps a small reserve and backfills listings rejected by filters or exhausted retries, so one bad listing does not unnecessarily leave the dataset below `maxProducts`.
- **Only public data.** The Actor does not access private account data, order history, or messages, and does not bypass access controls.

### 🧩 Related Actors

Build a product-sourcing pipeline:

- [Weibo Search & Comments Scraper](https://apify.com/webdata_labs/weibo-search-comments-scraper) - validate product and brand conversations in public Chinese social posts and comments.
- [Xiaohongshu & Douyin Product Trend Radar](https://apify.com/webdata_labs/xiaohongshu-douyin-trend-radar) - discover China social-commerce topics before researching wholesale supply.
- [Google Shopping Scraper](https://apify.com/webdata_labs/google-shopping-scraper) - check retail prices for the product you are about to source, so you can size the margin before contacting a supplier.
- [eBay Listings Scraper](https://apify.com/webdata_labs/ebay-listings-scraper) - measure how crowded the resale side already is.
- [Shopify Store Enricher](https://apify.com/webdata_labs/shopify-store-enricher) - enrich the retailers already selling the product you found.
- [AI Product Taxonomy Mapper API](https://apify.com/webdata_labs/ai-product-taxonomy-mapper-api) - map the scraped titles into your own category tree.
- [FeedFix API](https://apify.com/webdata_labs/feedfix-api) - clean the resulting product feed before it hits a marketplace.

### ❓ FAQ

#### Do I need a 1688 account or a session cookie?

No. Public offer pages, mobile search, and `winport` supplier pages are readable anonymously, and there is no credential field on the input form. An advanced, hidden `sessionCookie` field exists for API callers who need a logged-in session for a restricted listing; it is optional, secret, and never written to logs or datasets.

#### Do I have to configure a proxy?

No, and you cannot. 1688 serves an empty page to traffic from outside China, so the Actor always uses CN residential sessions and the cost is included in the per-product price. This removes the most common cause of failed runs on 1688 scrapers.

#### Am I charged for products my filters removed?

No. `priceMin`, `priceMax`, `minOrderQuantity`, `merchantType`, `province`, and `city` are applied before a row is pushed to the dataset, and billing is per pushed row. `OUTPUT.filteredOut` tells you how many were dropped.

#### Am I charged when an offer fails?

No. Failed offers are reported in `OUTPUT.failedOffers` with a reason code and are not billed. There is also no start fee, so a run that returns nothing costs nothing.

#### Should I search in Chinese or in English?

Both work. Chinese and English keywords surface different offer sets, and Chinese often surfaces more of them, so a thorough shortlist uses both and relies on offer-ID deduplication. Set `translateTitles: true` and you get Chinese-grade recall with English-readable output.

#### How many products can one keyword return?

Typically 20-55 unique offers, because 1688's anonymous mobile search pages recycle rows. For larger pulls, combine keywords, add supplier shops, or supply a list of offer IDs.

#### What does `merchantType` actually check?

`superFactory` keeps offers whose supplier is flagged as a factory or carries a factory-verification badge (深度验厂). `verifiedMerchant` keeps 实力商家, 诚信通, and factory-verified sellers. Both read the flags 1688 publishes on the offer page; they are trust signals, not an audit.

#### Can I get the SKU variant grid?

Yes. Set `includeSkuDetails: true` and each row gains `skuVariants` with variant name, price, stock, and image, plus the raw `skuMatrix`. It is off by default because it makes the export heavier than most sourcing spreadsheets need.

#### Is it legal to scrape 1688?

Scraping public product data can be lawful in many situations, but legality depends on jurisdiction, purpose, contract terms, and the data collected. This Actor collects public product and supplier information only. Do not bypass access controls, collect private account data, or use results in ways that violate applicable law or 1688's terms. Obtain legal advice for high-risk or regulated use.

#### Is this a 1688 API?

Effectively yes. Run it through the Apify API, synchronously or asynchronously, and read structured dataset items as JSON, CSV, or Excel. The dataset schema is stable and documented in the field table above.

### 🛠️ Support

Found a listing that parses wrong, or a filter that behaves unexpectedly? Open an issue on the Actor's Issues tab with the run URL, the public offer URL, the input you used, and the field you expected. Redact cookies and any private input values. Parser fixes for real 1688 pages are prioritized over feature requests.

### ⭐ Rate this Actor

If this saved you an afternoon of copying prices out of 1688, please leave a rating on the **Reviews** tab. Review count is the main trust signal buyers use on Apify Store, and reviews also decide what gets built next here. If something is broken, please open an issue first so it can be fixed - a fixed bug helps you more than a one-star rating does.

### Changelog

- **2026-08-03** - `priceMin` and `priceMax` now come from the offer's own quantity ladder instead of a scan of every price on the page, so they can no longer report a struck-through list price or a neighbouring recommendation. Added `serviceScore`, `goodRate`, `reviewCount`, and a working `repurchaseRate`; removed `description`, `yearsActive`, `transactionLevel`, and `responseRate`, which 1688 does not publish on the offer page and which were always `null`; `attributes` is now populated from the offer's own 商品参数 and no longer duplicated as `specifications`. Merchant badges are read from the offer's badge list rather than from any matching text on the page. Supplier catalogs and keyword searches are now paged one request at a time, so a large run no longer times out inside a single page handler; runs stop cleanly before their own timeout and still write `OUTPUT`; filtered runs discover more candidates so the requested number of products is actually reached; discovery pages that hit 1688's verification are now retried in a browser instead of ending the run empty.
- **2026-07-31** - Added supplier-catalog pagination through 1688's mobile `asyncView` endpoint, including cookie-bound continuation tokens, eight-product batches, deduplication, retries for transient page/proxy failures, safe stopping on empty or repeated pages, and reserve-candidate backfilling after filtered or failed offers.
- **2026-07-29** - Removed the proxy and session-cookie controls from the input form (CN residential proxy is now always used internally), added `sortBy`, `priceMin`, `priceMax`, `minOrderQuantity`, `merchantType`, `province`, `city`, `includeSkuDetails`, and `includeDescriptionHtml`, added `keywords`/`queries`/`maxResults` input aliases, added `province`, `city`, `merchantSigns`, `merchantTags`, and `skuVariants` output fields, switched offer fetching to a proxied HTTP path with a browser fallback, and added search pagination plus MOQ price ladder, supplier, and SKU dataset views.
- **2026-07-27** - Added search and supplier entry modes, MOQ price ladders, English titles, sourcing fields, partial-success reliability handling, and `product-scraped` billing support.
- **2026-07-23** - Fixed ID-only inputs, retries, deduplication, and transparent failure diagnostics.

# Actor input Schema

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

Product keywords to search on 1688. Chinese and English keywords surface different offer sets, so run both for a thorough shortlist; titleEn returns the results in English either way.

## `offerUrls` (type: `array`):

Public 1688 product detail URLs to extract, for example https://detail.1688.com/offer/927875250705.html.

## `offerIds` (type: `array`):

Numeric 1688 offer IDs. Use this instead of URLs when refreshing a tracked catalog.

## `supplierUrls` (type: `array`):

TEMPORARILY UNAVAILABLE: 1688 currently answers every public supplier-catalog URL with its verification page, so this mode returns no products and only a SECURITY\_CHALLENGE diagnostic in OUTPUT - you are not charged for it. Use search keywords or offer URLs/IDs meanwhile. The field stays in place and will start working again by itself when 1688 relaxes the check. Public winport.m.1688.com supplier URLs returned in product rows; the Actor follows the supplier catalog's mobile pages until maxProducts is reached or the catalog is exhausted.

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

How the Actor ranks search candidates before it fetches offer pages. Best selling uses the transaction count on the search card; price sorting uses the card price.

## `priceMin` (type: `integer`):

Keep only offers whose lowest tier price is at least this many CNY.

## `priceMax` (type: `integer`):

Keep only offers whose lowest tier price is at most this many CNY.

## `minOrderQuantity` (type: `integer`):

Keep only offers whose minimum order quantity is at most this number. Offers that do not publish an MOQ are dropped when this filter is set.

## `merchantType` (type: `string`):

Filter by the supplier signals 1688 publishes on the offer page. Super factory keeps factory-verified sellers, verified merchant keeps 实力商家 / 诚信通 / 深度验厂 sellers.

## `province` (type: `string`):

Keep only suppliers in this province. Accepts Chinese (广东) or English (Guangdong).

## `city` (type: `string`):

Keep only suppliers in this city. Accepts Chinese (深圳) or English (Shenzhen).

## `includeSkuDetails` (type: `boolean`):

Add skuVariants (variant name, price, stock, image) and the raw skuMatrix to each row. Useful for catalog import, heavier output.

## `includeDescriptionHtml` (type: `boolean`):

Fetch the offer description document and store it in descriptionHtml. This is a large field and adds one request per product, so it is off by default.

## `translateTitles` (type: `boolean`):

Populate titleEn with a best-effort machine translation when 1688 does not provide one.

## `maxProducts` (type: `integer`):

Safety limit for this run. You are charged per product returned, so this is also your budget cap. Large limits need a longer run timeout: the Actor stops before its own timeout and reports stoppedEarly in OUTPUT rather than being killed mid-run.

## `keywords` (type: `array`):

Alias for searchQueries, accepted so input JSON written for other 1688 Actors validates here. Merged with searchQueries.

## `queries` (type: `array`):

Alias for searchQueries, accepted so input JSON written for other 1688 Actors validates here. Merged with searchQueries.

## `maxResults` (type: `integer`):

Alias for maxProducts, accepted so input JSON written for other 1688 Actors validates here. Takes precedence over maxProducts when both are set.

## `sessionCookie` (type: `string`):

Optional Cookie header from a logged-in 1688 browser session. Not needed for public offer, search, or winport supplier pages. Stored only in the run input; never written to logs or datasets.

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

Ignored. 1688 serves an empty page outside China, so the Actor always uses CN residential proxy sessions and includes the cost in the per-product price.

## Actor input object example

```json
{
  "offerUrls": [
    {
      "url": "https://detail.1688.com/offer/588600851175.html"
    }
  ],
  "sortBy": "relevance",
  "merchantType": "any",
  "includeSkuDetails": false,
  "includeDescriptionHtml": false,
  "translateTitles": true,
  "maxProducts": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing successfully extracted 1688 products.

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

Counts, success rate, and non-billable failed-offer diagnostics.

# 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 = {
    "offerUrls": [
        {
            "url": "https://detail.1688.com/offer/588600851175.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/1688-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 = { "offerUrls": [{ "url": "https://detail.1688.com/offer/588600851175.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/1688-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "offerUrls": [
    {
      "url": "https://detail.1688.com/offer/588600851175.html"
    }
  ]
}' |
apify call webdata_labs/1688-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=webdata_labs/1688-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/uHG8meD9IKMOcJfK7/builds/W8TtMWTRxOeZM1cXb/openapi.json
