Partner Integration API Documentation
Overview
This API allows external partners to integrate with our B2B merchandise system. It provides endpoints for order management, product information, and category management.
Authentication
All API endpoints require a valid access token. Add the following header to your requests:
Authorization: Bearer <access_token>
the access token will be associated with one customer on the caomuju.com website.
you can see the orders created from this token.
ask the admin to associate your token with your account.
Product Management APIs
List Products
POST /rest/V1/external/products
Retrieves a paginated list of products with optional filtering.
Request Body
currently type parameter only supports test
{
"type": "string", // Required: Product type or tag to filter by: currently only supports "test"
"page_num": "integer", // Optional: Page number (default: 1)
"page_size": "integer", // Optional: Items per page (default: 20)
"language": "string", // Optional: Response language: "en", "cn", "mn", or null (defaults to en)
"filters": { // Optional: Additional filters
"category_id": "integer", // Optional: Filter by category ID (includes all descendants)
"keyword": "string", // Optional: Search by keyword in product name
"brand": "string" // Optional: Filter by brand name (partial match)
}
}
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| type | string | Yes | - | Product type or tag to filter by. Currently only supports “test” |
| page_num | integer | No | 1 | Page number for pagination |
| page_size | integer | No | 20 | Number of items per page, max 500 |
| language | string | No | en | Response language: “en”, “cn”, “mn”, or null (defaults to en) |
| filters.category_id | integer | No | - | Filter products by category ID (includes all descendant categories) |
| filters.keyword | string | No | - | Search products by keyword in product name |
| filters.brand | string | No | - | Filter products by brand name (partial match) |
Response Fields
| Field | Type | Description |
|---|---|---|
| sku_id | string | Product SKU identifier |
| sku_name | string | Product name |
| sku_pics | array | Array of all product image URLs |
| selling_price | float | Selling price per unit |
| stock | integer | Available stock quantity |
| min_sell_qty | integer | Minimum quantity that can be ordered |
| category_name | string | Category name |
| category_id | integer | Category ID |
| brand_name | string | Brand name |
| description | string | Product description |
| length | string | Product length with unit (e.g., “715/mm”) |
| width | string | Product width with unit (e.g., “290/mm”) |
| height | string | Product height with unit (e.g., “75/mm”) |
| weight | string | Product weight with unit (e.g., “0.700000/kg”) |
Response
{
"code": 200,
"msg": "success",
"response_data": {
"page_num": "integer",
"page_size": "integer",
"total": "integer",
"pages": "integer",
"list": [
{
"sku_id": "string",
"sku_name": "string",
"sku_pics": ["string"],
"selling_price": "float",
"stock": "integer",
"min_sell_qty": "integer",
"category_name": "string",
"category_id": "integer",
"brand_name": "string",
"description": "string"
}
]
}
}
Response Example
{
"code": 200,
"msg": "success",
"response_data": {
"page_num": 1,
"page_size": 2,
"total": 511,
"pages": 256,
"list": [
{
"sku_id": "201806100009",
"sku_name": "Rabbit instant noodle bowl 6621",
"sku_pics": [
"https://192.168.41.28/media/catalog/product/I/D/ID_A89A5CDA754043E4A49ECFE15B5CDFBE.jpeg",
"https://192.168.41.28/media/catalog/product/I/D/ID_3A315670A9414F23B633C7DDCB323D67.jpeg"
],
"selling_price": 10.8,
"stock": 10000,
"min_sell_qty": 10,
"category_name": "Instant Noodles",
"category_id": 123,
"brand_name": "Brand Name",
"description": "Product description",
"length": "715/mm",
"width": "290/mm",
"height": "75/mm",
"weight": "0.700000/kg"
},
{
"sku_id": "201806100010",
"sku_name": "Rabbit instant noodle bowl",
"sku_pics": [
"https://192.168.41.28/media/catalog/product/I/D/ID_3A315670A9414F23B633C7DDCB323D67.jpeg"
],
"selling_price": 10.8,
"stock": 10000,
"min_sell_qty": 5,
"category_name": "Instant Noodles",
"category_id": 123,
"brand_name": "Brand Name",
"description": "Product description",
"length": "715/mm",
"width": "290/mm",
"height": "75/mm",
"weight": "0.700000/kg"
}
]
}
}
Notes
- All timestamps are in ISO 8601 format with UTC+8 timezone
- Returns a flat list of products - each product is returned individually
- The
typeparameter must match the product type or tag you wish to filter by (currently onlytestis supported) - Pagination is supported via
page_numandpage_size - The
keywordfilter searches the product catalog using OpenSearch and returns matching products - The
brandfilter performs a partial match on brand name using OpenSearch - Brand and keyword filters can be combined with
category_idfilter - The
category_idfilter includes all products in the specified category AND all its descendant categories sku_picsis an array containing all available product imagesmin_sell_qtyindicates the minimum quantity that must be ordered for this product
Get Product Details
GET /rest/V1/external/product/detail/{sku}
Retrieves detailed information about a specific product.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| sku | string | Yes | Product SKU to lookup |
Query Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| language | string | No | en | Response language: “en”, “cn”, “mn”, or null (defaults to en) |
Response
{
"code": 200,
"msg": "success",
"variants": [
{
"variant_id": "integer",
"variant_name": "string",
"options": [
{
"option_id": "integer",
"option_value": "string"
}
]
}
],
"products": [
{
"sku_id": "string",
"sku_name": "string",
"sku_pic": "string",
"selling_price": "float",
"stock": "integer",
"description": "string",
"category_path": "string",
"category_id": "integer",
"brand_name": "string",
"tag": "string",
"length": "string",
"width": "string",
"height": "string",
"weight": "string",
"variant_options": [
{
"variant_id": "integer",
"option_id": "integer"
}
]
}
]
}
Response Example
{
"code": 200,
"msg": "success",
"variants": [
{
"variant_id": 152,
"variant_name": "Color",
"options": [
{"option_id": 1234, "option_value": "Red"},
{"option_id": 1235, "option_value": "Blue"}
]
},
{
"variant_id": 153,
"variant_name": "Size",
"options": [
{"option_id": 2345, "option_value": "Small"},
{"option_id": 2346, "option_value": "Large"}
]
}
],
"products": [
{
"sku_id": "201806100009",
"sku_name": "Rabbit instant noodle bowl 6621",
"sku_pic": "https://192.168.41.28/media/catalog/product/I/D/ID_A89A5CDA754043E4A49ECFE15B5CDFBE.jpeg",
"selling_price": 10.8,
"stock": 10000,
"description": "Product description",
"category_path": "Food > Instant Noodles",
"category_id": 27619,
"brand_name": "Brand Name",
"tag": "popular",
"length": "715/mm",
"width": "290/mm",
"height": "75/mm",
"weight": "0.700000/kg",
"variant_options": [
{"variant_id": 152, "option_id": 1234},
{"variant_id": 153, "option_id": 2345}
]
},
{
"sku_id": "201806100010",
"sku_name": "Rabbit instant noodle bowl",
"sku_pic": "https://192.168.41.28/media/catalog/product/I/D/ID_3A315670A9414F23B633C7DDCB323D67.jpeg",
"selling_price": 10.8,
"stock": 10000,
"description": "Product description",
"category_path": "Food > Instant Noodles",
"category_id": 27619,
"brand_name": "Brand Name",
"tag": "popular",
"length": "715/mm",
"width": "290/mm",
"height": "75/mm",
"weight": "0.700000/kg",
"variant_options": [
{"variant_id": 152, "option_id": 1235},
{"variant_id": 153, "option_id": 2346}
]
}
]
}
Response Structure
The response contains two arrays:
variants- Describes all variant attributes (e.g., Color, Size) and their available options. This is metadata about what variants exist.products- Contains the actual product items with their variant option references. Each product’svariant_optionsarray links to specific variant options viavariant_idandoption_id.
For simple products (not part of a configurable), the variants array will be empty and products will contain a single product.
Check Availability
POST /rest/V1/external/availability/check
Checks the availability of multiple SKUs using JD VOP API. Returns a list of unavailable SKUs that cannot be purchased.
Request Body
{
"skus": [
{
"sku": "string", // Required: Product SKU
"quantity": "integer" // Required: Quantity to check
}
]
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| skus | array | Yes | Array of SKU-quantity pairs to check availability for |
| skus[].sku | string | Yes | Product SKU identifier |
| skus[].quantity | integer | Yes | Quantity to check for availability |
Response
{
"code": 200,
"msg": "success",
"delivery_price": 25.50, // Delivery price for the order
"unavailable_skus": [
{
"sku": "string", // SKU that is unavailable
"can_purchase": false // Indicates if the SKU can be purchased (will always be false here)
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| code | integer | Response code (200 for success) |
| msg | string | Response message |
| delivery_price | float | Delivery price for the order (in CNY) |
| unavailable_skus | array | List of unavailable SKUs |
| unavailable_skus[].sku | string | SKU that is unavailable |
| unavailable_skus[].can_purchase | boolean | Indicates if the SKU can be purchased (will always be false) |
Notes
- This API checks product availability using JD VOP (Jingdong’s Open Platform) API
- Availability is checked for a fixed delivery area: Inner Mongolia, Xilingol League, Erenhot City, Erenhot Border Economic and Technological Cooperation Zone
- Only unavailable SKUs are returned in the response (empty array means all SKUs are available)
can_purchasefield will always befalsefor items in theunavailable_skusarray
Order Management APIs
Create Order
POST /rest/V1/external/order
Creates a new order in a single step, handling cart creation, item addition, address setting, and order placement internally.
Request Body
{
"po_number": "string",
"items": [
{
"sku": "string", // Required: Product SKU
"qty": "integer" // Required: Quantity of the product
}
],
"firstname": "string", // Optional: First name (default: "Shoppy")
"lastname": "string", // Optional: Last name (default: "MN")
"street": "string", // Optional: Street address (default: "UB")
"city": "string", // Optional: City (default: "UB")
"postcode": "string", // Optional: Postal code (default: "18010")
"country_id": "string", // Optional: Country code (default: "CN")
"telephone": "string", // Optional: Phone number (default: "111-222-3333")
"state": "string" // Optional: State/Province for shipping/billing address
}
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| po_number | string | No | - | Purchase Order number for the order. When omitted, order will be created in waiting_confirmation status |
| items | array | Yes | - | Array of items to be ordered |
| items[].sku | string | Yes | - | Product SKU identifier |
| items[].qty | integer | Yes | - | Quantity of the product to order |
| firstname | string | No | Shoppy | First name for shipping/billing address |
| lastname | string | No | MN | Last name for shipping/billing address |
| street | string | No | UB | Street address for shipping/billing |
| city | string | No | UB | City for shipping/billing address |
| postcode | string | No | 18010 | Postal/ZIP code for shipping/billing address |
| country_id | string | No | CN | Country code (ISO 2-letter) for shipping/billing address |
| telephone | string | No | 111-222-3333 | Phone number for shipping/billing address |
| state | string | No | - | State/Province for shipping/billing address |
State Parameter Formats (China)
For orders with country_id: "CN", the state parameter supports multiple formats:
| Format | Example | Description |
|---|---|---|
| Region Code | CN-BJ |
Magento region code |
| Pinyin (Full) | Beijing Shi |
Full romanized name |
| Pinyin (Short) | Beijing |
Common short name |
| Chinese (Full) | 北京市 |
Full Chinese name with suffix |
| Chinese (Short) | 北京 |
Short Chinese name |
Example with Chinese state name:
{
"po_number": "PO-2024-001",
"items": [{"sku": "SKU123", "qty": 10}],
"firstname": "张",
"lastname": "三",
"street": "朝阳区xxx路123号",
"city": "北京",
"state": "北京",
"postcode": "100000",
"country_id": "CN",
"telephone": "+8613812345678"
}
China Regions Reference
| Code | Pinyin | Chinese | Short/Aliases |
|---|---|---|---|
| CN-AH | Anhui Sheng | 安徽省 | 安徽, Anhui |
| CN-BJ | Beijing Shi | 北京市 | 北京, Beijing |
| CN-CQ | Chongqing Shi | 重庆市 | 重庆, Chongqing |
| CN-FJ | Fujian Sheng | 福建省 | 福建, Fujian |
| CN-GS | Gansu Sheng | 甘肃省 | 甘肃, Gansu |
| CN-GD | Guangdong Sheng | 广东省 | 广东, Guangdong |
| CN-GX | Guangxi Zhuangzu Zizhiqu | 广西壮族自治区 | 广西, Guangxi |
| CN-GZ | Guizhou Sheng | 贵州省 | 贵州, Guizhou |
| CN-HI | Hainan Sheng | 海南省 | 海南, Hainan |
| CN-HE | Hebei Sheng | 河北省 | 河北, Hebei |
| CN-HL | Heilongjiang Sheng | 黑龙江省 | 黑龙江, Heilongjiang |
| CN-HA | Henan Sheng | 河南省 | 河南, Henan |
| CN-HK | Hong Kong SAR | 香港特别行政区 | 香港, Hong Kong, HK |
| CN-HB | Hubei Sheng | 湖北省 | 湖北, Hubei |
| CN-HN | Hunan Sheng | 湖南省 | 湖南, Hunan |
| CN-JS | Jiangsu Sheng | 江苏省 | 江苏, Jiangsu |
| CN-JX | Jiangxi Sheng | 江西省 | 江西, Jiangxi |
| CN-JL | Jilin Sheng | 吉林省 | 吉林, Jilin |
| CN-LN | Liaoning Sheng | 辽宁省 | 辽宁, Liaoning |
| CN-MO | Macao SAR | 澳门特别行政区 | 澳门, Macao, Macau, MO |
| CN-NM | Nei Mongol Zizhiqu | 内蒙古自治区 | 内蒙古, Nei Mongol, Inner Mongolia |
| CN-NX | Ningxia Huizi Zizhiqu | 宁夏回族自治区 | 宁夏, Ningxia |
| CN-QH | Qinghai Sheng | 青海省 | 青海, Qinghai |
| CN-SN | Shaanxi Sheng | 陕西省 | 陕西, Shaanxi |
| CN-SD | Shandong Sheng | 山东省 | 山东, Shandong |
| CN-SH | Shanghai Shi | 上海市 | 上海, Shanghai |
| CN-SX | Shanxi Sheng | 山西省 | 山西, Shanxi |
| CN-SC | Sichuan Sheng | 四川省 | 四川, Sichuan |
| CN-TW | Taiwan Sheng | 台湾省 | 台湾, Taiwan |
| CN-TJ | Tianjin Shi | 天津市 | 天津, Tianjin |
| CN-XJ | Xinjiang Uygur Zizhiqu | 新疆维吾尔自治区 | 新疆, Xinjiang |
| CN-XZ | Xizang Zizhiqu | 西藏自治区 | 西藏, Xizang, Tibet |
| CN-YN | Yunnan Sheng | 云南省 | 云南, Yunnan |
| CN-ZJ | Zhejiang Sheng | 浙江省 | 浙江, Zhejiang |
Response
{
"code": 200,
"msg": "success",
"order_number": "000000662",
"order_status": "po_submitted",
"total": 16.2
}
Status Behavior
- With
po_numberprovided: Order status will bepo_submitted - Without
po_number: Order status will bewaiting_confirmation(ready for PO submission later)
Example: Create Order With Custom Address
{
"po_number": "PO-2024-001",
"items": [
{
"sku": "SKU123",
"qty": 10
}
],
"firstname": "John",
"lastname": "Doe",
"street": "123 Main Street",
"city": "Beijing",
"postcode": "100000",
"country_id": "CN",
"telephone": "+8613812345678"
}
Response:
{
"code": 200,
"msg": "success",
"order_number": "000000664",
"order_status": "po_submitted",
"total": 108.0
}
Example: Create Order Without PO Number
{
"items": [
{
"sku": "SKU123",
"qty": 5
}
]
}
Response:
{
"code": 200,
"msg": "success",
"order_number": "000000663",
"order_status": "waiting_confirmation",
"total": 54.0
}
Get Order Details
GET /rest/V1/external/orders/{order_number}
Retrieves detailed information about a specific order.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| order_number | string | Yes | The order number (increment ID) to lookup |
Response
{
"code": 200,
"msg": "success",
"response_data": {
"order_number": "string", // Order increment ID
"order_status": "string", // Order status (e.g., "po_submitted", "waiting_confirmation")
"total": "float", // Order total amount
"po_number": "string", // PO number (customer provided or system generated)
"currency": "string", // Currency code (e.g., "CNY")
"items": [ // Ordered items
{
"sku": "string", // Product SKU
"qty": "integer", // Quantity ordered
"price": "float" // Price per item
}
],
"created_at": "string" // ISO 8601 datetime in UTC+8
}
}
Cancel Order
POST /rest/V1/external/orders/{orderNum}/cancel
Cancels an existing order. Orders can only be canceled if they are in po_submitted or waiting_confirmation status.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| orderNum | string | Yes | The increment ID of the order to cancel |
Request Body
No request body required. The order number is provided in the path parameter.
Response
{
"code": 200,
"msg": "success",
"order_number": "string", // Order increment ID
"order_status": "canceled" // Updated order status
}
List Orders
GET /rest/V1/external/orders
Retrieves a paginated list of orders with optional filtering.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| page_size | integer | No | Items per page (default: 20, max: 100) |
| status | string | No | Filter by order status |
| start_date | string | No | Filter by start date (ISO 8601 format) |
| end_date | string | No | Filter by end date (ISO 8601 format) |
Response
{
"code": 200,
"msg": "success",
"response_data": {
"total_count": "integer", // Total number of orders matching the filters
"page_size": "integer", // Number of items per page
"current_page": "integer", // Current page number
"total_pages": "integer", // Total number of pages
"orders": [ // Array of orders
{
"order_number": "string", // Order increment ID
"order_status": "string", // Order status
"total": "float", // Order total amount
"po_number": "string", // PO number
"currency": "string", // Currency code
"created_at": "string", // ISO 8601 datetime in UTC+8
"items_count": "integer" // Number of items in the order
}
]
}
}
Get Order Logistics
GET /rest/V1/external/orders/{orderId}/logistics
Retrieves logistics and tracking information for a specific order.
Note: Currently returns example data for testing purposes. Real logistics data integration will be available after system integration.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| orderId | string | Yes | The order ID to query logistics for |
Response
{
"order_id": "string", // Order ID
"logistic_info_list": [ // Delivery carrier information
{
"order_id": "string", // Order ID
"delivery_carrier": "string", // Delivery carrier name
"delivery_order_id": "string" // Delivery order/tracking number
}
],
"track_info_list": [ // Tracking history
{
"track_msg_time": "string", // Timestamp of tracking update (e.g., "2020-07-23 20:15:07")
"track_content": "string", // Tracking message content
"track_operator": "string", // Operator who made the update
"lat": "string", // Latitude coordinate for map display
"lng": "string" // Longitude coordinate for map display
}
]
}
Response Example
{
"order_id": "123006233275",
"logistic_info_list": [
{
"order_id": "123006233275",
"delivery_carrier": "快递",
"delivery_order_id": "PKG0021479414451"
}
],
"track_info_list": [
{
"track_msg_time": "2020-07-23 20:15:07",
"track_content": "您的订单已经进入仓库准备出库",
"track_operator": "系统",
"lat": "39.9042",
"lng": "116.4074"
},
{
"track_msg_time": "2020-07-23 21:30:15",
"track_content": "您的订单已经从仓库发出,正在运往分拣中心",
"track_operator": "系统",
"lat": "39.9042",
"lng": "116.4074"
},
{
"track_msg_time": "2020-07-24 08:45:22",
"track_content": "您的订单已到达分拣中心",
"track_operator": "系统",
"lat": "32.0603",
"lng": "118.7969"
},
{
"track_msg_time": "2020-07-24 09:20:33",
"track_content": "您的订单正在派送中,快递员:张三,电话:138****1234",
"track_operator": "系统",
"lat": "31.9373",
"lng": "118.7047"
},
{
"track_msg_time": "2020-07-24 14:30:45",
"track_content": "您的订单已签收,签收人:本人",
"track_operator": "系统",
"lat": "31.9330",
"lng": "118.6933"
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| order_id | string | Order ID |
| logistic_info_list | array | List of delivery carrier information |
| logistic_info_list[].order_id | string | Order ID |
| logistic_info_list[].delivery_carrier | string | Delivery carrier name |
| logistic_info_list[].delivery_order_id | string | Tracking number |
| track_info_list | array | List of tracking status updates |
| track_info_list[].track_msg_time | string | Timestamp of the update |
| track_info_list[].track_content | string | Tracking message content |
| track_info_list[].track_operator | string | Operator who made the update |
| track_info_list[].lat | string | Latitude coordinate for map display |
| track_info_list[].lng | string | Longitude coordinate for map display |
logistic_info_list
The logistic_info_list contains carrier and tracking information for the order:
- Who is delivering? →
delivery_carrier - What’s the tracking number? →
delivery_order_id - Which order? →
order_id
Use cases:
-
External tracking - Use
delivery_order_idto track the package -
Display to customers - Show carrier name and tracking number
track_info_list
The track_info_list contains the delivery journey with status updates (time, location, status).
Example usage: Display delivery progress to customers:
- Warehouse → Shipped → Out for delivery → Delivered
Field Comparison
| Field | Purpose |
|---|---|
| logistic_info_list | Who & what - Carrier name + tracking number |
| track_info_list | When & where - Delivery journey/status updates |
Category Management API
Get Categories
GET /rest/V1/external/categories
Retrieves all categories in a hierarchical structure. The response includes categories starting from level 1, with their nested children categories.
Notes:
- Each category includes both English (
name_en) and Mongolian (name_mn) names - If a translation is not available, the field may contain an empty string or the original name
Response
{
"code": 200,
"msg": "success",
"response_data": [
{
"id": 28677,
"level": 1,
"name_en": "Automotive",
"name_mn": "Автомашины хэрэгслийн бүтээгдэхүүн",
"children": [
{
"id": 28754,
"level": 2,
"name_en": "Beauty Cleansing",
"name_mn": "Гоо сайхны цэвэрлэгээний бүтээгдэхүүн",
"children": [
{
"id": 28773,
"level": 3,
"name_en": "Car Wash Bucket",
"name_mn": "洗车水桶",
"children": []
}
]
}
]
}
]
}
Each category object contains:
id: integer - The category IDname_en: string - The category name in Englishname_mn: string - The category name in Mongolianlevel: integer - The category’s level in the hierarchy (1 being the top level)children: array - Array of child categories, each following the same structure