# KK 货源平台 · 开放 API 规范（AI 员工 / ERP 通用）

> 版本：2026-06-13 v5 · 主站：https://kk.h-sh.com  
> 人类入口：[AI员工一键接入](https://kk.h-sh.com/ai) · [开发者速查](https://kk.h-sh.com/developer) · [字段速查](/kk-open-api.md) · [HTML 文档](https://kk.h-sh.com/api/open/docs)

**读者**：Hermes、OpenClaw、Cursor Agent、ERP、爬虫等**供应商侧自动化程序**。  
**目标**：读本文档后，无需反复向商户确认字段含义，即可完成接入与商品维护。

---

## 0. 工作原则（必读）

1. **主动执行，少问用户** — 库存、上下架、列表查询直接调 API。
2. **唯一硬依赖** — 商户须提供 **API Key**（`kk_` 开头）。对话中已有 Key 时**禁止重复索要**。
3. **媒体必须显式上传** — 平台不会替你上传；图片用 `POST /open/upload-image`，主图视频用 `POST /open/upload-video`，再把 URL 写入 JSON。
4. **库存只走 SKU** — 通过 `skus[].stock` 维护；商品级 `stock` 为平台自动汇总，**开放 API 不提供直接修改商品 stock 的字段**。
5. **两个对外标识** — API 只用 `id`（路径参数）和 `art_no`（厂家款号）；平台内部前台编码不在开放 API 返回。
6. **出错自愈** — 401 换 Key；422 看字段；400 检查 JSON 层级。

---

## 1. 接入清单

```
□ 1. 获取 API Key（kk_ + 32位十六进制）
     路径：https://kk.h-sh.com/supplier/api-keys （需实名认证，明文仅显示一次）

□ 2. HTTP 配置
     Base URL: https://kk.h-sh.com/api
     Header:   X-API-Key: {Key}
     JSON:     Content-Type: application/json

□ 3. 自检
     GET /open/products?page=1&page_size=5
     → 返回 {"data":[...], "total": N} 即成功
```

---

## 2. 认证与错误码

| HTTP | 含义 | 处理 |
|------|------|------|
| 401 | Key 无效/吊销 | 请商户重新生成 Key |
| 403 | 未实名或无权操作他人商品 | 核对 Key 与 product_id |
| 404 | 商品不存在 | 先 GET 列表确认 id |
| 400 | 参数结构/业务错误 | 见 §3.1 层级约定 |
| 422 | 字段校验失败 | 查类目、标签长度、图片域名 |

**数据范围**：`GET/PATCH /open/products*` 仅操作 **本 Key 绑定的商户商品**（按 `merchant_id` 隔离）。全平台公开商品列表用 `GET /api/public/products`（无需 Key）。若 `total` 与公开接口相同，请核对是否误调了 `/api/public/products`。

---

## 3. API 端点

| 方法 | 路径 | 用途 |
|------|------|------|
| POST | `/open/upload-image` | 上传图片 → CDN URL |
| POST | `/open/upload-video` | 上传主图视频（mp4/mov/webm/m4v）→ CDN URL |
| POST | `/open/products` | 创建商品 + SKU |
| GET | `/open/products` | 本商户列表（`?category=` `?is_active=` `?page=` `?page_size=`） |
| GET | `/open/products/{id}` | 详情含全部 SKU |
| GET | `/open/categories` | 平台类目树（大类 + 子类 slug） |
| GET | `/open/merchant-categories` | 我的自定义分类列表（slug 供上传用） |
| POST | `/open/merchant-categories` | 创建自定义分类 |
| PATCH | `/open/merchant-categories/{id}` | 更新自定义分类（name/slug/sort_order） |
| DELETE | `/open/merchant-categories/{id}` | 删除自定义分类（软删，商品关联置空） |
| PATCH | `/open/products/{id}` | 改商品信息/上下架/货号/来源/自定义分类 |
| PATCH | `/open/products/{id}/skus` | 改 SKU 库存/价格/白底图 |
| POST | `/open/keys` | 生成新 Key |
| GET | `/open/docs` | HTML 速查 |

---

## 3.1 请求体层级约定（最重要，减少 400）

### POST `/open/products` — 创建

**根层级与 `product` 并列**，不可嵌错：

| 字段 | 所在层级 | 说明 |
|------|----------|------|
| `product` | 根 | 商品标量字段（含 `art_no`） |
| `main_images` | **根** | 主图 URL 数组，必填 ≥1 |
| `main_video_url` | **根** | 主图视频 URL，选填；先 `upload-video`，勿放入 `main_images` |
| `skus` | **根** | SKU 数组，选填 |
| `source` | **根** | 来源页 URL，选填 |
| `detail_images` | **根** | 详情图 URL 数组，选填（也可放 `product` 内） |
| `detail_content` | **根** | HTML 图文详情，选填 ≤5000 字（也可放 `product` 内） |

```json
{
  "product": {
    "name": "夏季童鞋",
    "category": "kids_shoes",
    "price": 89.0,
    "art_no": "厂家款号ABC",
    "merchant_category_slug": "xia-ji-xin-pin"
  },
  "main_images": ["https://cf.h-sh.com/kk_HSH/..."],
  "detail_content": "<p>图文详情</p>",
  "source": "https://www.example.com/item/123",
  "skus": [{"color": "黑色", "size": "32", "stock": 10, "white_image_url": "https://cf.h-sh.com/kk_HSH/..."}]
}
```

**禁止：**

- ❌ 把 `main_images` / `skus` / `source` 放进 `product` 内 → 400
- ❌ 把 `source` 与 `art_no` 拼成一个字符串，如 `"https://... | 款号"` → 平台会截断 ` |` 后内容，**货号应单独传 `product.art_no`**
- ❌ 自定义平台内部编码 → 平台自动生成，开放 API 不返回、不可传入

### PATCH `/open/products/{id}` — 更新

**扁平 JSON，无 `product` 包装**：

```json
{"name": "新名称", "price": 99, "art_no": "新货号", "source": "https://...", "merchant_category_slug": "xia-ji-xin-pin", "clear_merchant_category": false, "is_active": false}
```

清空自定义分类：`{"clear_merchant_category": true}`

更新图文详情（扁平 JSON）：

```json
{"detail_content": "<p>更新后的 HTML</p>", "detail_images": ["https://cf.h-sh.com/kk_HSH/..."]}
```

### 3.2 图文详情 `detail_content`（写入与自检）

| 项 | 说明 |
|----|------|
| 创建位置 | **根层级** `detail_content`（推荐）或 `product.detail_content`，**根优先** |
| 详情图 | **根层级** `detail_images` 或 `product.detail_images` |
| 长度 | HTML 正文 ≤ 5000 字 |
| HTML 包裹 | **须为块级 HTML**（如 `<p>…</p>`、`<div>…</div>`）；纯文本或仅 `<img>` 会在入库时**自动**拆段为 `<p>`，建议接入方直接提交 `<p>` 避免排版异常 |
| 读取 | `GET /open/products/{id}` 必含 `detail_content`（无内容时为 `""`） |
| 内部 API | 与公开 API 相同字段；`POST /internal/open/products` 同样支持根层级 |

**自检（创建后必做）：**

```bash
curl -s "https://kk.h-sh.com/api/open/products/{id}" -H "X-API-Key: $KEY" | jq '.detail_content'
```

若返回空字符串，检查：① JSON 是否把 `detail_content` 放在根层级；② 是否误用档口只读接口 `GET /api/merchant/...`（不返回详情 HTML）。

**勿混淆的接口：**

| 接口 | 能否上传/更新 detail_content |
|------|------------------------------|
| `POST/PATCH /api/open/products` | ✅ |
| `POST/PATCH /api/internal/open/products` | ✅ |
| `POST/PATCH /api/products`（商户后台 JWT） | ✅（2026-06-03 起创建亦支持） |
| `GET /api/merchant/{username}/products` | ❌ 公开档口列表，不含详情字段 |

### PATCH `/open/products/{id}/skus` — 更新 SKU

数组或 `{"items":[...]}` / `{"skus":[...]}`，每条必须含 `color` + `size` 作为定位键。

### 3.3 POST 创建响应（必读，勿反复确认）

创建成功返回：

```json
{
  "product": {
    "id": 12345,
    "art_no": "X2026-001",
    "main_video_url": "https://cf.h-sh.com/kk_HSH/2026-06-03/KYc_900.mp4",
    "source": "https://www.example.com/item/123",
    "main_images": ["..."],
    "detail_content": "...",
    ...
  },
  "skus": [
    {
      "id": 1001,
      "color": "黑色",
      "size": "38",
      "stock": 50,
      "price": null,
      "white_image_url": "https://cf.h-sh.com/kk_HSH/2026-06-03/KYc_2.jpg"
    }
  ],
  "status": "active"
}
```

| 字段 | 说明 |
|------|------|
| `product.id` | **后续所有 API 的唯一键** |
| `skus[]` | 与 `GET /open/products/{id}` 结构**完全一致**，含 `white_image_url`（未设置时为 `null`） |
| `main_video_url` | 在 `product` 对象内；temp 视频已迁入 `{date}/{code}_900.{mp4\|mov\|...}` |
| `status` | `active`（Key 开启 auto_approve）或 `pending_review` |

**接入方无需再问商户确认：** 创建时传的 `white_image_url` / `main_video_url` 是否存上 — 直接看 POST 响应或 `GET` 详情即可。

---

## 4. 商品数据模型

### 4.0 对外标识（开放 API 只暴露这两个）

| 字段 | 谁赋值 | 格式/示例 | 用途 |
|------|--------|-----------|------|
| `id` | 平台 | 整数，如 `12345` | **API 唯一键**：路径 `/open/products/{id}`、upload-image 的 `product_id` |
| `art_no` | 商户/API | 字符串，≤19 字 | 厂家款号/自定义货号，选填，可重复 |

- 创建成功后响应含 `product.id`，后续所有操作以此为准。
- `art_no` **不是**来源 URL；来源用根层级 `source`。

> 平台内部另有前台短编码（如 W0、K10，用于 kk.h-sh.com 商品页 URL），**开放 API 不返回**，对接无需关心。

### 4.1 货号 `art_no`

| 操作 | 字段位置 |
|------|----------|
| POST 创建 | `product.art_no` |
| PATCH 更新 | 根层级 `art_no` |
| GET 列表/详情 | 根层级 `art_no` |

### 4.2 来源页 `source`

| 操作 | 字段位置 | 入库字段 |
|------|----------|----------|
| POST 创建 | 根层级 `source` | `source_url` |
| PATCH 更新 | 根层级 `source` | `source_url` |
| GET 列表/详情 | 响应字段名 `source` | — |

**约定：**

- 必须是**纯 URL**（`http://` 或 `https://` 开头）。
- **禁止** `"URL | 货号"` 或 CSV 拼接；货号用 `art_no`。
- 若误传 `"https://xxx.html | 备注"`，平台入库时截断 ` |` 及之后内容。

### 4.3 库存 `stock`

| 层级 | 是否可写 | 说明 |
|------|----------|------|
| `skus[].stock` | ✅ | 唯一正确写入方式 |
| 商品 `stock`（GET 响应） | ❌ 只读 | = 所有 SKU stock 之和，PATCH skus 后自动重算 |

### 4.4 主图 vs SKU 白底图

| 类型 | 字段 | 用途 |
|------|------|------|
| 主图 | `main_images`（根） | 详情页轮播、列表缩略 |
| SKU 白底图 | `skus[].white_image_url` | 按颜色展示、选码、搜索向量 |
| 详情图 | `detail_images`（根或 product） | 详情图；前台零边距无圆角纵向拼接 |
| 详情 HTML | `detail_content`（根或 product） | 块级 HTML；纯文本自动包 `<p>`；GET 会返回 |

### 4.5 分类体系（最易混淆，必读）

平台有**两套互不影响**的分类，上传时须分别理解：

| 对比项 | 平台类目 `category` | 商户自定义分类 `merchant_category_slug` |
|--------|---------------------|----------------------------------------|
| **谁维护** | 平台统一 | 商户后台或开放 API 创建 |
| **字段名** | `product.category` | `product.merchant_category_slug`（创建）/ 根层级（PATCH） |
| **是否必填** | ✅ 必填 | 选填 |
| **典型值** | 平台 slug（如 `sandals` 子类或 `hats` 大类） | 如 `xia-ji-xin-pin`（商户自设 slug） |
| **作用** | 决定商品编码前缀 W/K/H/B（按所属大类）；全站类目筛选 | 仅在该商户主页显示 Tab（`?cat=slug`） |
| **创建前** | 先 `GET /open/categories` 查树；**有 subs 时传子类 slug** | 先 `POST /open/merchant-categories` 创建，或后台 `/supplier/categories`；上传前 `GET` 核对 slug |
| **传错后果** | 400/422（大类有子类时传大类 slug 会 422） | 400「slug 不存在」；不传则商品归入「全部」 |

**常见误区：**

- ❌ 把自定义分类名填进 `category` → 400
- ❌ 女鞋有子类时仍传 `women_shoes` → 422「须选子分类」
- ❌ 把 `women_shoes` 填进 `merchant_category_slug` → 400（除非商户恰好建了同名 slug）
- ✅ 平台类目决定「这是什么货」；自定义分类决定「在我档口怎么摆」

#### 平台类目 `category`（必填）

先调用 **`GET /open/categories`**，返回大类 + `subs` 子类列表：

```json
{
  "data": [
    {
      "slug": "women_shoes",
      "name": "女鞋",
      "requires_subcategory": true,
      "subs": [{"slug": "sandals", "name": "凉鞋"}, {"slug": "boots", "name": "靴子"}]
    },
    {
      "slug": "hats",
      "name": "帽子",
      "requires_subcategory": false,
      "subs": []
    }
  ]
}
```

**选用规则：**

| 情况 | `product.category` 传什么 |
|------|---------------------------|
| 大类 `subs` 为空 | 传**大类 slug**（如 `hats`） |
| 大类有 `subs` | 传**子类 slug**（如 `sandals`），**不可**传 `women_shoes` |

编码前缀 W/K/H/B 按**所属大类**计算（子类 `sandals` → 仍用 W 序列）。

常见大类（子类以接口返回为准）：

| 大类 slug | 名称 | 编码前缀 |
|-----------|------|----------|
| `women_shoes` | 女鞋 | W |
| `kids_shoes` | 童鞋 | K |
| `hats` | 帽 | H |
| `bags` | 包 | B |

#### 商户自定义分类 `merchant_category_slug`（选填）

**批处理推荐**：直接用开放 API 建分类，无需商户手动进后台。

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/open/merchant-categories` | 列表（含 `id`、`slug`、`product_count`） |
| POST | `/open/merchant-categories` | 创建 |
| PATCH | `/open/merchant-categories/{id}` | 更新 `name` / `slug` / `sort_order` |
| DELETE | `/open/merchant-categories/{id}` | 软删（该分类下商品 `merchant_category_slug` 置空） |

```bash
# 批跑前一次性建好 6 个 Tab 分类
curl -X POST "https://kk.h-sh.com/api/open/merchant-categories" \
  -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"name":"运动鞋","slug":"yun-dong-xie","sort_order":1}'
```

| 字段 | 说明 |
|------|------|
| `name` | 显示名（档口 Tab 文案） |
| `slug` | 小写唯一标识，上传时写 `merchant_category_slug` |
| `sort_order` | 排序，默认 0 |

限制：基础认证默认最多 9 个活跃分类（达上限 403）；`slug` 商户内唯一，已软删的 slug 可复活。

挂商品：

1. 创建商品：`product.merchant_category_slug: "yun-dong-xie"`
2. 查询已有：`GET /open/merchant-categories` → `{"data":[{"id":1,"slug":"...","name":"...","product_count":12}]}`
3. 更新商品分类：PATCH 根层级 `merchant_category_slug`；清空传 `clear_merchant_category: true`
4. 响应字段：`merchant_category_slug`（未分类时为 `null`）

亦可商户后台 → **商品分类**（`/supplier/categories`）手动创建，效果相同。

---

## 5. SKU 说明

### 5.1 唯一键

每个 `(color, size)` 组合 = 一条 SKU，**严格字符串相等**（`"38"` ≠ `"038"`）。

### 5.2 命名建议

| 字段 | 规范 | 示例 |
|------|------|------|
| color | 中文 2～4 字，全商品统一 | 黑色、米白 |
| size | 鞋码用字符串数字；帽包可用 均码 | `"37"`、`"均码"` |

### 5.3 白底图

| 场景 | 规则 |
|------|------|
| **创建时传入** | ✅ 推荐。在根层级 `skus[].white_image_url` 写入（须先 `upload-image` 得 KK CDN URL） |
| **公开 API** | 选填；不传则 `white_image_url` 为 `null`，可后续 PATCH 补图 |
| **内部 API** | 有 SKU 时**每个颜色至少一条**须带 `white_image_url`，否则 422 |
| **同颜色多尺码** | 通常共用 1 张白底图，各 SKU 可传相同 URL |
| **响应** | POST 创建、`GET` 详情、`PATCH /skus` 的 `updated_skus[]` **均含** `white_image_url` |

补图流程（仅当创建时未传）：`upload-image` → `PATCH /open/products/{id}/skus` 写 `white_image_url`。

### 5.4 PATCH SKU 行为

- 按 `(color, size)` 匹配：**存在则更新，不存在则新建**。
- 部分更新：只传要改的字段（如仅 `stock`）。

---

## 6. 图片上传

### 6.1 合法 URL 域名

- `https://cf.h-sh.com/kk_HSH/...`
- `https://kk.h-sh.com/kk_HSH/...`（含 `temp/` 暂存路径）

### 6.2 两种模式

| 场景 | product_id | 路径 | 说明 |
|------|------------|------|------|
| 创建商品前（图片） | 不传 | `temp/{merchant_id}/{uuid}.jpg` | POST /open/products 或 PATCH 时自动迁入 `{merchant_id}/products/{product_id}/{uuid}.jpg` |
| 创建商品前（视频） | 不传 | `temp/{merchant_id}/{uuid}.mp4` 等 | POST /open/products 时自动迁入 `{merchant_id}/products/{product_id}/main_video.{原扩展名}` |
| 已有商品单张追加 | 可传 | `{merchant_id}/products/{product_id}/{uuid}.jpg` | 每张新图 UUID 唯一，**不会**覆盖同店其他商品 |
| **Bulk / ERP 批量补图** | **禁止传** | 必须 temp | temp upload → POST/PATCH；**勿**用 product_id 模式 |

**存量商品**（2026-06-12 前创建）正式 URL 仍为 `{date}/{code}_{序号}.jpg`，PATCH 时继续有效。

```bash
# 创建前 / bulk 补图（推荐）
curl -X POST "https://kk.h-sh.com/api/open/upload-image" \
  -H "X-API-Key: $KEY" -F "file=@main.jpg"

# 已有商品单张追加（非 bulk）
curl -X POST "https://kk.h-sh.com/api/open/upload-image?product_id=12345" \
  -H "X-API-Key: $KEY" -F "file=@white.jpg"
# 返回路径示例：…/kk_HSH/42/products/12345/a1b2c3d4.jpg
```

### 6.3 主图视频

支持 `.mp4` / `.mov` / `.webm` / `.m4v`。

```bash
curl -X POST "https://kk.h-sh.com/api/open/upload-video" \
  -H "X-API-Key: $KEY" -F "file=@main.mp4"
```

| 步骤 | 说明 |
|------|------|
| 1. 上传 | `POST /open/upload-video`（创建前可不传 `product_id`，走 `temp/`） |
| 2. 写入 | 将返回的 `url` 写入根层级 `main_video_url`（**勿**放入 `main_images`） |
| 3. 创建/PATCH | 平台将 temp 视频复制到 `{merchant_id}/products/{product_id}/main_video.{原扩展名}` |
| 4. 响应 | `product.main_video_url` 返回 canonical 后的 CDN URL；无视频时为 `null` |

**禁止**把视频 URL 放进 `main_images`。

### 6.4 图片 URL 归属（批量接入必读）

自 2026-06-12 起，创建/更新商品时除校验 KK CDN 域名外，还会校验 **URL 归属**，防止并发 bulk 时把 A 货号的图写进 B 货号。

| 操作 | 允许的 URL | 拒绝示例 |
|------|------------|----------|
| **POST 创建** | 本商户 `temp/{merchant_id}/{uuid}.*`（upload-image 返回值） | 任意正式路径、其他商户 temp |
| **PATCH 更新** | 本商户 temp；或 **本商品** P2 正式路径 `{merchant_id}/products/{product_id}/…`；存量兼容 `{date}/{code}_*.jpg` | 把商品 A 的正式 URL 写进商品 B |
| **主图视频** | 同上（P2 正式为 `…/main_video.mp4` 等；存量为 `{code}_900.mp4`） | 跨商品引用 |

**400 示例：** `图片URL所属商品（店铺15/商品1001）与当前商品（店铺15/商品1002）不一致`

#### Bulk / ERP 并发建议

1. **每个货号独立 URL 列表** — 禁止多线程/多店共用 module 级 `urls[]` 或「最后一次 upload 返回值」
2. **upload 完立刻 POST/PATCH** — 单货号：`upload × N → 立刻写 main_images`，再处理下一货号
3. **多店并行时** — 店与店可并行，**单店内建议串行** upload+写库
4. **PATCH 保留旧图** — 可继续传本商品已有正式 URL（P2 或存量路径）；新图用 temp upload

#### upload-image?product_id=（单张追加，非 bulk）

- 直接写入 P2 正式路径 `{merchant_id}/products/{product_id}/{uuid}.jpg`（视频为 `main_video.{ext}`）
- 文件名 **UUID 唯一**，按店铺+商品隔离，不会跨店撞 OSS key
- Bulk 补图仍**必须** temp + POST/PATCH，不要依赖 product_id

---

## 7. 完整示例

```bash
curl -X POST "https://kk.h-sh.com/api/open/products" \
  -H "X-API-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product": {
      "name": "夏季一字带凉鞋",
      "category": "women_shoes",
      "price": 89.0,
      "art_no": "X2026-001",
      "description": "聚氨酯底",
      "brand": "自有品牌",
      "origin_place": "温州",
      "unit": "双",
      "min_order_qty": 2,
      "tags": ["夏季", "新款"]
    },
    "main_images": ["https://cf.h-sh.com/kk_HSH/..."],
    "source": "https://www.example.com/p/item123",
    "skus": [
      {"color":"黑色","size":"37","stock":10,"white_image_url":"https://cf.h-sh.com/kk_HSH/..."},
      {"color":"黑色","size":"38","stock":20,"white_image_url":"https://cf.h-sh.com/kk_HSH/..."}
    ]
  }'
```

**响应要点：**

```json
{
  "product": {
    "id": 12345,
    "art_no": "X2026-001",
    "source": "https://www.example.com/p/item123",
    "main_video_url": null,
    ...
  },
  "skus": [
    {"id": 1001, "color": "黑色", "size": "37", "stock": 10, "price": null, "white_image_url": "https://cf.h-sh.com/kk_HSH/..."},
    {"id": 1002, "color": "黑色", "size": "38", "stock": 20, "price": null, "white_image_url": "https://cf.h-sh.com/kk_HSH/..."}
  ],
  "status": "active"
}
```

`status`：`active`（Key 开启 auto_approve）或 `pending_review`（待审核）。

---

## 8. 字段限制速查

| 字段 | 位置 | 限制 |
|------|------|------|
| name | product | 1～200 字，必填 |
| category | product | 平台 slug，必填；先 `GET /open/categories`，有 subs 传子类 |
| price | product | > 0，必填 |
| art_no | product（创建）/ 根（PATCH） | ≤ 19 字，选填 |
| source | 根 | 合法 URL，≤ 500 字，选填 |
| description | product | ≤ 200 字 |
| main_video_url | 根（创建/PATCH） | 主图视频 CDN URL；先 upload-video，**勿**放入 main_images |
| detail_images | 根或 product | 详情图 URL；前台无圆角零间距拼接 |
| detail_content | 根或 product | 块级 HTML ≤5000 字；纯文本自动包 `<p>`；**GET 必返回** |
| tags | product | 每项 ≤ 4 汉字 |
| main_images | 根 | 必填 ≥ 1，须 KK CDN |
| skus[].color / size | 根 | 必填（每条 SKU） |
| skus[].stock | 根 | ≥ 0，默认 0 |
| white_image_url | skus[] | 须 KK CDN；**创建时可传**；公开 API 选填，内部 API 有 SKU 时每颜色必填 |

---

## 9. 日常维护

| 任务 | 操作 |
|------|------|
| 查列表 | `GET /open/products?page=1&page_size=40` 或 `?is_active=true` |
| 查详情含 SKU | `GET /open/products/{id}` |
| 下架 | `PATCH /open/products/{id}` `{"is_active":false}` |
| 改货号/来源 | `PATCH /open/products/{id}` `{"art_no":"...","source":"..."}` |
| 改库存 | `PATCH /open/products/{id}/skus` `[{"color":"黑","size":"38","stock":99}]` |
| 补/改白底图 | 创建时传 `skus[].white_image_url`，或 `upload-image` → PATCH skus |

---

## 10. AI 员工系统提示（可复制）

```
你是 KK 货源平台供应商运营 AI。规范：https://kk.h-sh.com/KK-openAi.md

接入：Base URL https://kk.h-sh.com/api，Header X-API-Key

创建商品 JSON 层级：
- product.{name,category,price,art_no,...}
- 根层级 main_images（必填）、main_video_url?（选填，先 upload-video）、skus、source?
- skus[] 含 color,size,stock,white_image_url?（白底图创建时可传，响应含 white_image_url）
- 禁止 main_images/skus/source/main_video_url 放入 product
- 禁止 "url | 货号" 拼接；货号用 product.art_no

标识符：id=API 唯一键，art_no=厂家款号（平台内部前台编码不在 API 返回）
库存：只写 skus[].stock，不写商品级 stock
主图视频：upload-video → 根层级 main_video_url；temp 视频创建后变为 {code}_900.mp4

流程：upload-image 不传 product_id（+ upload-video?）→ POST /open/products → 看 POST 响应或 GET 校验（无需反复问用户）

图片归属（2026-06-12）：
- POST 创建：仅本商户 temp URL
- PATCH：temp 或本商品 code 前缀正式 URL；跨商品 K2z0_1 等 → 400
- Bulk：每货号独立 URL 缓冲，upload 完立刻写库；禁止 upload-image?product_id=
- 单张追加：upload?product_id= 序号从 DB max+1 起算（重启不覆盖旧图）
```

---

## 11. 服务商代传

代上架**不走开放 API**。详见 [API Key 代持](https://kk.h-sh.com/help/api-key-delegation)。

---

## 12. 相关链接

- [AI员工一键接入](https://kk.h-sh.com/ai)
- [开发者页面](https://kk.h-sh.com/developer)
- [字段速查 kk-open-api.md](/kk-open-api.md)
- [HTML 文档](https://kk.h-sh.com/api/open/docs)

---

*KK 货源平台 · 以生产环境为准*
