# 1688 Pet Supplies Scraper — China Wholesale Market Research (`crawleast/china-pet-supplies-scraper`) Actor

Find profitable pet products to dropship from China's largest wholesale platform. Get English titles, dropship-ready scores, estimated landed costs, and compliance hints — all in one API call.

- **URL**: https://apify.com/crawleast/china-pet-supplies-scraper.md
- **Developed by:** [Kyle Wang](https://apify.com/crawleast) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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 Pet Supplies Scraper — Wholesale Sourcing & Dropship Data

**Research winning pet products on 1688.com — Alibaba's domestic wholesale marketplace — with the data you need to evaluate them, not just a Chinese title and a price you can't interpret.**

Most 1688 scrapers dump Chinese-only titles and a single "from" price that hides the quantity breaks, the MOQ, and the supplier trust signals you actually need. This 1688 scraper takes an English keyword like "dog leash" and returns a research-ready row: an AI-translated English title, the full quantity-break price ladder, a 0–100 dropship-ready score, an estimated landed cost in USD, and compliance hints for your target market — all of these for the products covered by the per-run detail budget (see the SUMMARY diagnostic section below for what happens beyond it).

No Chinese needed. No 1688 account. No manual translation. One API call.

**Keywords:** 1688, 1688 scraper, wholesale, dropshipping, supplier search, product research, MOQ, landed cost

***

#### 🛡️ Trust at a glance

| What we commit to | How it works here |
| --- | --- |
| Pay only for delivered results | Zero-result runs cost **$0.00** — you are billed per product row actually delivered, nothing else |
| No hidden usage fees | Pure pay-per-event pricing; proxy and platform compute costs are included, never passed through |
| Honest degradation | Every run's SUMMARY discloses exactly what happened — partial deliveries always come with a named reason, never silently |
| Flat fair pricing | One honest price per delivered row ($0.0045 + $0.01 run fee) — no tier tables, no subscription, no start fee |
| MCP / agentic-payment ready | Input, dataset, key-value-store and output schemas are all declared — machines can validate the contract before calling |
| Issues answered fast | Open an Issue instead of guessing — our response time is public on the developer profile |
| Live reliability stats | Success rate and run volume are shown live on this Store page — judge from real data, not claims |

***

#### ⚡ One-click examples

Skip the input form — these public tasks run proven configurations in one click:

- **[Quick Start — 10 products](https://apify.com/crawleast/china-pet-supplies-scraper/1688-quick-start-10-products)** — the cheapest way to see a full research row (~$0.06)
- **[Deep Research — 50 full-detail items](https://apify.com/crawleast/china-pet-supplies-scraper/1688-deep-research-50-products)** — two keywords, 50 detailed products with price ladders and landed cost
- **[Price Ladder Scan — cheapest first](https://apify.com/crawleast/china-pet-supplies-scraper/1688-price-ladder-scan)** — results sorted by price for instant comparison
- **[Offer ID Lookup](https://apify.com/crawleast/china-pet-supplies-scraper/1688-offerid-lookup)** — full detail for known 1688 product IDs, no keyword search
- **[Fast Catalog Scan — 30 items in seconds](https://apify.com/crawleast/china-pet-supplies-scraper/1688-fast-catalog-scan)** — search-card-level rows, fastest and cheapest scan mode

***

#### 🆚 Why 1688 instead of Alibaba.com or AliExpress?

1688.com is the Chinese domestic wholesale arm of the Alibaba group — the same factories that list on Alibaba.com sell there for the home market, typically at noticeably lower factory prices because there is no export markup. That makes 1688 the sharper place to do product selection and price comparison before you commit to a supplier. This Actor covers exactly that research step: search, compare and cost out products on 1688 from English. To be clear about scope: this Actor scrapes 1688.com (China domestic B2B), not Alibaba.com international — if you are weighing 1688 vs Alibaba as a sourcing channel or looking for an Alibaba alternative for price research, this is the tool that reads the domestic side.

***

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

| ✅ What you get | ❌ What this isn't |
| --- | --- |
| **English titles** (AI-translated) alongside the Chinese original | Not a Chinese-only export you paste into Google Translate column by column |
| **Dropship-Ready Score (0–100)** based on 7 weighted factors | Not a raw data dump that leaves you guessing if a product is worth researching |
| **Estimated landed cost** in USD (product + shipping + duty + fees) | Not a CNY price that ignores your real cost to land it in your market |
| **Compliance hints** (FDA / CE / Prop 65 / FCC) per target market | Not a scraper that leaves compliance research entirely to you |
| **Pet-supplies keyword mapping** (500+ EN→CN terms built in) | Not a generic scraper where "dog leash" returns zero Chinese results |
| **Dropship-only filter** — verified dropship products kept, proven non-dropship culled, unverifiable rows delivered but clearly flagged (`dropshipStatus: "unknown"`) | Not an unfiltered list where half the results don't support dropshipping |
| **PPE pricing** $0.0045 per delivered product + $0.01 run fee, no startup fee (no monthly fee) | Not a $20–30/month subscription you pay even when you don't run it |

***

#### 🎯 Who is this for?

- 🚀 **Dropshipping beginners** testing pet products with low MOQ
- 📦 **Amazon FBA sellers** researching pet supplies from China factories
- 🐾 **Pet niche store owners** on Shopify looking for trending products
- 💰 **Product researchers** who need landed cost + margin before committing
- 🌐 **E-commerce entrepreneurs** who don't read Chinese but research products from China

***

#### 🔧 Features

**🌐 AI-Translated English Titles**
Every product comes with an AI-translated English title alongside the original Chinese title. No more pasting Chinese text into Google Translate column by column — you see a clean English title right away.

**📦 Dropship-Ready Score (0–100)**
A weighted score based on 7 factors that tell you if a product is actually suitable for dropshipping:

- Dropship support (does the supplier offer one-piece dropship?)
- MOQ (lower is better for dropshipping)
- 48-hour pickup rate (how fast does the supplier ship?)
- Distributor count (how many dropshippers already work with them?)
- Supplier composite score (trust signal)
- 30-day order volume (demand signal)
- Repurchase rate (quality signal)

The score maps to a letter grade (A–D) so you can filter at a glance.

**💰 Estimated Landed Cost in USD**
See your true per-unit cost — not just a CNY wholesale price. The estimate includes:

- Product unit cost (converted from CNY at a fixed FX rate)
- International shipping (estimated by weight and destination)
- Import duty (based on target market and product category)
- Platform fees

**⚠️ Compliance Hints**
Get alerts about certification requirements for your target market before you list:

- US: FDA, FCC, CPSC, Prop 65, ASTM F963
- EU: CE, REACH
- UK: UKCA
- AU: ACCC

Compliance hints are heuristic estimates based on product titles and categories — always verify with a qualified expert.

**🐾 Pet-Supplies Keyword Mapping**
500+ English-to-Chinese keyword mappings built specifically for pet supplies. Type "dog leash" and the Actor automatically searches using the correct Chinese keyword. No need to know Chinese or use a separate translation tool.

**🎯 Dropship-Only Filter**
Turn on `dropshipOnly` to exclude any product that doesn't explicitly support one-piece dropshipping. No more wading through wholesale-only listings that require bulk orders.

One expectation to manage: when a product's details cannot be fetched (detail requests are the platform's most heavily protected layer), items whose dropship status could not be verified are **still returned** and stamped `dropshipStatus: "unknown"` — they are not silently dropped. On large batches (>50 products) expect a meaningful share of items in this unverified state. Every run's SUMMARY reports the exact arithmetic: `dropshipCulled` (removed because the details proved they do NOT support dropship) and `dropshipUnknownDelivered` (returned unverified). You can filter strictly on your side by dropping rows where dropshipStatus = "unknown" — SUMMARY's dropshipCulled / dropshipUnknownDelivered counts let you verify the exact split.

**📊 Quantity-Break Price Ladder**
Get the full price tier breakdown — not just a single "from" price. See exactly how much you pay at 1 unit, 100 units, 500 units, so you can plan your margins at scale. (Delivered for products covered by the detail budget — see the SUMMARY diagnostic section below.)

***

#### Quick Start

##### 1. Run on Apify Console

1. Go to the Actor page on Apify Store.
2. Click **Try for free**.
3. Enter keywords like `["dog leash", "cat toy"]`.
4. Click **Start** and wait for results.
5. Download the dataset as JSON, CSV, or Excel.

##### 2. Run via API

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/china-pet-supplies-scraper/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["dog leash", "cat toy"],
    "maxResults": 50,
    "dropshipOnly": true,
    "targetMarket": "US"
  }'
```

> **Time budget for bigger orders:** orders with `maxResults` above 55 automatically switch to an extended time budget (780 seconds) to fit the larger workload — nothing to configure. Orders of 55 items or fewer per keyword run within the standard 330-second budget, which may not be enough when you request several keywords at once; in that case the Actor stops at the deadline, marks the run `partial` in the summary, and you are billed only for the items actually delivered.

##### 3. Run locally

```bash
npm install
apify login
apify run --input '{"keywords":["dog leash"]}'
```

***

#### 🤖 Copy to your AI assistant

This Actor is **API-first and agent-ready**: deterministic JSON input/output, per-event billing with a documented floor, and machine-readable failure semantics (SUMMARY diagnostics) — ideal for MCP servers, n8n/Make flows, LangChain tools and autonomous sourcing agents.

Paste this into your AI assistant:

```text
Use the Apify Actor crawleast/china-pet-supplies-scraper to research
wholesale pet products on 1688.com. POST this JSON to
https://api.apify.com/v2/acts/crawleast~china-pet-supplies-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>&timeout=900
body: {"keywords": ["dog leash"], "maxResults": 20, "dropshipOnly": true,
"targetMarket": "US"}.
Each dataset row is one product with English title, quantity-break price
ladder, dropship-ready score and estimated landed cost in USD. Report the
top 5 by dropshipReadyScore, and flag any compliance hints.
```

`run-sync-get-dataset-items` returns the final dataset in one call — perfect for tool-calling loops. Larger orders (more than ~55 items, or several keywords at once) can take up to 15 minutes: append `?timeout=900` (seconds) to the sync endpoint, or set your HTTP client timeout ≥ 15 minutes — otherwise the gateway may return 408 while the run keeps working in the background (poll `runs/{runId}` to recover; delivered rows are billed per row regardless).

***

📜 **Release notes:** version history and upgrade guidance (0.3.36 → 0.4.2) live in [CHANGELOG.md](./CHANGELOG.md).

***

#### Input Parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `keywords` | array\<string> | ✅ | — | English search keywords, e.g. `["dog leash", "cat toy"]`. API callers may also send `query` or `search` (string or array) as an alias when `keywords` is absent. |
| `petCategory` | enum | ❌ | `all` | `clothing_leash` / `bed_cage` / `cleaning_grooming` / `toys` / `training` / `aquarium` / `all` |
| `maxResults` | integer | ❌ | `50` | Max products per keyword (1–2000) |
| `fullDetailSharding` | boolean | ❌ | `auto` | Full-detail sharding for large orders: auto-ON when `maxResults > 55`, auto-OFF at ≤ 55. `true` forces sharding; `false` restores the legacy mixed shape (card-level surplus). See "Full-detail sharding" below. |
| `maxRunTimeSecs` | integer | ❌ | `780` | Runtime budget in seconds (max 780). The effective budget is the minimum of this value, the platform run timeout minus a 48s finish reserve, and the code-side cap — 330s for non-sharded runs (unchanged behaviour) and 780s when full-detail sharding is active. ⚠️ The 780s budget requires the platform run timeout of **900s (15 min)** configured in `actor.json` — if you launch runs with a custom timeout below 900s, large orders get killed mid-shard (see "Full-detail sharding"). |
| `priceMinCNY` | integer | ❌ | — | Min price in CNY — an APPROXIMATE search-level filter (see note below the table) |
| `priceMaxCNY` | integer | ❌ | — | Max price in CNY — an APPROXIMATE search-level filter (see note below the table) |
| `dropshipOnly` | boolean | ❌ | `true` | Only return products that support dropshipping. Honest caveat: items whose dropship support could not be verified (unknown state, e.g. search-card rows whose details could not be fetched) are NOT silently excluded — they are delivered and stamped `dropshipStatus: "unknown"` so you can tell verified rows from unverified ones. This fail-open is deliberate: strict exclusion of unknown-state items would jeopardize filling large orders. |
| `maxMOQ` | integer | ❌ | — | Max minimum order quantity (1–10000). Needs fetched detail data — in a degraded run, rows without details pass through (see note below). |
| `merchantType` | enum | ❌ | `any` | `any` / `superFactory` (Source Factory) / `verifiedMerchant` (Verified Merchant) |
| `province` | string | ❌ | — | Supplier province (Chinese), e.g. `"浙江"`. Needs fetched detail data — in a degraded run, rows without details pass through (see note below). |
| `city` | string | ❌ | — | Supplier city (Chinese), e.g. `"温州市"` |
| `sortBy` | enum | ❌ | `relevance` | `relevance` / `bestSelling` / `priceAsc` / `priceDesc` / `dropshipScore`. `priceAsc` / `priceDesc` / `dropshipScore` re-order the ENTIRE delivered dataset before hand-off (items with no price sink to the end of a price sort; `dropshipScore` = highest dropship-readiness score first). Note: these three sorting modes hold all results back and deliver them in ONE ordered batch when the run finishes — the dataset is empty until then (expected); `relevance` / `bestSelling` deliver results as they are collected. |
| `includeEnglishTranslation` | boolean | ❌ | `true` | Translate titles to English |
| `includeLandedCost` | boolean | ❌ | `true` | Include landed cost estimate in USD |
| `includeCompliance` | boolean | ❌ | `true` | Include compliance hints for target market |
| `targetMarket` | enum | ❌ | `US` | `US` / `EU` / `UK` / `AU` / `global` |
| `shippingWeightMax` | number | ❌ | — | Max product weight (kg) |
| `excludeFoodProducts` | boolean | ❌ | `true` | Exclude pet food/treats (complex import requirements) |
| `includeSkuDetails` | boolean | ❌ | `false` | Fetch detailed SKU specs (slower) |
| `includeDescriptionImages` | boolean | ❌ | `true` | Fetch product description images (adds 2–3s per product) |
| `offerIds` | array\<string> | ❌ | `[]` | Direct product IDs to fetch, bypassing keyword search |
| `maxPages` | integer | ❌ | — | Max search pages per keyword (1–100) |
| `skipDetails` | boolean | ❌ | `false` | Skip the detail layer entirely for fast, cheap search-card-level runs |
| `proxyConfiguration` | proxy | ❌ | — | Apify proxy config (use RESIDENTIAL CN for production) |

**How the filters really work (transparency note):**

- **Price filters are approximate.** `priceMinCNY` / `priceMaxCNY` are applied on the SEARCH layer against the listing price shown on each search card. The product page may use tiered (quantity) pricing that differs from the card price, so an occasional item slightly outside your range can still be delivered — treat the bounds as a strong narrowing, not a hard guarantee.
- **Detail-dependent filters fail-open in degraded runs.** Filters that need fetched product details (`maxMOQ`, `province`, `city`, and similar) can only check items that reached the detail layer. If a run degrades to search-card-level delivery (the SUMMARY's `degradedItems` tells you exactly how many rows that was), rows without detail data are passed through rather than silently dropped — you get the maximum deliverable data and full visibility into how much of it was filterable.

***

#### Output

Each product in the dataset contains enriched fields for product research:

```json
{
  "offerId": "951309417091",
  "titleCn": "工厂直销宠物运动腰包跑步多功能狗狗牵引绳防爆冲可伸缩免提狗绳",
  "titleEn": "Factory Direct Pet Sports Belt Running Multi-functional Dog Leash Anti-pull Retractable Hands-free Dog Rope",
  "detailUrl": "https://detail.1688.com/offer/951309417091.html",
  "images": [
    "https://cbu01.alicdn.com/img/ibank/O1CN01ObqAAw1wGklHQWemv_!!2215585976281-0-cib.jpg_270x270xzq60.jpg"
  ],
  "videoUrl": "https://cloud.video.taobao.com/play/u/2215585976281/p/2/e/6/t/1/526449776190.mp4",
  "price": {
    "min": 32.5,
    "max": 38.5,
    "currency": "CNY",
    "unit": "piece"
  },
  "quantityPrices": [
    { "price": 38.5, "minQuantity": 1 },
    { "price": 34.5, "minQuantity": 200 },
    { "price": 32.5, "minQuantity": 500 }
  ],
  "moq": 1,
  "orderCount30d": null,
  "salesTotal": 100,
  "transactionCountText": "100+ transactions",
  "repurchaseRate": 0.32,
  "categoryPath": "宠物/宠物用品/狗用品",
  "categoryEn": "Pet Supplies (All)",
  "tags": [],
  "stock": {
    "total": 20891,
    "skus": [
      { "skuId": "5928199428364", "spec": "Royal Blue > 2.5CM*(145-200)CM", "count": 9987, "price": null }
    ]
  },
  "skuDetails": [
    {
      "skuId": "5928199428364",
      "spec": "Royal Blue > 2.5CM*(145-200)CM",
      "price": null,
      "discountPrice": null,
      "stock": 9987,
      "weight": null,
      "dimensions": { "length": null, "width": null, "height": null }
    }
  ],
  "descriptionImages": [
    "https://cbu01.alicdn.com/img/ibank/O1CN01eB3IQa1wGklHR3kG7_!!2215585976281-0-cib.jpg"
  ],
  "productFlags": {
    "labels": [],
    "tags": [],
    "guarantees": [
      {
        "serviceName": "7-Day Return",
        "description": "Seller supports 7-day no-reason returns. Custom orders excluded.",
        "serviceCode": "qtwlybt"
      }
    ],
    "supplierType": "factory",
    "specialService": null,
    "isOnePiece": true
  },
  "shipping": {
    "postFee": null,
    "deliveryTime": "Ships within 48h",
    "deliveryLimitText": "48h shipping commitment",
    "sendAddress": "广东省深圳市"
  },
  "dropship": {
    "enabled": true,
    "orders30d": 156,
    "pickupRate48h": 0.86,
    "distributorCount": 23
  },
  "supplier": {
    "companyName": "深圳市一宠科技有限公司",
    "shopUrl": "",
    "cardType": "factory",
    "scores": {
      "service": "4.5",
      "repeatRate3m": "66.59%",
      "composite": 100
    },
    "saleNum": "3700+",
    "saleCountDate": "within 1 year",
    "rateInfo": {
      "positiveRate": 100,
      "score": 5
    },
    "province": "广东",
    "sellerType": "superFactory",
    "yearsOnPlatform": 4,
    "isSuperFactory": true,
    "isFactoryInspected": false,
    "city": "深圳市"
  },
  "dropshipReadyScore": 82,
  "dropshipGrade": "B",
  "scoreConfidence": "ok",
  "dataQuality": "partial",
  "translationMethod": "dictionary",
  "estLandedCostUsd": {
    "unitCostUSD": 4.51,
    "internationalShippingUSD": 2.99,
    "estimatedDutyUSD": 0.14,
    "platformFeeUSD": 0.92,
    "platformFeePercent": 12,
    "dutyPercent": 3,
    "totalLandedCostUSD": 8.56,
    "suggestedRetailPriceUSD": 21.4,
    "estimatedMarginPercent": 60,
    "markup": 2.5,
    "fxRate": 7.2,
    "currency": "USD"
  },
  "compliance": {
    "materialCategory": "general",
    "targetMarket": "US",
    "suggestedCertifications": ["CPSC compliance"],
    "riskFlags": [],
    "supplierCertificates": [],
    "disclaimer": "These hints are heuristic and for informational purposes only. Always consult a compliance expert and verify current regulations before listing."
  },
  "sourceKeyword": "dog leash",
  "scrapedAt": "2026-08-13T06:12:44.644Z"
}
```

> **Note:** `titleCn`, `supplier.companyName`, `shipping.sendAddress`, and `categoryPath` retain their original Chinese text as they are raw source data from the wholesale platform. All enrichment fields (scores, costs, compliance, translations) are in English.

**Field-semantics notes (0.3.39):**

- `dropshipStatus`: `null | "unknown"`. `null` (field absent or null) = no caveat — the row was either verified dropship-enabled or the filter was off; `"unknown"` = the item was delivered without a verifiable dropship verdict (fail-open under `dropshipOnly: true`).
- `stock.total` / `stock.skus[].count`: `null` means unknown — the platform sometimes reports sentinel values above 10,000,000 that are not real inventory counts; those are replaced with `null` rather than a fabricated cap.
- `city` vs `supplierCity` / `supplier.city`: both are kept on purpose — top-level `city` is the full administrative location string (province + city, kept in Chinese) straight from the detail page, while `supplierCity` / `supplier.city` is the supplier-card city translated to English where known. Use `supplier.city` for filtering display and `city` for the raw source value.
- `scoreConfidence`: `"ok"` = the dropship score rests on enough real data; `"insufficient_data"` = most scoring factors were missing (the grade was downgraded one level accordingly).

**What a search-card-level (`dataQuality: "minimal"`) row looks like:** when an item is delivered at search-card level (see the SUMMARY diagnostic section below), it never reached the protected detail layer, so it carries only what the search results expose: title(s), image(s), headline price range and supplier card. Its `quantityPrices` is `[]`, `moq` is `null`, `shipping` is `null`, and `dropshipStatus` is `"unknown"` (plus reduced enrichment fields). These are intentionally degraded research rows, not broken records — the SUMMARY's `qualityMix` counts exactly how many of each quality tier you received.

##### SUMMARY diagnostic fields

Every run ends with a SUMMARY record (key-value store) that reports exactly how the detail layer performed. Product-detail fetching is the platform's most heavily protected layer, so the Actor budgets it deliberately and degrades gracefully instead of failing silently. The key fields tell you what happened:

| Field | Meaning | What to do |
|-------|---------|------------|
| `detailStatus` | Overall detail-layer outcome for the delivered dataset: `full` (every delivered item has fetched details), `partial` (some items have details, others were delivered at search-card level), `card_only` (items delivered, but none got details), or a cause code (`no_token`, `circuit_open`, `skipped_by_input`). | `full` needs nothing. On `partial`/`card_only`, see the `maxResults` guidance below. |
| `detailQuotaExhausted` | Present (`true`) when the run hit its per-run detail-call budget (the platform starts blocking detail requests after a cumulative call cliff, so the Actor stops *before* the cliff instead of burning every remaining request). In legacy mode (`fullDetailSharding: false`) the leftover products are still delivered, but at search-card level. With full-detail sharding (default for large orders — see below) the run stops honestly instead of padding with cards. | Large orders shard automatically (see "Full-detail sharding" below); use `fullDetailSharding: false` only if you explicitly prefer the legacy card-level fallback. |
| `degradedItems` | Present only when at least one delivered item did NOT get a fetched detail layer (count of search-card-level deliveries). Its **absence** certifies an all-detail run. | Compare against your `maxResults`; combined with `detailQuotaExhausted` it tells you exactly how many items the budget covered. |
| `qualityMix` | Breakdown of delivered items by per-item data quality: `full` (detail layer + all enrichment), `partial` (details fetched but some fields missing), `minimal` (search-card-level delivery only). | Use it to judge dataset depth at a glance — e.g. `{ full: 100, partial: 0, minimal: 0 }` is a perfect all-detail run. |
| `detailQuota` | Usage of the detail-call budget: `calls` (detail calls consumed) vs `quota` (the budget cap — in the default legacy mode 55 for orders ≤10 items and 85 for 11–55 item orders since 0.3.38; a 240 cost cap in `detailIdentityRotation` mode; `min(maxResults × 5, 550)` under full-detail sharding). | Informational — `calls` reaching `quota` is what triggers `detailQuotaExhausted`. |
| `cliffDetected` | Present (`true`) when the platform started actively blocking detail requests in this run (consecutive fully-blocked groups), so the Actor stopped launching details early to avoid burning requests. | Rerun later or rotate proxies; combine with `skipDetails` if you only need search-card rows. |
| `partial` + `partialReason` | Present (`true`) when the run ended early for an operational reason, regardless of detail coverage. Reason codes: `deadline_expired` (the run's time budget ran out before all pages were fetched), `detail_quota_exhausted` (the per-run detail-call budget was spent), `search_supply_exhausted` (the search layer could not supply enough candidates). Sharded full-detail runs use specific reasons: `sfd_deadline_floor`, `sfd_hard_call_cap`, `sfd_zero_delivery`, `insufficient_pool`, `identity_pollution_wall`, `identity_mint_fuse` (0.3.38: shard-level mint pollution persisted after a proactive remint) (0.3.40: only emitted after the bounded cooldown retry is spent). A fully filled run carries NO `partialReason` — `shardStats.stopReason: "filled"` is the success outcome. | `partialReason` names the cause; the flushed dataset is still complete for everything fetched up to that point. Transient platform-side blocking of the Actor's browsing sessions — not a data problem. Rerun the Actor: a fresh run starts with clean sessions. You are billed only for the rows delivered in each run. |
| `shardStats` | Present ONLY on full-detail-sharding runs: `shards` (shards executed, including shard-0), `callsPerShard` (detail calls per shard), `mintPollutions` / `mintFailures` (identity supply health), `retainedParks` (0.3.38: how many times the continuation-search page was reserved mid-run instead of closed — a count > 0 certifies the page-turning fix engaged), `cardsDiscarded` (parked search cards discarded to honour the full-detail contract), `seedFallbacks` (always 0 — SFD never falls back to seed tokens), `stopReason` (`filled` or the exit code above). | Informational — `stopReason: "filled"` certifies the quota was filled entirely with full-detail deliveries. |

**Rule of thumb:** orders up to ~55 items fit one identity's detail budget — since 0.3.38 that budget is 55 detail calls for ≤10-item orders and 85 for 11–55-item orders (the full-detail sharding auto-ON threshold stays at 55 items — a separate switch from the per-identity call budget); larger orders automatically enable **full-detail sharding** (below) and keep every delivery full-detail. Under aggressive filtering (e.g. `dropshipOnly` culling most of a keyword's products) the delivered total can still fall short of `maxResults`. The SUMMARY fields above (`shardStats`, `detailQuotaExhausted`, `qualityMix`, `partial`) say exactly what happened — never guess, check them.

##### Full-detail sharding (large orders)

**The contract:** whatever you order — 1, 10 or 100 items — every delivered row carries a fetched detail layer. Never a minimal-card filler.

One fresh browser identity gets a detail budget of ~55 calls, so orders above ~55 items cannot be served by a single identity. When `maxResults > 55` (or `fullDetailSharding: true`), the run **shards automatically**: shard 0 rides the warm token chain, and every further shard mints a FRESH identity with its OWN ~55-call quota, drawing survival-adjusted batches from the card pool until your quota is filled. The run's time budget is raised accordingly (up to 780s of work inside the 900s platform timeout).

> **Timeout note for large orders:** the Actor's platform run timeout is set to **900 seconds (15 minutes)** — the 780s work budget plus a 48s finish reserve need it. If you launch runs through your own API/schedule settings, keep the run timeout at 900s or higher; a lower timeout kills large orders mid-shard (the flushed partial data is still delivered and billed per row, but you will need a rerun).

| Order | What to expect |
|-------|----------------|
| ≤ 55 items | Single-identity run, unchanged (~90s). |
| 100 items | Typically 3–4 fresh identities with dropship-only filtering (2–3 without); typically **~7–9 minutes**, platform cost ≈ **$0.12–0.16** (compute + proxies). |
| Very large orders | A hard cost hat of `min(maxResults × 5, 550)` detail calls caps the spend. Orders above ~250 cannot be fully filled within one run's 780s budget — expect capped delivery (~110–250 rows at maxResults=500 depending on survival rate); the SUMMARY states the reason. |

**Honest shortfall:** if the shard loop cannot fill the quota — the time floor runs out, the search pool dries up, or the platform starts poisoning fresh identities — the run stops early, delivers what it has (every row still full-detail), and SUMMARY states exactly why (`partial` + `partialReason` + `shardStats.stopReason`). In the worst case (observed post-detail survival below ~20%) the delivered COUNT may fall short of `maxResults` — but no row ever loses its detail layer to pad the number. Set `fullDetailSharding: false` to opt out and restore the legacy behaviour (surplus delivered at search-card level).

***

#### 💵 Pricing

Pay only for delivered rows: **$0.0045 per product** + a **$0.01 run fee** charged once at run completion and only if at least one row was delivered. Runs that deliver nothing are not charged. No hidden usage fees.

| Event | Price | When it's charged |
|-------|-------|-------------------|
| Dataset item | **$0.0045** | Per product row actually delivered to the dataset |
| Run base fee | **$0.01** | Once per run, at completion — only when ≥1 row was delivered |

There is a **$0.04 minimum charge** per run that delivers at least one product. No startup fee, no monthly subscription. **A run that returns nothing costs nothing** — the floor and the run fee only apply when at least one product is delivered. Each run's actual cost is reported in its SUMMARY (`estimatedCost`).

Example run costs:

| Products | Cost |
|----------|------|
| 0 results (nothing delivered) | $0.00 |
| 1 (hits the $0.04 floor) | $0.04 |
| 10 (≈$0.045 rows + $0.01 run fee) | $0.06 |
| 50 (test run, ≈50 full details) | $0.24 |
| 100 (full-detail sharding — every row detailed, ~7–9 min) | $0.46 |
| 500 (niche scan; full-detail sharding — every delivered row detailed; delivery is capped by the 780s budget, see "Very large orders" above) | $2.26 |

Cost formula per run: `products = 0 → $0.00; otherwise max($0.04, products × $0.0045 + $0.01 run fee)` — the floor applies only when at least one product is delivered. The examples above use exactly this arithmetic.

##### Run outcomes

Every run ends in one of three states, all verifiable in the run's key-value store (`SUMMARY` and `OUTPUT` records):

| Outcome | What happens | Cost |
|---------|--------------|------|
| Products delivered | Dataset rows + SUMMARY report as usual | $0.0045 per delivered product + $0.01 run fee, floored at $0.04 |
| Zero results | The run finishes SUCCEEDED with an empty dataset; SUMMARY reports the searched keywords and diagnostics | **$0.00** |
| Empty input | Both `keywords` and `offerIds` empty → the run finishes SUCCEEDED with `errorCode: "NO_INPUT"` in the SUMMARY and OUTPUT records, nothing researched | **$0.00** |

Note the large-order example: with full-detail sharding (default above ~55 items) a 100-item run keeps EVERY row full-detail at the price of a longer run (~7–9 min, ≈$0.12–0.16 of platform cost). If you only need search-card rows, set `skipDetails: true` to skip the detail layer entirely and run faster; set `fullDetailSharding: false` to restore the legacy card-level fallback for the surplus.

Free tier: $5 monthly platform credit covers roughly **1,000 products** ($5 ÷ $0.0045 ≈ 1,111 rows; slightly fewer across multiple runs due to the per-run fee and the $0.04 floor).

***

#### FAQ

**Q: How much does it cost to scrape 1688?**
A: Pay only for delivered rows: $0.0045 per product, plus a $0.01 run fee charged once at run completion and only if at least one row was delivered, floored at a $0.04 minimum charge when at least one product is delivered, with no startup fee (see Pricing above). Runs that deliver nothing are not charged. There is no monthly subscription for the Actor itself, and the $5 free Apify credit covers roughly 1,000 products to start.

**Q: Do I need a 1688 account or a Chinese phone number?**
A: No. The Actor accesses publicly available product data on 1688.com through Apify residential proxies. No 1688 account, no Chinese phone number, no Chinese-language skills required.

**Q: Does this 1688 scraper work outside China?**
A: Yes. For production runs, the Actor uses Apify RESIDENTIAL proxies located in China to access 1688. During local development, it uses your direct IP.

**Q: How accurate is the Dropship-Ready Score?**
A: The score is a weighted heuristic based on 7 factors (dropship support, MOQ, 48h pickup rate, distributor count, supplier score, 30-day orders, repurchase rate). It is a starting point — always verify before committing.

**Q: How accurate is the landed cost estimate?**
A: It uses a fixed FX rate (1 USD = 7.2 CNY, MVP) and estimated shipping/duty/platform-fee coefficients. For production, integrate a live FX API and real shipping quotes.

**Q: Can I get pet food data?**
A: Pet food is excluded by default (`excludeFoodProducts: true`) because it requires complex import permits and labeling. Set it to `false` if you understand the compliance requirements.

**Q: 1688 changed its site — will the scraper break?**
A: The Actor is actively maintained and updated whenever 1688's internals change. You don't need to do anything on your side — just keep using the latest version.

***

#### Compliance & Disclaimer

This Actor is a **data research tool** that retrieves publicly available product information from China's wholesale platforms. It does **not** provide legal advice.

- **Compliance hints** are heuristic estimates based on product titles and categories. Always consult a qualified compliance expert before listing products.
- **Landed cost estimates** are approximations using fixed coefficients — verify with your freight forwarder and marketplace.
- Users are responsible for complying with all applicable laws, including product safety regulations (FDA, FCC, CE, Prop 65, etc.), import/customs regulations, and platform terms of service.
- The Actor operators are not liable for decisions made based on this data.

***

#### Tech Stack

- **Runtime:** Node.js 20 + ES Modules
- **Framework:** Apify SDK v3 + Crawlee
- **Container:** `apify/actor-node:20-beta`

### Related Actors

- **[1688 Image Search Scraper](https://apify.com/crawleast/1688-image-search-scraper)** — reverse image search on 1688: upload a product photo, get visually similar wholesale listings with factory prices, MOQ and supplier trust signals, plus optional full-detail enrichment (SKUs, landed cost, dropship score).

Recommended pipeline: **discover by keyword** with this Actor (market research, category dives, winner shortlists) → **source by photo** with the Image Search Scraper (find the factory behind each winning product) → re-check finalists via its `offerIds` detail-only mode.

### Reviews

Found a bug or have a wishlist? Open an **Issue** — a fixed bug helps you more than a one-star rating, and we answer fast.

If this run saved you time, a quick review on the Store page helps other buyers find it — 10 seconds, hugely appreciated.

### License

MIT

# Actor input Schema

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

List of English search keywords, e.g. \["dog leash", "cat toy"]. Each keyword is mapped to its Chinese equivalent and searched on 1688.com.

## `petCategory` (type: `string`):

Restrict results to a pet supplies sub-category. Use 'all' to search across all categories.

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

Maximum number of products to return per keyword. Expectation management: full product details are budgeted per single identity (about 55 detail-covered products for small orders of ≤10 items, and 85 for mid-size orders of 11–55 items since 0.3.38). Since 0.3.38, orders of 11–55 items get a raised detail budget (85 calls), improving full-detail coverage for mid-size runs. Above 55, full-detail sharding takes over (see fullDetailSharding): the run automatically splits the order into shards, each riding a brand-new identity with its own quota, so EVERY delivered item keeps full detail — run time and cost grow with the order size (a 100-item order costs ≈ $0.12–0.16 of platform compute+proxy, 7–9 min). When fullDetailSharding is explicitly OFF, the surplus above the per-identity quota is delivered at search-card level (dataQuality='minimal' — headline price, titles and supplier card only, quantityPrices=\[]/moq=null/shipping=null/dropshipStatus='unknown'). Under aggressive filtering (e.g. dropshipOnly) the delivered total can fall short of maxResults. Check the SUMMARY fields detailQuotaExhausted / qualityMix / shardStats / partial to see exactly what you got.

## `fullDetailSharding` (type: `boolean`):

Guarantees every delivered item carries FULL product details — never a 'minimal' search card. Default 'auto' semantics: leave unset and the mode switches ON automatically when maxResults > 55 (above one identity's detail quota — 55 calls for ≤10-item orders, raised to 85 for 11–55-item orders since 0.3.38); set true to force it, false to opt out (legacy quota behaviour, surplus degrades to card level). When ON and the order exceeds one identity's quota (55 calls for ≤10 items / 85 for 11–55 items since 0.3.38), the run shards INSIDE a single run: each shard rides a brand-new browser identity with its OWN fresh quota until the order is filled. Expectation management: run time and cost grow with the order size (a 100-item order costs ≈ $0.12–0.16 of platform compute+proxy in about 7–9 minutes; the run-time budget is raised to 780s). Honest delivery: under worst-case survival (<20% of detail fetches survive the post-detail filters) the delivered COUNT may fall short of maxResults — but every item that IS delivered still carries full detail, and SUMMARY reports partial=true + shardStats.stopReason so you see exactly why.

## `priceMinCNY` (type: `integer`):

Minimum price in Chinese Yuan (CNY). Approximate filter: applied to the listing price shown on search cards, while product pages may use tiered (quantity) pricing — an occasional item slightly outside the range can still be delivered. Leave empty for no lower limit.

## `priceMaxCNY` (type: `integer`):

Maximum price in Chinese Yuan (CNY). Approximate filter: applied to the listing price shown on search cards, while product pages may use tiered (quantity) pricing — an occasional item slightly outside the range can still be delivered. Leave empty for no upper limit.

## `dropshipOnly` (type: `boolean`):

Only return products that support dropshipping. Products without a dropship indicator will be excluded. Expectation management: when product details cannot be fetched, items whose dropship status could not be verified are STILL returned and stamped dropshipStatus='unknown' (they are not silently dropped). On large batches (>50 products) expect a meaningful share of items to be in this unverified state — check the SUMMARY fields dropshipCulled / dropshipUnknownDelivered to see exactly how many items were culled vs delivered unverified. You can filter strictly on your side by dropping rows where dropshipStatus = "unknown" — SUMMARY's dropshipCulled / dropshipUnknownDelivered counts let you verify the exact split.

## `maxMOQ` (type: `integer`):

Maximum minimum order quantity. Use 1 for strict dropship-only filtering (overrides dropshipOnly when set). Needs fetched product details: if the run degrades to search-card-level delivery (reported as 'degradedItems' in the SUMMARY), rows without detail data are passed through rather than dropped.

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

Filter by supplier verification level on 1688.

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

Filter suppliers by province. IMPORTANT: enter the value in CHINESE characters — 1688 stores supplier locations in Chinese, so the filter matches Chinese text (e.g. Zhejiang = '浙江', Guangdong = '广东', Jiangsu = '江苏', Shandong = '山东'). Needs fetched product details: if the run degrades to search-card-level delivery (reported as 'degradedItems' in the SUMMARY), rows without detail data are passed through rather than dropped. Leave empty for all provinces.

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

Filter suppliers by city. IMPORTANT: enter the value in CHINESE characters — 1688 stores supplier locations in Chinese, so the filter matches Chinese text (e.g. Wenzhou = '温州市', Yiwu = '义乌市', Guangzhou = '广州市', Shenzhen = '深圳市'). Leave empty for all cities.

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

Sort order for the delivered results. 'priceAsc' / 'priceDesc' / 'dropshipScore' re-order the ENTIRE dataset before delivery: price sorts use each item's unit price (items without a price go to the end), 'dropshipScore' puts the Actor's highest dropship-readiness scores first. Note: these three modes hold all results back and deliver them in ONE ordered batch when the run finishes — the dataset is empty until then (expected). 'relevance' / 'bestSelling' keep the platform's delivery order and deliver results as they are collected.

## `sortType` (type: `string`):

Advanced: fine-grained sort override. 'Normal' = the platform's default relevance order; 'Transactions' = most-sold first; 'Hot / newest' = the platform's trending recommendations; the two price options sort by unit price. Most users should use the simpler 'Sort by' (sortBy) control instead — it covers the same cases and stays effective even when the Actor falls back to its alternate search path. This override only affects the primary search path; leave it on 'Normal' unless you specifically need the platform's raw ordering.

## `includeEnglishTranslation` (type: `boolean`):

Translate Chinese product titles into English. Adds a 'titleEn' field to each result.

## `includeLandedCost` (type: `boolean`):

Estimate the total landed cost (unit cost + shipping + duty + platform fee) and suggested retail price. Adds an 'estLandedCostUsd' object to each result.

## `includeCompliance` (type: `boolean`):

Generate compliance hints (FDA, FCC, CE, Prop 65, ASTM F963, etc.) for the target market. Adds a 'compliance' object to each result.

## `targetMarket` (type: `string`):

Target market used for landed cost and compliance calculations.

## `shippingWeightMax` (type: `number`):

Exclude products heavier than this value (in kilograms). Useful for keeping international shipping costs under control.

## `excludeFoodProducts` (type: `boolean`):

Exclude pet food and treat products (which often require import permits, FDA registration, and have complex labeling requirements).

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

Fetch and include detailed SKU/specification data for each product. Automatically included when specs are available from the detail API. Increases run time.

## `includeDescriptionImages` (type: `boolean`):

Fetch product description images via a secondary JSONP request. Adds 2-3s per product. Set to false to speed up scraping when description images are not needed.

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

1688 product IDs to fetch directly, bypassing search. When provided, the Actor skips keyword search and fetches details for each ID.

## `maxPages` (type: `integer`):

Maximum number of search pages to crawl per keyword. Stops at maxResults or maxPages, whichever comes first.

## `maxRunTimeSecs` (type: `integer`):

Soft time budget for the run (in seconds). Default 780: the effective budget is the minimum of this value, the platform run timeout minus a 48s finish reserve, and the code-side cap — 330s for non-sharded runs (unchanged behaviour, the code still clamps to 330s) and 780s when full-detail sharding is active. When the budget runs out, the Actor flushes everything collected so far (marked partial in SUMMARY) and exits normally instead of hanging. Does not slow down the normal path — the checks are lightweight time comparisons. Large sharded orders need the platform run timeout kept at 900s (15 min, as configured in actor.json); launching runs with a lower custom timeout kills them mid-shard (partial data is still delivered and billed per row).

## `mintOnMiss` (type: `boolean`):

When the shared session-token cache is empty, allow ONE bounded on-the-spot browser token mint (max 60s) so the Actor still delivers full details without a separate token-refresh schedule. Set to false to skip inline minting entirely — on a cache miss the run degrades immediately to search-level data (SUMMARY detailStatus=no\_token) for the fastest possible degraded run.

## `detailIdentityRotation` (type: `boolean`):

EXPERIMENTAL feature (A/B test, default OFF, outcome not guaranteed): when ON, the FIRST ~40 products of each detail batch still ride the run's shared identity on the warm page (fast harvest), and only the REMAINING products switch to brand-new independent browser identities (each a fresh browser with its own cookies and credentials). The hope is that fresh identities reduce the platform's blocking of detail requests. Trade-offs you should know: (1) each new-identity group starts ~13 seconds slower because the identity must be created first; (2) on large runs (maxResults > 40) this extra time will very likely exhaust the run's time budget — the run then ends with PARTIAL data (everything collected so far is delivered and marked partial in SUMMARY) instead of full details; (3) when the remaining time budget drops below what one identity group needs, the warm phase hands the clock over to the identity groups, and when the run-level cost cap is reached no further identity groups launch — the leftover products then degrade to card-level data (SUMMARY reports detailQuotaExhausted=true). A failed identity creation silently falls back to the shared identity, so results are never worse than with this option OFF. Leave OFF for normal runs; only enable it to compare detail quality on large batches — the SUMMARY diagnostics are the same either way. Relationship to fullDetailSharding (SFD): when SFD is active (auto-ON for maxResults > 55, or explicitly true) it OVERRIDES this switch — SFD runs the same identity machinery but with the full-detail contract (no card-level degrade, run budget raised to 780s, a raised cost cap and a shard fill loop), and this option's value is ignored for the run.

## `skipDetails` (type: `boolean`):

Skip the entire detail pipeline (token bootstrap, block-probe, in-browser fallback) and return search-level data only: title, price range, images, sales count and company info, enriched with translation and dropship scoring where possible. Fastest and cheapest mode — a typical cloud run finishes in under 45 seconds. Fields that require detail data (SKU specs, exact MOQ tiers, shipping templates, description images, compliance details) are omitted. Enable for bulk market research and keyword discovery; disable when you need full product details.

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

Apify proxy configuration. For production runs targeting 1688.com, use RESIDENTIAL proxies in China (countryCode: CN). Leave empty to use no proxy (development).

## `searchMode` (type: `string`):

auto = the standard four-level search chain and the mode every regular user should keep. mtop\_only = diagnostic mode that forces a single experimental search path with no fallback; a keyword that fails returns 0 offers. Leave 'auto' for all real runs.

## Actor input object example

```json
{
  "keywords": [
    "dog leash",
    "cat toy"
  ],
  "petCategory": "all",
  "maxResults": 50,
  "dropshipOnly": true,
  "merchantType": "any",
  "sortBy": "relevance",
  "sortType": "normal",
  "includeEnglishTranslation": true,
  "includeLandedCost": true,
  "includeCompliance": true,
  "targetMarket": "US",
  "excludeFoodProducts": true,
  "includeSkuDetails": false,
  "includeDescriptionImages": true,
  "offerIds": [],
  "maxRunTimeSecs": 780,
  "mintOnMiss": true,
  "detailIdentityRotation": false,
  "skipDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CN"
  },
  "searchMode": "auto"
}
```

# Actor output Schema

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

One row per product researched on 1688.com: bilingual titles, price range and quantity-break ladder, MOQ, stock, supplier trust signals, dropship-ready score and grade, estimated landed cost in USD and compliance hints. Field meanings are described in the dataset schema (Overview view).

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

Machine-readable run report stored under the SUMMARY key: item totals, per-keyword stats, quality mix (full/partial/minimal), dropship cull counts, average dropship-ready score, PPE cost estimate and search/detail 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 = {
    "keywords": [
        "dog leash",
        "cat toy"
    ],
    "dropshipOnly": true,
    "includeEnglishTranslation": true,
    "includeLandedCost": true,
    "includeCompliance": true,
    "excludeFoodProducts": true,
    "includeDescriptionImages": true,
    "offerIds": [],
    "mintOnMiss": true,
    "detailIdentityRotation": false,
    "skipDetails": false,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "CN"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawleast/china-pet-supplies-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 = {
    "keywords": [
        "dog leash",
        "cat toy",
    ],
    "dropshipOnly": True,
    "includeEnglishTranslation": True,
    "includeLandedCost": True,
    "includeCompliance": True,
    "excludeFoodProducts": True,
    "includeDescriptionImages": True,
    "offerIds": [],
    "mintOnMiss": True,
    "detailIdentityRotation": False,
    "skipDetails": False,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "CN",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("crawleast/china-pet-supplies-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 '{
  "keywords": [
    "dog leash",
    "cat toy"
  ],
  "dropshipOnly": true,
  "includeEnglishTranslation": true,
  "includeLandedCost": true,
  "includeCompliance": true,
  "excludeFoodProducts": true,
  "includeDescriptionImages": true,
  "offerIds": [],
  "mintOnMiss": true,
  "detailIdentityRotation": false,
  "skipDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CN"
  }
}' |
apify call crawleast/china-pet-supplies-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawleast/china-pet-supplies-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/SgfE5TG1Zeh9Vj10J/builds/gb4iz8VHjaHa6Yby4/openapi.json
