{
  "openapi": "3.0.1",
  "info": {
    "title": "1688 Pet Supplies Scraper — China Wholesale Market Research",
    "description": "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.",
    "version": "0.4",
    "x-build-id": "gb4iz8VHjaHa6Yby4"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/crawleast~china-pet-supplies-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-crawleast-china-pet-supplies-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/crawleast~china-pet-supplies-scraper/runs": {
      "post": {
        "operationId": "runs-sync-crawleast-china-pet-supplies-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/crawleast~china-pet-supplies-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-crawleast-china-pet-supplies-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "keywords": {
            "title": "Search keywords (English)",
            "type": "array",
            "description": "List of English search keywords, e.g. [\"dog leash\", \"cat toy\"]. Each keyword is mapped to its Chinese equivalent and searched on 1688.com.",
            "items": {
              "type": "string"
            }
          },
          "petCategory": {
            "title": "Pet supplies category",
            "enum": [
              "clothing_leash",
              "bed_cage",
              "cleaning_grooming",
              "toys",
              "training",
              "aquarium",
              "all"
            ],
            "type": "string",
            "description": "Restrict results to a pet supplies sub-category. Use 'all' to search across all categories.",
            "default": "all"
          },
          "maxResults": {
            "title": "Max results per keyword",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "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.",
            "default": 50
          },
          "fullDetailSharding": {
            "title": "Full-detail sharding (SFD, large orders)",
            "type": "boolean",
            "description": "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": {
            "title": "Min price (CNY)",
            "minimum": 0,
            "type": "integer",
            "description": "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": {
            "title": "Max price (CNY)",
            "minimum": 0,
            "type": "integer",
            "description": "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": {
            "title": "Dropship-only",
            "type": "boolean",
            "description": "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.",
            "default": true
          },
          "maxMOQ": {
            "title": "Max MOQ",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "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": {
            "title": "Supplier type",
            "enum": [
              "any",
              "superFactory",
              "verifiedMerchant"
            ],
            "type": "string",
            "description": "Filter by supplier verification level on 1688.",
            "default": "any"
          },
          "province": {
            "title": "Supplier province (Chinese)",
            "type": "string",
            "description": "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": {
            "title": "Supplier city (Chinese)",
            "type": "string",
            "description": "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": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "bestSelling",
              "priceAsc",
              "priceDesc",
              "dropshipScore"
            ],
            "type": "string",
            "description": "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.",
            "default": "relevance"
          },
          "sortType": {
            "title": "Advanced sort override",
            "enum": [
              "normal",
              "booked",
              "va_rmdarkgvm30",
              "va_price_asc",
              "va_price_desc"
            ],
            "type": "string",
            "description": "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.",
            "default": "normal"
          },
          "includeEnglishTranslation": {
            "title": "Include English titles",
            "type": "boolean",
            "description": "Translate Chinese product titles into English. Adds a 'titleEn' field to each result.",
            "default": true
          },
          "includeLandedCost": {
            "title": "Include landed cost estimate",
            "type": "boolean",
            "description": "Estimate the total landed cost (unit cost + shipping + duty + platform fee) and suggested retail price. Adds an 'estLandedCostUsd' object to each result.",
            "default": true
          },
          "includeCompliance": {
            "title": "Include compliance hints",
            "type": "boolean",
            "description": "Generate compliance hints (FDA, FCC, CE, Prop 65, ASTM F963, etc.) for the target market. Adds a 'compliance' object to each result.",
            "default": true
          },
          "targetMarket": {
            "title": "Target market",
            "enum": [
              "US",
              "EU",
              "UK",
              "AU",
              "global"
            ],
            "type": "string",
            "description": "Target market used for landed cost and compliance calculations.",
            "default": "US"
          },
          "shippingWeightMax": {
            "title": "Max shipping weight (kg)",
            "minimum": 0,
            "type": "number",
            "description": "Exclude products heavier than this value (in kilograms). Useful for keeping international shipping costs under control."
          },
          "excludeFoodProducts": {
            "title": "Exclude pet food",
            "type": "boolean",
            "description": "Exclude pet food and treat products (which often require import permits, FDA registration, and have complex labeling requirements).",
            "default": true
          },
          "includeSkuDetails": {
            "title": "Include SKU details",
            "type": "boolean",
            "description": "Fetch and include detailed SKU/specification data for each product. Automatically included when specs are available from the detail API. Increases run time.",
            "default": false
          },
          "includeDescriptionImages": {
            "title": "Include description images",
            "type": "boolean",
            "description": "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.",
            "default": true
          },
          "offerIds": {
            "title": "1688 product IDs (direct fetch)",
            "type": "array",
            "description": "1688 product IDs to fetch directly, bypassing search. When provided, the Actor skips keyword search and fetches details for each ID.",
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max search pages per keyword",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum number of search pages to crawl per keyword. Stops at maxResults or maxPages, whichever comes first."
          },
          "maxRunTimeSecs": {
            "title": "Max run time (seconds)",
            "minimum": 60,
            "maximum": 780,
            "type": "integer",
            "description": "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).",
            "default": 780
          },
          "mintOnMiss": {
            "title": "Mint token on cache miss",
            "type": "boolean",
            "description": "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.",
            "default": true
          },
          "detailIdentityRotation": {
            "title": "Detail identity rotation (experiment)",
            "type": "boolean",
            "description": "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.",
            "default": false
          },
          "skipDetails": {
            "title": "Skip product details (search-only fast path)",
            "type": "boolean",
            "description": "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.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify proxy configuration. For production runs targeting 1688.com, use RESIDENTIAL proxies in China (countryCode: CN). Leave empty to use no proxy (development)."
          },
          "searchMode": {
            "title": "Search mode",
            "enum": [
              "auto",
              "mtop_only"
            ],
            "type": "string",
            "description": "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.",
            "default": "auto"
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}