# 1688 Product Scraper: Prices, SKUs & Supplier Monitoring (`zaiq/1688-products-scraper`) Actor

Read public 1688 offer pages for wholesale price tiers, MOQ, SKU prices and stock, supplier information and shipping. Compare price, stock and MOQ with a named monitoring store. Unavailable offers and check pages produce free notes.

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

## Pricing

from $4.00 / 1,000 delivered offers

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/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

## 1688 Product Scraper: prices, SKU stock and supplier monitoring

Read public **1688 offer URLs or IDs** into one row per offer: price tiers, minimum order, SKU variants and stock, supplier information and shipping origin. Each row starts with a short verdict for comparing offers.

**$4 per 1,000 delivered offers**, the same price on every Apify plan, plus Apify’s $0.00005 start charge. Check pages, removed offers and failed lookups have no offer charge.

Smallest input: `{"offerIds": ["735353578254"]}`. Use known offer IDs or links. Supplier shop pages are usually blocked by a verification check, and keyword search is not supported.

### What you get

| Field | What it holds |
|---|---|
| verdict | A one-line price, MOQ, SKU, shipping and supplier summary. |
| title, titleEnglish | Original title and optional English translation. |
| priceTiers, pricingType | Quantity breaks where shown. SKU price ranges are kept separate from quantity tiers. |
| skus, skuDimensions, stock | SKU IDs, labels, per-variant prices, displayed stock and option images. |
| supplier | Business name, shop URL, seller type code, service score and repeat-purchase rate where shown. Missing tenure or business type remains null. |
| shipping, sales | Origin, displayed domestic fee, delivery wording and the sales period shown. |
| images, videoUrls, attributes, category | Public media URLs and structured specifications; media files are not downloaded. |
| monitoring | Previous price, MOQ and stock values with item-level changes. |
| SUMMARY | Per-input status, charged offer count, failures, route changes and traffic. |

### What people use it for

- **Compare sourcing offers:** Compare quantity prices and SKU availability for products you already identified.
- **Track replenishment:** Schedule the same offer IDs and named monitoring store to see price, stock and MOQ changes.
- **Monitor a supplier shortlist:** Track known offers from selected suppliers by their offer IDs or links.

### How to use it

1. Paste offer URLs or IDs. The prefilled offer is a small first run.
2. Optionally give a monitoring store name and reuse it on later runs.
3. Set Maximum offers and Maximum cost per run, then start.
4. Open Wholesale offers or Prices and variants; export JSON for complete nested SKU matrices.

### Input

| Field | Example | Notes |
|---|---|---|
| offerUrls | An offer URL | Desktop and mobile offer URLs are normalized to the desktop public page. |
| offerIds | \["735353578254"] | IDs can be combined with URLs. Duplicates produce one offer row per run. |
| shopUrls | Your supplier’s shop URL | Usually blocked: 1688 answers shop pages with a verification check on every route we tested. A blocked shop is a free note and never stops the offers in the same run. |
| maxOffers | 100 | 1–1,000 attempted offers; the independent 300-request limit may stop a large live run earlier. |
| maxOffersPerShop | 50 | Maximum links followed from each public shop page. |
| monitoringStore | sourcing-watch | Optional named store. Keep one concurrent writer per store. |
| translateToEnglish | false | Translate title, category, unit and shipping origin. Supplier names, SKU labels and attributes remain in the source language. |
| proxyCountry | CN | CN or HK for the final residential fallback. |
| maxChargeUsd | 0.04005 | Optional additional offer-charge cap, including the start charge. |

### Output

Each result is one row in the run's dataset (download it as JSON, CSV, Excel, XML or HTML, or read it through the API). An example row (values shortened):

```json
{
  "verdict": "¥7.50–¥9.00 / 个 · MOQ 2 · 270 SKUs · ships from Example city · service 4.0分 · 1.8万+ sold (一年内)",
  "status": "ok",
  "offerId": "123456789012",
  "title": "磁吸保护壳",
  "titleEnglish": null,
  "currency": "CNY",
  "priceMin": 7.5,
  "priceMax": 9,
  "priceTiers": [
    {
      "minQuantity": 2,
      "maxQuantity": 499,
      "price": 9
    },
    {
      "minQuantity": 500,
      "maxQuantity": 4999,
      "price": 8.5
    },
    {
      "minQuantity": 5000,
      "maxQuantity": null,
      "price": 7.5
    }
  ],
  "unit": "个",
  "minimumOrder": 2,
  "stock": 2694192,
  "skuCount": 270,
  "sales": {
    "countShown": "1.8万+",
    "periodShown": "一年内",
    "exactCount": 18940
  },
  "url": "https://example.com/offers/sample",
  "skus": [
    {
      "skuId": "sample-sku-1",
      "specId": "sample-spec-1",
      "specification": "Blue > Model A",
      "attributes": [
        {
          "name": "Colour",
          "value": "Blue"
        },
        {
          "name": "Model",
          "value": "Model A"
        }
      ],
      "price": 9,
      "priceSource": "first quantity tier",
      "stock": 9999,
      "salesCount": 0,
      "image": "https://example.com/images/blue-case.jpg"
    }
  ],
  "supplier": {
    "name": "Example Manufacturing Company",
    "url": "https://example.com/supplier",
    "yearsOn1688": null,
    "ratings": {
      "serviceScoreShown": "4.0分",
      "repeatPurchaseRateShown": "57.12%"
    }
  },
  "monitoring": {
    "status": "off"
  }
}
```

This shortened example comes from a real signed-out test row. Product wording, company names, identifiers and site addresses were replaced; prices, MOQ, stock, counts and scores are from that run. Only one of the 270 SKU entries is shown here. SUMMARY records input failures, route escalation, traffic and event counts.

### Pricing

- **Delivered offer: $0.004.** One event covers the offer and its available SKU, supplier and shipping fields. Monitoring adds no event fee.
- The same price on every Apify plan. There are no volume discounts.
- Apify’s **$0.00005 start charge counts towards Maximum cost per run**. A run with no delivered offers still has that start charge.
- English translation is optional. Model usage is billed separately to the buyer through Apify’s OpenRouter gateway. It is outside this Actor’s offer-event limit.
- Unavailable fields are left empty and explained. An offer with usable title and price data may still have missing optional fields or an incomplete SKU matrix, which is marked in dataQuality.

What typical jobs cost at the list price:

| Job | Cost |
|---|---|
| 1 delivered offer | $0.00405 including start |
| 100 delivered offers | $0.40005 including start |
| 1,000 delivered offers over runs | $4 in offer events, plus the start charge for each run |
| No delivered offers | $0 in offer events, plus $0.00005 start |

Set Maximum cost per run in Apify; the Actor checks the remaining offer budget before fetching. The optional maxChargeUsd input can set a lower limit. Free notes are still written after a limit. These limits do not include separate model usage.

### Tips

- Use JSON export for complete tier and SKU arrays; spreadsheet exports have column limits.
- Group several known offers in one run to share the start charge.
- Treat stock, sales, ratings and shipping as supplier/platform claims observed at the recorded time.
- Use the same monitoring store on scheduled runs; missing or blocked pages do not erase its last complete observations.

### Use it through the API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("zaiq/1688-products-scraper").call(run_input={"offerIds": ["735353578254"], "maxOffers": 1})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

**JavaScript**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('zaiq/1688-products-scraper').call({"offerIds": ["735353578254"], "maxOffers": 1});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**HTTP (one call, results back)**

```bash
curl -X POST 'https://api.apify.com/v2/acts/zaiq~1688-products-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"offerIds": ["735353578254"], "maxOffers": 1}'
```

### Integrations and schedules

- **Schedules:** run it every hour, day or week from the Apify Console (Schedules) and keep a history of results.
- **Make, Zapier, n8n, Google Sheets, Slack, Airtable:** connect it through Apify's integrations, or send each finished run to a **webhook**.
- **Datasets:** results stay in the run's dataset; export them or read them by API whenever you need them.

### Use it with AI agents (MCP)

Add Apify's MCP server (`https://mcp.apify.com`) to Claude, ChatGPT, Cursor, VS Code or any MCP client. The agent can find this Actor and run it for you: ask it for public offer prices, SKU stock and changes from a list of offer IDs. AI agents can also pay for runs directly through Apify's agentic payments.

### Limits

- Public, signed-out pages only. No account, cookies or CAPTCHA-solving input is accepted.
- Verification checks and login walls can prevent a run from delivering offers. A route is retired after a check.
- Keyword search is not supported. Public shop lists may be blocked or incomplete; this Actor does not promise a whole-shop catalogue.
- Up to 1,000 input offers, 300 source requests and 60 minutes of source work per run. Requests are spaced by at least one second; 429 responses trigger backoff and stop source requests.
- Only fields embedded in the public offer page are returned. Supplier tenure, business type, location, SKU images or other details may be absent.
- Prices are shown in CNY. Variant prices, quantity tiers and promotions can have different conditions. Shipping fees are domestic page displays, not international landed costs.
- No supplier contact phones or individual email addresses are collected.
- Monitoring stores the latest complete observation for each tracked offer. It reports changes between observations; it cannot prove what happened between scheduled runs. Keep a monitoring store to at most 1,000 tracked offers.
- A failed translation keeps the original offer and adds a note. The offer remains chargeable when its source data was delivered.

### FAQ

**Does a blocked offer cost an offer event?**

No. It produces a free note. The run’s start charge still applies.

**Does every product have quantity tiers?**

No. Some products are priced by SKU. Their min/max range is shown without inventing quantity breaks.

**Is a null stock value zero stock?**

No. Null means the page did not expose the value. Explicit zero is preserved.

**Can I monitor price and MOQ changes?**

Yes. Set monitoringStore, run the same offers again, and inspect monitoring.previous and monitoring.changes. Partial or blocked pages preserve the last complete snapshot.

**Are translations included in the offer price?**

The Actor adds no translation event. Model usage is billed separately by the gateway to the buyer.

**Does it collect every supplier product?**

No. Shop mode follows exposed links only. For a dependable monitoring scope, supply the specific offer IDs.

### Related Actors from Zaiq

- [alibaba-scraper](https://apify.com/zaiq/alibaba-scraper): Products and suppliers on another wholesale marketplace.
- [shopify-products-scraper](https://apify.com/zaiq/shopify-products-scraper): Product catalogues and change tracking for supported storefronts.

### Support

Questions, a site that changed, or a field you need? Open an issue on this Actor's **Issues** tab: we answer there, usually within a day.

***

Also found as: 1688 product scraper, 1688 price tracker, 1688 SKU stock, wholesale MOQ, supplier monitoring, 1688 offer API.

# Actor input Schema

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

Desktop or mobile 1688 offer URLs. Mobile URLs are read through the desktop public page. Duplicate IDs are delivered once.

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

Numeric offer IDs, as strings. You can combine these with offer URLs.

## `shopUrls` (type: `array`):

Supplier shop pages. 1688 usually answers these with a verification check on every route (checked 26 Oct 2026); a blocked shop is a free note and never stops the offers in the same run. Offer links and IDs are the reliable input.

## `maxOffers` (type: `integer`):

Maximum unique offers attempted across the run, including URL and shop inputs. There is also a 300-request source limit.

## `maxOffersPerShop` (type: `integer`):

Maximum offer links followed from each public shop page, within Maximum offers.

## `monitoringStore` (type: `string`):

Optional named key-value store for price, MOQ and stock history. Reuse the same name across scheduled runs. Use one concurrent run per store. Leave empty to turn monitoring off.

## `translateToEnglish` (type: `boolean`):

Translate title, category, unit and shipping origin. Original text is retained. The buyer pays model usage separately through Apify’s OpenRouter gateway; that usage is outside the offer event budget. SKU labels and supplier names remain as shown.

## `proxyCountry` (type: `string`):

Country for the final Apify residential route when direct and datacenter routes fail. A check retires that route; it is never solved.

## `maxChargeUsd` (type: `number`):

An additional limit for offer events, including Apify’s $0.00005 start charge. The platform Maximum cost per run also applies. Separate AI usage is not included.

## Actor input object example

```json
{
  "offerUrls": [
    "https://detail.1688.com/offer/735353578254.html"
  ],
  "offerIds": [],
  "shopUrls": [],
  "maxOffers": 100,
  "maxOffersPerShop": 50,
  "monitoringStore": "",
  "translateToEnglish": false,
  "proxyCountry": "CN"
}
```

# Actor output Schema

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

Dataset: the results.

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

What each input returned, and notes.

# 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": [
        "https://detail.1688.com/offer/735353578254.html"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("zaiq/1688-products-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 '{
  "offerUrls": [
    "https://detail.1688.com/offer/735353578254.html"
  ]
}' |
apify call zaiq/1688-products-scraper --silent --output-dataset

```

## MCP server setup

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