1688 API Tutorial: Search Products and Retrieve Details with Python
Build a small 1688 API workflow with keyword search, product details and JSON output. Learn pagination, price filters, English output and error handling.
From a sourcing keyword to a product record
A 1688 product data workflow usually needs two different operations: find listings that match a sourcing question, then inspect a specific listing. This guide uses Just One API to search for “保温杯” (insulated cups), lets you select one product, and retrieves its details in English. You can use the saved records to start a catalog or sourcing comparison.
Just One API is a third-party data API service. This tutorial is about reading marketplace data; it does not place orders or provide access to a seller's private account. If you are looking for a 1688 scraper API, start by checking that the returned data contains the fields your application needs.
The keyword is an integration example. Search results are a sample of available listings, not a complete market inventory or a supplier quality assessment.
Choose the endpoint for each input
Use Product Search V2 when your input is a keyword. Use Product Details V2 when you have a product ID. If you have a listing URL instead, use Product Details by URL V1; do not pass a full URL as itemId.
The two endpoints used in the script are GET requests:
/api/1688/search-item-list/v2: requirestokenandkeyword./api/1688/get-item-detail/v2: requirestokenanditemId.
Create an account at the Just One API dashboard, obtain your token, and confirm endpoint access and current pricing in your account before running requests. Check any available trial allowance there; this guide does not assume a fixed number of free calls.
Search one page before expanding the collection
Product Search V2 starts at page=1. pageSize requests a number of results; the returned count can differ. This example requests 10 listings from the first page and sorts by ascending price with sort=price_up. Other documented sort values are default, sales and price_down.
For a price range, add priceStart and priceEnd as strings, for example "20" and "80". These search filters are in CNY. Keep the keyword, filters and sorting unchanged when requesting the next page. Pagination is supported, but this sample deliberately reads only page 1.
The endpoint also documents sourcing filters such as moq and supportDropshipping. Confirm the returned listings meet your requirements before using a filter in procurement decisions; a filter is not an independent verification of a supplier or an available shipping service.
Select a product and request English details
Open the saved search data and select a valid product ID for the details request. Inspect the actual response example in the documentation before writing an automatic ID extractor: field nesting can differ between endpoints and versions. The script therefore takes an explicit --item-id rather than guessing a response path.
Details V2 accepts language=en for English output; the documented default is zh. This option belongs to the details endpoint and is not a language parameter for Product Search V2. The details endpoint also has an optional scene=drop_shipping pricing scene. This sample omits it; compare results under the same scene if your application needs dropshipping prices.
Keep listing-level, SKU-level and quantity-dependent prices separate when those fields are present. Record the collection time and the applicable quantity, specification and pricing context. An absent field is unknown, not zero stock or zero sales, and a displayed offer price is not a confirmed landed purchase cost.
Python example: one request per command
Install requests and set your token in a macOS or Linux terminal. your_token is a placeholder. Keep real tokens out of source control, shared screenshots and request logs.
python3 -m pip install requests
export JUSTONEAPI_TOKEN='your_token'Save the following as 1688_sample.py. Each invocation makes one API request, with no automatic retries, redirects or pagination. It checks both HTTP status and business code=0. It saves the returned data with a collection time and endpoint path, without writing the full response envelope or echoed request parameters.
import argparse
import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
def main():
parser = argparse.ArgumentParser()
parser.add_argument("mode", choices=("search", "detail"))
parser.add_argument("--keyword")
parser.add_argument("--item-id")
parser.add_argument("--output", required=True)
args = parser.parse_args()
if args.mode == "search" and not (args.keyword or "").strip():
parser.error("search requires --keyword")
if args.mode == "detail" and not (args.item_id or "").strip():
parser.error("detail requires --item-id")
output = Path(args.output)
if output.exists() or not output.parent.is_dir():
raise SystemExit("Use a new output filename in an existing folder.")
token = os.environ.get("JUSTONEAPI_TOKEN", "").strip()
if not token or token == "your_token":
raise SystemExit("Set JUSTONEAPI_TOKEN to your own API token.")
if args.mode == "search":
path = "/api/1688/search-item-list/v2"
params = {"keyword": args.keyword, "page": 1,
"pageSize": 10, "sort": "price_up"}
else:
path = "/api/1688/get-item-detail/v2"
params = {"itemId": args.item_id, "language": "en"}
try:
response = requests.get("https://api.justoneapi.com" + path,
params={**params, "token": token},
timeout=120, allow_redirects=False)
except requests.RequestException:
raise SystemExit("No confirmed result. No automatic retry was made; "
"check request records before repeating.") from None
try:
payload = response.json()
except ValueError:
raise SystemExit("Expected a JSON response; no result file was saved.") from None
if response.status_code != 200:
raise SystemExit(f"HTTP {response.status_code}; no result file was saved.")
if not isinstance(payload, dict):
raise SystemExit("Unexpected response structure; inspect the documentation.")
code = payload.get("code")
if type(code) is not int or code != 0:
label = str(code) if type(code) is int else "missing/invalid"
raise SystemExit(f"Business code {label}; no result file was saved.")
if "data" not in payload:
raise SystemExit("Success envelope has no data field; inspect the documentation.")
result = {"collected_at_utc": datetime.now(timezone.utc).isoformat(),
"endpoint": path, "data": payload["data"]}
with output.open("x", encoding="utf-8") as file:
json.dump(result, file, ensure_ascii=False, indent=2)
print(f"Saved {output.name}")
if __name__ == "__main__":
main()Run a single product search:
python3 1688_sample.py search --keyword '保温杯' --output search.jsonInspect search.json, select a real product ID and replace YOUR_ITEM_ID below. Use a new output filename for each request so a later run cannot silently overwrite an earlier sample.
python3 1688_sample.py detail --item-id YOUR_ITEM_ID --output detail.jsonRunning both commands once makes two requests. The script does not choose products, contact suppliers or submit orders. The saved data keeps the response shape as returned; a later CSV conversion should use field mappings that you have checked against your actual response.
Handle failures before increasing volume
A response is usable only after checking HTTP status and the business result. The usage guide explains 100 for an invalid or inactive token, 301 for a collection failure, 302 for a rate limit, 303 for a daily quota, 600 for permission denied, 601 for insufficient balance and 602 for a token budget being reached.
Correct the relevant account setting or request before repeating. A timeout does not establish whether the server completed the request. This script stops without retrying; check request records before submitting another potentially chargeable call. Do not log the full request URL, because authentication is supplied as a query parameter.
Common questions
Can I treat a missing field as zero?
No. Preserve missing values as unknown. Compare the same specification, quantity, currency and pricing scene across collection times before interpreting a price change. This tutorial does not establish that stock or sales fields are available for every product.
Does the highest API version always give the best result?
No. Start with the 1688 endpoint directory and choose the version whose inputs and returned fields match your use case. Test your own sample before replacing a working integration.
Is this a purchase or supplier-verification API?
This workflow reads product data. It does not create orders, certify suppliers or guarantee product availability. Those decisions need additional checks outside the sample.
Test one keyword and one known listing
Start with the Product Search V2 documentation, then open Product Details V2 for one selected item. Confirm data coverage and account access before expanding the workflow. If your required data is absent from the current documentation, describe the requirement to Just One API for a custom collection assessment.
Continue with Just One API
Log in to the Dashboard for your token, read the full API docs, or open the MCP GitHub project for the latest configuration.