1688 Supplier Finder — Bulk Supplier Shortlist & Comparison avatar

1688 Supplier Finder — Bulk Supplier Shortlist & Comparison

Pricing

from $2.10 / 1,000 delivered supplier shortlist rows

Go to Apify Store
1688 Supplier Finder — Bulk Supplier Shortlist & Comparison

1688 Supplier Finder — Bulk Supplier Shortlist & Comparison

Compare 1688 suppliers across your whole product list: a ranked, deduplicated shortlist per product with prices, MOQ and estimated landed cost, plus a free rollup of the suppliers that cover several of your SKUs.

Pricing

from $2.10 / 1,000 delivered supplier shortlist rows

Rating

0.0

(0)

Developer

Kyle Wang

Kyle Wang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Share

Send your product list. See which 1688 suppliers can cover several of your products, plus a short, ranked supplier shortlist for every product.

Built for multi-SKU sourcing: compare 1688 suppliers across a whole product catalog in one run. Send one product photo URL per product, as JSON or as a pasted CSV with your SKUs and ASINs. One run returns:

OutputWhat it answersCost
Supplier rollup: SUPPLIER_ROLLUP (JSON + CSV)Which suppliers show up for several of my products? Can I consolidate my catalog into fewer factories?Free
Shortlist rows: the datasetFor each product, the top offers (5 by default), deduplicated where company identity is known, ranked by estimated landed costPay per event
Input status: INPUT_STATUS (JSON + CSV)What happened to each product I sent?Free

Why the rollup comes first: buyers with a full catalog usually prefer a few stable suppliers to the cheapest offer per SKU. Fewer suppliers mean fewer relationships to manage, fewer sample rounds and simpler consolidated shipments. Every row carries supplierCatalogCoverage (how many of your products that supplier appears for), and the rollup lists suppliers by how many of your products they matched.

Pricing (FREE plan): $0.010 per matched product + $0.003 per row + $0.002 per enriched row, plus $0.01 once per run that delivers rows. 10 products × 5 offers with 1 enriched each = $0.28. Paid plans discount the three main events by 10–30%; the base fee stays $0.01. All examples below use FREE-plan prices. Failed, unmatched and skipped products cost nothing; there is no fee just for starting a run.

What the fee replaces: shortlisting 5 suppliers for each of 100 products by hand means opening, translating and costing about 500 listings. One run returns the ranked shortlists and the shared-supplier rollup for $2.71 (FREE plan, 1 enriched offer per product).

One product or a whole list? To look up a single product and see every raw candidate, use 1688 Image Search (up to 20 cards per image). Use this Actor when you need a decision across many products: a ranked shortlist per product and the suppliers they share.

Fewer rows, each ready for a decision

This Actor deliberately returns fewer rows than a raw search. Per product you get a short list (default 5) that is already:

  • Deduplicated where corporate identity is available: one offer per identified company per product (supplierDedupe). Offers without a reliable company ID cannot be deduplicated by supplier.
  • Ranked: by estimated landed cost (default), unit price, supplier years, match position or supplier coverage; rankBasis records which key placed each row.
  • Costed: the top offer of each product (enrichDepth: 1) gets a full product-detail fetch with price ladder, confirmed price, landed-cost and margin estimates and a dropship score, wherever 1688 provides the data.
  • Flat: one row per product × offer, carrying your clientSku and inputAsin, ready for spreadsheets, BI tools and joins.
  • Rolled up: suppliers grouped across your whole list, free of charge.

Quick start

Photos as JSON (products):

{
"products": [
{
"imageUrl": "https://cbu01.alicdn.com/img/ibank/15418323391_1847764777.jpg",
"clientSku": "SKU-001",
"asin": "B0EXAMPLE1"
},
{
"imageUrl": "https://cbu01.alicdn.com/img/ibank/O1CN01FCwJrl29btzNvQkHM_!!2235628087-0-cib.jpg_270x270xzq60.jpg",
"clientSku": "SKU-002"
}
],
"shortlistSize": 5,
"enrichDepth": 1,
"sortBy": "landedCost",
"targetMarket": "US"
}

If both photos match and each fills its shortlist: $0.01 + 2 × $0.010 + 10 × $0.003 + 2 × $0.002 = $0.064.

A pasted CSV (productsCsv, header row required):

sku,asin,image_url,title
SKU-001,B0EXAMPLE1,https://cbu01.alicdn.com/img/ibank/15418323391_1847764777.jpg,
SKU-002,,https://cbu01.alicdn.com/img/ibank/O1CN01FCwJrl29btzNvQkHM_!!2235628087-0-cib.jpg_270x270xzq60.jpg,

Every data row needs a photo URL; title is only an optional reference label, not a search input. All other settings keep their defaults (5 offers per product, enrichDepth 1, ranked by landed cost, US market). If both rows match and fill their shortlists, the run costs $0.064. Through the API, send the same text as one JSON string with \n line breaks.

When the run finishes, the Output tab links the rows, SUPPLIER_ROLLUP.csv and INPUT_STATUS.csv.

Every recommended setup uses enrichDepth: 1: the top offer of each product gets a full product detail (price ladder, confirmed price and, where available, a landed-cost estimate) for $0.002, and the other rows stay list-level.

GoalSendSettings
Amazon FBA / private label sourcingPhotos of products you plan to sell (your own shot or a listing's main image), with SKU and ASIN as labelsshortlistSize: 5, enrichDepth: 1, sortBy: "landedCost", targetMarket = your marketplace
Consolidate a catalog into fewer suppliersYour catalog as a CSV with image URLsshortlistSize: 5, enrichDepth: 1, sortBy: "supplierCoverage", then read SUPPLIER_ROLLUP.csv from the top
Dropshipping / multi-store product sourcingA store export with image URLsshortlistSize: 5, enrichDepth: 1, sortBy: "landedCost"
Brand looking for established manufacturersProduct photosshortlistSize: 5, enrichDepth: 1, sortBy: "supplierYears", then filter on isFactory
Automation or AI-agent pipelineOne API call per batch, on a scheduleAny of the above, with spend capped by maxTotalChargeUsd

Tips: product-only photos on a plain background match best. Put suppliers you have already rejected into excludeSupplierIds.

How it works

  1. Match. Each photo goes through 1688's reverse image search. Up to maxResultsPerProduct candidates (default 20) are collected per product. An optional input title is copied back as a label; title-only searching is not supported.
  2. Filter and count coverage. Suppliers in excludeSupplierIds and candidates below minMatchScore are removed. For every identified company, the Actor then counts how many of your products it appears for (supplierCatalogCoverage).
  3. Shortlist. Remaining candidates are sorted by sortBy (landed cost is not known yet, so landedCost sorts by unit price). Each identified company keeps its best offer per product, and the top shortlistSize remain.
  4. Enrich. The first enrichDepth offers of each shortlist get a full product-detail fetch.
  5. Final rank. With sortBy: "landedCost", rows with a landed-cost estimate come first (cheapest first) and the rest follow by unit price. rank runs from 1 to shortlistSize; rankBasis records the key used.
  6. Deliver. Rows go to the dataset; the rollup and the status list go to the key-value store.

Input

FieldTypeDefaultMeaning
productsarray—Items like {"imageUrl": "...", "clientSku": "...", "asin": "..."}. Each requires a public http(s) photo URL without credentials. title, clientSku and asin are optional reference labels; title-only entries are not searched.
productsCsvstring—Alternative to products: raw CSV text with an image URL header (up to 2 MB and 100 data rows). If both are sent, products is used.
shortlistSizeinteger5Offers returned per product (1–10).
enrichDepthinteger1 (from enrichDetails)How many of each product's top offers get a full detail fetch (0 to shortlistSize).
enrichDetailsbooleantrueUsed only when enrichDepth is not set: true gives 1, false gives 0.
maxResultsPerProductinteger20Candidate pool per product before filtering and ranking (1–20).
targetMarketenumUSUS, EU, UK, AU or global. Drives duty estimates and certification hints.
sortByenumlandedCostlandedCost, price, supplierYears, matchScore or supplierCoverage. With enrichDepth: 0, landedCost falls back to unit price.
minMatchScorenumber0Drop candidates below this relative score (0–1). 0 ranks without cutting anything.
supplierDedupebooleantrueKeep one offer per supplier per product.
excludeSupplierIdsarray[]Supplier companyId values to leave out.
maxTotalChargeUsdnumber20Spending cap for the run (minimum 0.04). See Pricing.

Over-long values are trimmed rather than rejected: titles to 200 characters, asin to 32, clientSku to 64.

Output: one flat row per product × offer

Each dataset item pairs one of your input products with one 1688 offer. Products that fail or don't match produce no rows. Every field is typed and described in the dataset schema.

Your input, echoed

FieldMeaning
inputIndex0-based position in your list (the first CSV data row is 0)
clientSkuYour SKU, unchanged
inputAsinYour ASIN label, unchanged; it is never looked up
inputTypeimage for supported inputs
inputImageUrl, inputTitleThe photo URL and title you sent

Match

FieldMeaning
matchScoreRelative score from 1688's result position: 1.0 = first result (see FAQ)
rankPosition in this product's shortlist (1 = best by your sortBy)
rankBasisThe key that placed the row: landedCost, price, supplierYears, matchScore or supplierCoverage
matchMethodimage (reverse image search)
enrichedtrue when a product-detail page was fetched and delivered for this row; false for list-level rows

Offer and price

FieldMeaning
offerId, offerUrl1688 offer ID and listing link
titleCNOriginal Chinese title (authoritative)
titleENBest-effort English machine translation
mainImageListing main image
categoryId1688 category ID, when the search result carries one
unitPriceCNY, unitPriceUSDUnit price for the product's MOQ tier: the lowest specification price at the highest quantity threshold reachable at moq. This is not the cheapest bulk-quantity price across all breaks; larger-quantity tiers stay in priceLadder. USD uses a fixed CNY/USD rate
priceBasisWhere the unit price came from: current_price_table_moq uses the MOQ-applicable tier, promotion_min and base_offer_min use the source range minimum, search_card is unverified list data, detail_minimum when the exact source path is unavailable
priceEvidenceKeyFree key-value record with the captured source price, MOQ, SKU/spec and capture time for audit. Null on list rows or if it could not be saved
moqMinimum order quantity
priceLadderPublished detail-price entries with quantity thresholds where supplied (enriched rows only). Equal thresholds can describe different specifications, not quantity discounts; a missing threshold stays null.

Supplier

FieldMeaning
companyId1688 company ID, or name:<registered company name> when available without a member ID; see companyIdSource. Used for dedupe, exclusions and rollup. Individual seller IDs and unverified keyword storefront labels are not published as company identities.
companyNameCompany name (in Chinese); blank for individual sellers. Storefront labels are not treated as independently verified registered identity.
yearsOnPlatformYears on 1688
verifiedFlagtrue when 1688 shows a factory-inspection or Super Factory badge
isFactory, isSuperFactory1688 search-card factory flag and Super Factory badge. bizType: "Manufacturer" is a separate business-model label and does not force isFactory to true
province, citySupplier location
supplierUrlSupplier's 1688 storefront when available; blank for individual sellers
supplierCatalogCoverageHow many of your products this supplier appears for in this run (counted over each product's candidate pool, after exclusions and minimum-match filtering)

Decision and compliance fields (enriched rows only)

FieldMeaning
landedCostUSDPlanning estimate per unit delivered to targetMarket: lowest published purchase price plus shipping, duty and fee estimates. It is not a quote for the variant, pack or quantity you choose
landedCostBasismatched_sku when the minimum price and weight come from the same explicit source SKU; otherwise minimum_price_representative_weight or minimum_price_inferred_weight marks a rough estimate
landedCostWeightKgWeight actually used by the cost estimate, including a price-based guess when no source weight exists
unitWeightKgSource weight from the detail page. It is the linked SKU weight when unambiguous, otherwise a representative SKU average; null when no source weight exists
unitWeightBasismatched_sku, representative_sku_average or price_inferred
costSkuId, costSpecSource SKU and sanitized specification used for a matched_sku estimate; null when no single SKU can be proved
suggestedRetailUSDLanded cost × a rule-of-thumb markup, not a market price check
estimatedMarginPctMargin implied by suggestedRetailUSD: a planning figure, not a profit forecast
dropshipScoreDropship-readiness heuristic from MOQ, dropship support and supplier signals (higher is better)
complianceFlagsKeyword-based risk hints (e.g. electronics and batteries, food, infant toys)
suggestedCertificationsCertifications often needed in targetMarket for this kind of product: hints, not legal advice

Trust

FieldMeaning
priceVerifiedtrue when a positive price was read from the captured detail payload. It does not prove the selected variant, current checkout price or product match; use priceEvidenceKey and scrapedAt for audit
detailLevellist (search data only), detail (detail page with price, price ladder and weight) or partial (detail page delivered, but the price, ladder or weight is missing)
scrapedAtWhen the row was read; on evidence-linked enriched rows, the detail payload capture time (ISO 8601)
sourceUrlThe 1688 offer page associated with the candidate or fetched detail

Rows that were not enriched leave the decision fields, compliance hints and priceLadder empty by design (see FAQ). The dataset also carries helper fields such as companyIdSource, factoryInspected, bizType, individualSeller, translationMethod, originalPriceCNY, hasDiscount, dropshipGrade and dataQuality; the dataset schema describes them all.

Price evidence: PRICE_EVIDENCE_<offerId> (free)

Each successfully fetched detail offer gets one JSON record in the run's key-value store. It keeps the captured price range, quantity thresholds, SKU IDs, sanitized specifications, source-linked weights, price basis and capture time. The selected minimum entry is preserved separately even if it falls beyond the array limit. Representative-weight evidence includes source units, bounded raw samples, count and aggregation. Arrays are capped with truncation counts. It does not store full HTML, cookie jars, authentication headers, proxy settings or seller personal data, and it never adds a billable row.

Supplier rollup: SUPPLIER_ROLLUP (free)

Your delivered rows grouped by companyId across the whole list. This is the "can I consolidate my catalog into fewer factories?" view. Suppliers covering the most of your products come first, then the cheapest. It needs no extra searches, costs nothing and is never written to the dataset, so it adds no billable rows. SUPPLIER_ROLLUP.csv holds the same data, with arrays joined by ;.

FieldMeaning
companyId, companyName, yearsOnPlatform, verifiedFlag, provinceSupplier identity and signals
matchedProductCountHow many of your products have at least one shortlist row from this supplier
matchedProductIndexesThose products' inputIndex values, to join back to your list
offerCountDistinct offers from this supplier across your shortlists
priceCnyMin, priceCnyMaxUnit-price range across those rows
landedCostUsdMinLowest landed-cost estimate (from enriched rows)
avgMatchScoreAverage matchScore of its rows
bestRankBest rank it reached in any shortlist
catalogCoverageHow many of your products it appeared for in the candidate pools; the same count as supplierCatalogCoverage, and it can be higher than matchedProductCount

The rollup covers one run. If you split a catalog across runs, merge the CSV files on companyId.

Input status: INPUT_STATUS (free)

One entry per input product (INPUT_STATUS.csv for spreadsheets): inputIndex, clientSku, inputAsin, inputType, status, rowsDelivered, enrichedRowsDelivered and a reason when something failed. Title-only input entries are invalid and never searched; optional title labels on image entries are echoed in the Dataset.

StatusMeaningCharged
OKDelivered at least one rowYes, see Pricing
INVALID_PRODUCTNo public photo URL, an unsafe/invalid image URL, or an unsupported title-only entryNo
IMAGE_FETCH_FAILEDThe photo could not be downloaded or is not a usable imageNo
NO_MATCH1688 returned no usable candidates, or none passed your filtersNo
RISK_CONTROL1688's anti-bot layer refused the queryNo
NETWORKNetwork or proxy failureNo
DEADLINE_SKIPPEDNot reached within the run's time windowNo
SKIPPED_QUOTAYour maxTotalChargeUsd could not fully cover itNo

The key-value store also holds SUMMARY (run report: charged vs intended events, counts, warnings) and OUTPUT (final errorCode and message).

Pricing (pay per event)

EventFREEBRONZESILVERGOLDPLATINUMDIAMONDCharged when
run-base-fee$0.01$0.01$0.01$0.01$0.01$0.01Once per run, only if the run delivers at least one row
product-matched$0.010$0.009$0.008$0.007$0.007$0.007Per input product that delivers at least one row
shortlist-row$0.003$0.0027$0.0024$0.0021$0.0021$0.0021Per delivered dataset row
supplier-enriched$0.002$0.0018$0.0016$0.0014$0.0014$0.0014Per delivered row that received a full product-detail fetch (enriched: true)

Apify applies the subscription tier of the account running the Actor. BRONZE saves 10%, SILVER 20%, and GOLD, PLATINUM and DIAMOND 30% on the three main events. The base fee is never discounted. SUMMARY.eventPricesUsd, the budget precheck and the reported charge amounts use this run's actual prices.

Nothing is charged for products that fail, don't match or are skipped. There is no start fee and no platform-usage pass-through: proxy and compute costs are included. The rollup, the status list and the summary are free.

Worked examples at FREE-plan prices (every product matched, every shortlist full):

OrderCalculationTotal
2 photos × 5 offers, enrichDepth: 1 (quick start)$0.01 + 2 × $0.010 + 10 × $0.003 + 2 × $0.002$0.064
10 products × 5 offers, enrichDepth: 1$0.01 + 10 × $0.010 + 50 × $0.003 + 10 × $0.002$0.28
10 products × 5 offers, enrichDepth: 0$0.01 + 10 × $0.010 + 50 × $0.003$0.26
30 products × 5 offers, enrichDepth: 1$0.01 + 30 × $0.010 + 150 × $0.003 + 30 × $0.002$0.82

At FREE-plan prices, the most a matched product can cost is $0.010 + shortlistSize × $0.003 + enrichDepth × $0.002, which is $0.027 with the defaults. The same default product costs at most $0.0243 on BRONZE, $0.0216 on SILVER and $0.0189 on GOLD or above, plus the once-per-run base fee. A product with a shorter shortlist (for example, fewer distinct suppliers) costs less.

Budget cap. maxTotalChargeUsd defaults to $20 (minimum $0.04). Before searching, the run uses your subscription-tier prices to set aside the base fee and each product's maximum cost. Products at the end of your list that the cap cannot fully cover are skipped up front (SKIPPED_QUOTA), never searched and never charged, and the run reports QUOTA_BLOCKED. Rows already delivered are always kept.

Errors and run outcomes

errorCodeWhat happenedCharge
NO_INPUTNo products were sent, or every entry is empty$0
NO_IMAGE_INPUTNo product has a photo URL; title-only search is unsupported$0
INPUT_TOO_LONGMore products than one run accepts, or a CSV over 2 MB; split the list$0
CSV_PARSE_FAILEDThe CSV is unreadable or has no image URL column; the message lists the columns it detected$0
ENRICH_CAP_EXCEEDEDProducts × enrichDepth would exceed 400 full-detail fetches; the message suggests a valid configuration$0
QUOTA_BLOCKEDThe budget cap could not cover every product; the rest are SKIPPED_QUOTADelivered rows only
RISK_CONTROL_CANARY1688's risk control blocked the opening image search on every attempt, so the photo products were not searched (RISK_CONTROL)Delivered rows only
CIRCUIT_BREAKERImage search stopped after repeated risk-control blocks; the remaining photo products are RISK_CONTROLDelivered rows only
PARTIAL_DEADLINEThe time budget skipped some products (DEADLINE_SKIPPED)Delivered rows only; skipped products are free

The first five are validation errors: the run stops before any search. The errorCode is reported in OUTPUT and SUMMARY.

What is not in the data

  • Reviews and ratings: reviewCount and rating are not provided.
  • responseRate: usually null.
  • Category path: only categoryId is provided.
  • Personal data, excluded on purpose: no seller login IDs, personal phone numbers, emails or messenger handles, no buyer reviews or Q&A, and no person-level credit scores. Individual sellers have company IDs, company names, corporate badges and storefront URLs blanked. Keyword storefront labels are not published as registered company identities.

Limits & caveats

  • Up to 100 products per run. The default configuration (5 shortlist rows and 1 enrichment target per product) completed the private 100-product test within the 40-minute timeout. This is a workload limit, not a guarantee that every image matches or every field exists. Larger lists are rejected before any search (INPUT_TOO_LONG, no charge). More aggressive enrichment settings and shorter timeouts can cause partial delivery; use INPUT_STATUS and SUMMARY to check actual results.
  • Enrichment cap. A run can fetch at most 400 full details (products × enrichDepth). This is separate from the per-run product limit.
  • Similar is not the same. Visual similarity is not proof of the same product or of the original factory, and many 1688 sellers reuse the same photos. Title-only search is not supported, and matchScore only reflects 1688's result order. Confirm with the supplier and order samples.
  • Estimates are estimates. landedCostUSD uses the MOQ-tier unit price, a fixed CNY/USD rate, a per-kg shipping estimate, a duty rate for your targetMarket and a generic fee allowance. It is not a quote for a larger bulk order at a deeper discount; check priceLadder for the full tier schedule. landedCostBasis: "matched_sku" means the price and weight are linked to one source SKU; any other basis is a rough minimum-price estimate with representative or inferred weight. It does not include Amazon FBA fees, storage, advertising or returns. suggestedRetailUSD and estimatedMarginPct come from a markup rule, not market prices. None of these figures is a quote or a profit forecast.
  • Prices are indicative unless priceVerified is true; even then, check the variant and date. 1688 prices vary with quantity, variant and time. Use priceLadder, priceBasis, priceEvidenceKey and scrapedAt.
  • Badges come from 1688, not from us. verifiedFlag, isFactory and isSuperFactory reflect what 1688 displays. bizType is a separate seller business-model label, so Manufacturer with isFactory: false can both come from 1688. We do not verify identity, licenses or production capacity.
  • Chinese-first source. titleCN is authoritative, titleEN is a machine translation, and company names stay in Chinese.
  • 1688 risk control. Some queries are refused (RISK_CONTROL). Those products are not charged and are reported individually.
  • Compliance hints are keyword-based: a starting point for your own checks, not legal advice.

FAQ

Can I use this for Amazon FBA sourcing?

Yes. Send the products you plan to sell, using your own photo or a listing's main image, with your ASIN and SKU as labels. Each product gets a ranked 1688 shortlist, its top offer gets a landed-cost estimate for your targetMarket (US, EU, UK or AU) whenever the detail page confirms a price, and the rollup shows suppliers that could carry several of your products. Typical next steps: confirm the product and the supplier, request quotes, order samples and check compliance. The Actor does not check FBA eligibility, category restrictions or Amazon fees.

Does it work for product sourcing beyond Amazon?

Yes. Nothing is Amazon-specific apart from the labels you choose to send. Dropshipping and Shopify sellers get MOQ on every row and dropshipScore on enriched rows. Private label buyers can rank by supplierYears and filter on isFactory and verifiedFlag.

Can it look up my ASINs?

No. asin is only an echo label: it is copied unchanged to inputAsin so you can join results back to your sheet. Nothing is fetched from Amazon. To source an ASIN, send the listing's main image URL as imageUrl. A title may accompany the photo as a reference label but cannot replace it.

What CSV format does it accept?

  • A header row is required. Use comma-separated UTF-8 text; a BOM, quoted fields (with commas, quotes or line breaks inside) and blank lines are all handled.
  • Column names are case-insensitive. Photo: image_url, imageUrl, image, img or image url. Title: title, name, product, product_name or product name. ASIN: asin. SKU: sku, clientSku, client_sku or id. Other columns are ignored.
  • You need a photo URL column. An optional title column is a reference label only. Missing photo columns return CSV_PARSE_FAILED (free), including the columns detected. Duplicate aliases, malformed quotes and unequal column counts are rejected rather than silently losing data.
  • Copying cells straight out of Excel or Google Sheets produces tab-separated text. Export or download the sheet as CSV instead.
  • inputIndex 0 is the first data row after the header.

Why do some rows have no landed cost?

By design. Only the top enrichDepth offers of each product (1 by default) get a full product-detail fetch. The other rows are list-level (enriched: false, detailLevel: "list") and leave landedCostUSD, its basis and weight fields, costSkuId, costSpec, priceEvidenceKey, suggestedRetailUSD, estimatedMarginPct, dropshipScore, the compliance hints and priceLadder empty. Raise enrichDepth (up to shortlistSize, at $0.002 per enriched row) if you need these fields on more rows. Landed cost also needs a positive price read from the detail page, so an enriched row with priceVerified: false has none. If a detail fetch fails, the row stays list-level and the enrichment fee is not charged.

What does matchScore mean?

It is a relative score derived from 1688's result order. 1.0 is 1688's first result, and the score falls linearly with position (0.95, 0.90 and so on with the default maxResultsPerProduct of 20). 1688 returns no absolute similarity value, so matchScore is not a similarity percentage, it shifts when you change the pool size, and it should not be compared across products. Visual similarity is not proof of the same product or the original factory. minMatchScore (default 0) filters on this score; 0.5, for example, keeps roughly the top half of 1688's results.

Can I search by title alone?

No. The first release requires a public product photo URL for every product. Title-only searching did not pass the private validation gate and is not offered. You can include title alongside imageUrl as a reference label for joining results to your catalog.

How many products can I send in one run?

At most 100 products. The default 5-row shortlist and 1 enriched offer per product were tested at this size. Lists over 100 stop before searching with INPUT_TOO_LONG and cost nothing; split them across runs. Each run adds one $0.01 base fee only if it delivers rows. The first release does not support a 250-product run.

How do I find suppliers that cover many of my products?

Open SUPPLIER_ROLLUP.csv. Suppliers covering the most of your products are listed first, with their price range, lowest landed-cost estimate and matchedProductIndexes. To make every shortlist prefer those suppliers, set sortBy: "supplierCoverage".

Do I need a 1688 account?

No account, login or cookies. Proxy and compute costs are included in the event prices.

The Actor reads publicly visible 1688 listing data and deliberately leaves out personal data (see What is not in the data). You are responsible for how you use the data and for complying with 1688's terms and applicable laws.

API

Start a run:

curl -X POST "https://api.apify.com/v2/acts/crawleast~1688-supplier-finder/runs" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"products": [
{ "imageUrl": "https://example.com/product-1.jpg", "clientSku": "SKU-001", "asin": "B0EXAMPLE1" },
{ "imageUrl": "https://cbu01.alicdn.com/img/ibank/15418323391_1847764777.jpg", "title": "Product reference", "clientSku": "SKU-002" }
],
"shortlistSize": 5,
"enrichDepth": 1,
"sortBy": "landedCost",
"targetMarket": "US",
"maxTotalChargeUsd": 5
}'

The response contains the run id. Once the run has finished, read the outputs:

RUN_ID="<run id>"
curl -H "Authorization: Bearer YOUR_APIFY_TOKEN" "https://api.apify.com/v2/actor-runs/$RUN_ID/dataset/items?format=csv"
curl -H "Authorization: Bearer YOUR_APIFY_TOKEN" "https://api.apify.com/v2/actor-runs/$RUN_ID/key-value-store/records/SUPPLIER_ROLLUP.csv"
curl -H "Authorization: Bearer YOUR_APIFY_TOKEN" "https://api.apify.com/v2/actor-runs/$RUN_ID/key-value-store/records/INPUT_STATUS"

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
with open("catalog.csv", encoding="utf-8") as f:
run = client.actor("crawleast/1688-supplier-finder").call(run_input={
"productsCsv": f.read(),
"shortlistSize": 5,
"enrichDepth": 1,
"sortBy": "supplierCoverage",
})
rows = client.dataset(run["defaultDatasetId"]).list_items().items
store = client.key_value_store(run["defaultKeyValueStoreId"])
rollup = store.get_record("SUPPLIER_ROLLUP")["value"]
status = store.get_record("INPUT_STATUS")["value"]

Long lists take minutes, so prefer starting the run and reading its storages afterwards over synchronous endpoints, which can time out.

For AI agents and pipelines

Input, dataset, key-value store and output schemas are all declared, rows are flat (join on inputIndex or clientSku), INPUT_STATUS and OUTPUT.errorCode report per-product and run outcomes, and maxTotalChargeUsd caps spend. Copy this to your AI assistant:

Use the Apify Actor crawleast/1688-supplier-finder to shortlist 1688 suppliers
for a product list. Batch products into as few runs as possible, sent as
"products" ([{"imageUrl": "...", "clientSku": "..."}]) or "productsCsv", with
shortlistSize 5, enrichDepth 1, sortBy "landedCost" and a maxTotalChargeUsd cap.
Read the dataset rows (one per product x offer), SUPPLIER_ROLLUP (suppliers that
cover several products) and INPUT_STATUS (what happened to each product).
Treat landedCostUSD and estimatedMarginPct as estimates, matchScore as a
relative position score, and visual matches as candidates to verify.
  • 1688 Image Search Scraper: up to 20 raw candidate cards per photo, base64 photo uploads and offer-ID detail lookups.
  • 1688 Product Scraper: keyword research across 1688 categories, with English titles, MOQ price ladders and supplier signals.

Feedback & changelog

Found a bug or missing a field? Open an Issue with the run ID. Release history is in the Changelog tab.


Data is provided "as is" for research and sourcing decisions. Prices, landed-cost and margin figures, scores and compliance hints are estimates; verify independently before committing funds. Not affiliated with 1688.com, Alibaba Group or Amazon.