商品库 API
商品、品牌、分类与信息模板的接口参数和调用示例。
快速接入
商品库 API 的服务地址为 https://open.musedam.cc/api/product。在此地址后添加接口路径,例如 /products。
- 获取 MuseDAM API Key。
- 请商品库管理员在「成员设置 → 添加成员」中,将该密钥添加为 API Key 协作者,并分配所需角色。
- 从服务端调用接口,在请求头中携带
Authorization: Bearer <key>。
权限按密钥所属团队和协作者当前角色校验,请求参数不能切换商品库。
新添加的协作者默认为 view_only。按需要选择角色:
| 角色 | 可执行的操作 |
|---|---|
view_only | 查看已发布商品。 |
usable | 查看、分享和下载已发布商品。 |
editable | 创建和编辑商品、访问草稿、发布及删除商品。 |
manage | 管理全部资源,包括品牌、分类、信息模板及活动记录。 |
每个角色包含上一级角色的权限。后续示例中的资源 ID 需替换为实际值。
将 your_api_key 替换为已授权的 API Key,查询商品列表:
curl --request GET 'https://open.musedam.cc/api/product/products?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
请求成功时,success 为 true,data 为商品列表,pagination 为分页信息。列表为空时,先确认商品库中是否有当前角色可见的商品;view_only 和 usable 只能查看已发布商品。
请求与响应
所有请求均携带 Authorization: Bearer <key>;JSON 请求使用 Content-Type: application/json。接口表中的路径均相对上述服务地址。
JSON 接口使用以下结构。下载和导出成功时直接返回文件。
| 返回内容 | 读取方式 |
|---|---|
| 操作成功 | success: true,从 data 读取结果;code、message 为 null。 |
| 操作失败 | success: false,data: null;按 HTTP 状态码和 code 处理,不依赖 message 的文案。 |
| 参数校验失败 | 若响应包含 details,可按 details[].field 和 details[].message 修正字段。 |
| 请求追踪 | 保存 requestId 或响应头 X-Request-Id,用于排查问题。 |
普通列表使用 page 和 pageSize,在响应顶层返回 pagination。其中 totalCount 为总条数,totalPages 为总页数:
| 参数 | 默认值 | 范围 |
|---|---|---|
page | 1 | 从 1 开始的整数。 |
pageSize | 20 | 正整数,超过 100 时按 100 处理。 |
{
"page": 1,
"pageSize": 20,
"totalCount": 42,
"totalPages": 3
}商品和素材可能在请求期间变为不可见,因此实际返回条数可能少于 pageSize,计数仍保留分页时的结果。单项资源不可见时返回 404。
需要持续同步商品时,请使用游标同步,不要依靠普通页码列表。筛选参数见具体接口;普通查询会忽略未知参数,JSON 请求体会拒绝未知字段。
字段格式
| 字段 | 使用方式 |
|---|---|
| 数值型资源 ID | 正整数,最大 2147483647。 |
| 模板、分组、字段、版本 ID | 字符串,原样保存,不假定为 UUID。 |
| 素材 ID | 使用素材查询返回的 id(FilePath ID),不能替换成 AssetObject ID 或商品关联 ID。 |
分类 iconAssetId | 使用分类图标的标识符(CategoryIconAsset)。 |
size | 十进制字符串或 null,避免大文件字节数丢失精度。 |
| 日期 | RFC 3339 字符串或 null;同步时间戳保留完整六位小数。 |
| 商品 SKU | API 字段名为 spu。 |
旧版或无法解析的商品媒体可能返回 id: null。有效的媒体引用不会被截断。预览和下载链接的使用方式见媒体链接。
并发更新
读取品牌、分类、模板或商品时保存强 ETag(包括引号),更新、状态变更或删除时可放入 If-Match。返回 412 precondition_failed 时重新读取并核对;省略时后一次写入覆盖前一次。分享、历史和下载记录不使用 ETag。
创建与下载重试
创建资源可使用 Idempotency-Key。键按团队、API Key 和操作区分,最长 255 个字符,不能为空白或含控制字符。24 小时内用相同键和输入重试;更改输入返回 409 idempotency_key_reused。资源创建重放首次非媒体结果,媒体按当前权限重建。下载重试只复用业务记录,仍重新鉴权并传输当前文件。
请求限制与失败处理
请求体最多 1 MiB。未知 JSON 字段被拒绝;普通查询忽略未知参数,历史和同步查询另有严格校验。
| 返回结果 | 处理方式 |
|---|---|
| 401 / 403 | 检查密钥、协作者角色及资源可见性。 |
| 404 | 资源不存在、已删除或不可访问,核对 ID。 |
422 validation_failed | 修正输入;若有 details,读取 field 和 message。 |
409 sku_in_use / name_in_use | 修改冲突的 SKU 或名称;软删除商品的 SKU 仍被占用。 |
409 mutation_response_unavailable | 变更已提交或重放,按 mutationOutcome 核对;不要盲目重新创建。 |
503 write_conflict | 变更已回滚,按 Retry-After: 1 等待后重试。 |
| 413 | 缩小请求体或下载数量/大小。 |
通过响应头 X-Request-Id 或 JSON 中的 requestId 排查请求。下载错误含 mutationOutcome 时,记录已经提交,重试沿用原幂等键。
品牌
Brand 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Integer | 资源 ID。正整数 ID,最大 2147483647。 |
| name | String | 名称。 |
| code | String | 编码。 |
| description | String | 说明。可为 null |
| website | String | 网站地址。可为 null |
| sortOrder | Integer | 排序值。 |
| isEnabled | Boolean | 是否启用。 |
| createdAt | String | RFC 3339 时间字符串;保留完整精度。 |
| updatedAt | String | RFC 3339 时间字符串;保留完整精度。 |
获取品牌列表
接口路径:/brands
请求方式:GET
接口描述:返回公开元数据,按 sortOrder 再按 id 排序。不包含原始 logo URL。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
响应参数: 200,data:List<Brand>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/brands?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": 10,
"name": "Example brand",
"code": "example-code",
"description": null,
"website": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}创建品牌
接口路径:/brands
请求方式:POST
接口描述:创建品牌;允许名称重复,code 由服务端生成。Logo 地址限制见下方参数表。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | BrandCreate | 是 | JSON 请求体:application/json |
BrandCreate参数说明:
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 是 | 校验前会去除首尾空白。最短 1 个字符;最长 128 个字符 |
| description | String | 否 | 最长 512 个字符;可为 null |
| logoUrl | String | 否 | null/空值表示清除。仅支持 HTTP(S),不得包含凭据,且须为允许列表中的 MuseDAM CDN 或已配置的存储主机;存储前会移除 query 和 fragment。不支持上传;读取时不会返回。最长 512 个字符;可为 null |
响应参数: 201,data:Brand。 字段说明
响应头:ETag
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/brands' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Example brand"
}'响应示例
{
"success": true,
"data": {
"id": 10,
"name": "Example brand",
"code": "example-code",
"description": null,
"website": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}获取品牌详情
接口路径:/brands/{id}
请求方式:GET
接口描述:返回指定品牌的公开元数据及当前强 ETag,不包含原始 logo URL。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
响应参数: 200,data:Brand。 字段说明
响应头:ETag
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/brands/10' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 10,
"name": "Example brand",
"code": "example-code",
"description": null,
"website": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}更新品牌
接口路径:/brands/{id}
请求方式:PATCH
接口描述:更新所提供的元数据字段;未提供的属性保持不变。不支持文件上传或通用素材替换。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | BrandPatch | 是 | JSON 请求体:application/json |
BrandPatch参数说明:
不接受未定义字段;至少提供字段数:1。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 否 | 校验前会去除首尾空白。最短 1 个字符;最长 128 个字符 |
| description | String | 否 | 最长 512 个字符;可为 null |
| logoUrl | String | 否 | null/空值表示清除。仅支持 HTTP(S),不得包含凭据,且须为允许列表中的 MuseDAM CDN 或已配置的存储主机;存储前会移除 query 和 fragment。不支持上传;读取时不会返回。最长 512 个字符;可为 null |
响应参数: 200,data:Brand。 字段说明
响应头:ETag
请求示例:
curl --request PATCH \
'https://open.musedam.cc/api/product/brands/10' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": "Updated by API"
}'响应示例
{
"success": true,
"data": {
"id": 10,
"name": "Example brand",
"code": "example-code",
"description": "Updated by API",
"website": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:05:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}删除品牌
接口路径:/brands/{id}
请求方式:DELETE
接口描述:仅可删除没有有效分类或商品的品牌,否则返回 409;绝不会级联删除商品。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
响应参数: 200,data:DeletedId。 返回 data.id,即已删除的资源 ID。
响应头:ETag
请求示例:
curl --request DELETE \ 'https://open.musedam.cc/api/product/brands/10' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 10
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}分类
分类树与删除
同级名称必须唯一,父分类必须属于同一品牌。分类最多 10 级,每个品牌最多 5000 个未删除节点。sortOrder 是从零开始的同级位置;创建或移动时省略则追加,同父级更新时省略则保持位置。改名或移动会更新后代路径。
创建时,只有商品库默认模板未绑定品牌或已绑定当前品牌,才添加直接模板绑定;否则仍创建成功,按祖先分类、品牌、商品库默认模板查找。删除会软删除整棵子树;其中有未删除商品时返回 409 category_has_products,不执行删除。
Category 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Integer | 资源 ID。正整数 ID,最大 2147483647。 |
| brandId | Integer | 品牌 ID。正整数 ID,最大 2147483647。 |
| parentId | Integer | 父分类 ID。正整数 ID,最大 2147483647。;可为 null |
| name | String | 名称。 |
| pathKey | String | 分类路径。 |
| description | String | 说明。可为 null |
| iconEmoji | String | 分类表情图标。可为 null |
| iconAssetId | Integer | 分类图标 ID。正整数 ID,最大 2147483647。;可为 null |
| sortOrder | Integer | 排序值。 |
| isEnabled | Boolean | 是否启用。 |
| createdAt | String | RFC 3339 时间字符串;保留完整精度。 |
| updatedAt | String | RFC 3339 时间字符串;保留完整精度。 |
获取分类列表
接口路径:/categories
请求方式:GET
接口描述:返回扁平的有效分类树,按 brandId、parentId、sortOrder 和 id 排序。可选按品牌筛选;不会隐式展开子树。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
| brandId | Integer | 否 | 查询参数。按本商品库内的品牌 ID 筛选。正整数 ID,最大 2147483647。 |
响应参数: 200,data:List<Category>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/categories?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": 20,
"brandId": 10,
"parentId": null,
"name": "Catalog",
"pathKey": "/Catalog",
"description": null,
"iconEmoji": null,
"iconAssetId": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}创建分类
接口路径:/categories
请求方式:POST
接口描述:在指定品牌下创建有效节点。父节点必须是同一品牌/商品库中的有效节点。最大深度为 10,每个品牌最多 5000 个有效节点。同级名称必须唯一。仅当商品库默认模板未绑定任何品牌或已绑定该品牌时,才会添加显式模板绑定;否则分类仍创建成功,不添加显式绑定,并保留依次查找祖先分类、品牌和商品库默认模板的解析顺序。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | CategoryCreate | 是 | JSON 请求体:application/json |
CategoryCreate参数说明:
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| brandId | Integer | 是 | 正整数 ID,最大 2147483647。 |
| name | String | 是 | 精确值,不去除首尾空白。必须包含非空白字符且不含斜杠;在有效同级节点中唯一。最短 1 个字符;最长 64 个字符;须匹配 ^(?=.*\S)[^/]+$ |
| parentId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| sortOrder | Integer | 否 | 同级插入索引,不得大于目标位置的同级节点数。省略时:创建/移动时追加到末尾,父节点不变时保持原位置。最小值:0;最大值:5,000 |
| description | String | 否 | 可为 null |
| iconEmoji | String | 否 | 最长 16 个字符;可为 null |
| iconAssetId | Integer | 否 | 同一商品库中现有的 CategoryIconAsset ID,而非 FilePath ID。正整数 ID,最大 2147483647。;可为 null |
| isEnabled | Boolean | 否 | — |
响应参数: 201,data:Category。 字段说明
响应头:ETag
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/categories' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Catalog",
"brandId": 10
}'响应示例
{
"success": true,
"data": {
"id": 20,
"brandId": 10,
"parentId": null,
"name": "Catalog",
"pathKey": "/Catalog",
"description": null,
"iconEmoji": null,
"iconAssetId": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}获取分类详情
接口路径:/categories/{id}
请求方式:GET
接口描述:返回指定未删除分类及当前强 ETag;分类不存在或不属于当前商品库时返回 404。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
响应参数: 200,data:Category。 字段说明
响应头:ETag
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/categories/20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 20,
"brandId": 10,
"parentId": null,
"name": "Catalog",
"pathKey": "/Catalog",
"description": null,
"iconEmoji": null,
"iconAssetId": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}更新分类
接口路径:/categories/{id}
请求方式:PATCH
接口描述:在其现有品牌内更新或移动节点;brandId 不可变更。会拒绝循环引用、超出深度/节点数限制以及无效的排序索引。以原子方式更新后代路径。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | CategoryPatch | 是 | JSON 请求体:application/json |
CategoryPatch参数说明:
不接受未定义字段;至少提供字段数:1。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 否 | 精确值,不去除首尾空白。必须包含非空白字符且不含斜杠;在有效同级节点中唯一。最短 1 个字符;最长 64 个字符;须匹配 ^(?=.*\S)[^/]+$ |
| parentId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| sortOrder | Integer | 否 | 同级插入索引,不得大于目标位置的同级节点数。省略时:创建/移动时追加到末尾,父节点不变时保持原位置。最小值:0;最大值:5,000 |
| description | String | 否 | 可为 null |
| iconEmoji | String | 否 | 最长 16 个字符;可为 null |
| iconAssetId | Integer | 否 | 同一商品库中现有的 CategoryIconAsset ID,而非 FilePath ID。正整数 ID,最大 2147483647。;可为 null |
| isEnabled | Boolean | 否 | — |
响应参数: 200,data:Category。 字段说明
响应头:ETag
请求示例:
curl --request PATCH \
'https://open.musedam.cc/api/product/categories/20' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": "Updated by API"
}'响应示例
{
"success": true,
"data": {
"id": 20,
"brandId": 10,
"parentId": null,
"name": "Catalog",
"pathKey": "/Catalog",
"description": "Updated by API",
"iconEmoji": null,
"iconAssetId": null,
"sortOrder": 0,
"isEnabled": true,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:05:00.000Z"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}删除分类
接口路径:/categories/{id}
请求方式:DELETE
接口描述:仅当没有有效商品引用任何后代分类时,才软删除整个分类子树。不会删除或降级商品。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
响应参数: 200,data:DeletedId。 返回 data.id,即已删除的资源 ID。
响应头:ETag
请求示例:
curl --request DELETE \ 'https://open.musedam.cc/api/product/categories/20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 20
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}信息模板
分组 groups
groups 包含 1–200 个分组,一个模板的字段总数最多为 200。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 现有分组必填,1–128 个字符,必须属于本模板;新分组不传。 |
name | string | 必填,1–128 个字符,去除首尾空白。 |
fields | array | 必填,分组中的字段,见下表。 |
现有分组保持原有顺序,新分组按提交顺序追加。分组不接受 sortOrder 或 isDefault。默认分组由服务器指定,不能删除。
字段 fields
新字段必须提供 key、name 和 type。更新现有字段时必须传 id。类型不变时,省略的属性保留原值,sortOrder 除外;改变 type 时,config 会按目标类型迁移,必要时须显式提供新配置。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 现有字段必填,1–128 个字符,必须属于当前分组;新字段不传。 |
key | string | 新字段必填,1–64 个字符,须为唯一的有效标识符;已有字段不能修改。 |
name | string | 新字段必填,1–128 个字符。 |
type | string | 新字段必填,支持的类型见下方配置表。 |
required | boolean | 可选;新字段默认为 false。 |
placeholder | string 或 null | 可选,最多 255 个字符;新字段默认为 null。 |
sortOrder | integer | 可选,同组内唯一的非负整数;省略时使用字段在数组中的位置。 |
config | object | 按字段类型填写,见下方配置表;新字段省略时使用 {},但仍须满足该类型的配置要求。 |
typeChangeConfirmed | boolean | 可选;允许但需要确认的类型变更须传 true。 |
创建时会自动加入名称、SKU 和主图三个受保护字段,因此最多可新增 197 个自定义字段。第一个分组的自定义字段排列在这三个字段之后,传入的 sortOrder(省略时为数组位置)会增加 3。替换定义时须保留这些字段的 id,以及类型、必填标记和配置。字段不能移到其他分组。
新字段只能是自定义字段,不能使用保留的系统 key。isSystemField 和 systemKey 不能用于创建或重新分配系统身份;更新时保留原值。未知的分组或字段属性会被拒绝。
字段配置 config
配置由字段的 type 决定。例如,文本字段使用 {},货币和选项字段需要额外配置。
| 字段类型 | config 配置 |
|---|---|
text、textarea、email、phone、url、color、date、dateRange | 使用 {},不接受其他配置。 |
number | 可选 unit,字符串。 |
currency | 必填 code、symbol(非空字符串)和 decimals(0–4 的整数)。 |
richtext | 必填 mode,取值为 html 或 delta。 |
select、radio、checkbox | 必填非空 options 数组。每项见下表,value 不得重复。 |
image、file | 可选 maxCount(大于等于 1 的整数)、maxSizeMB(大于 0 的数字)和 accept(字符串数组)。 |
每个 options 元素包含:
| 字段 | 类型 | 说明 |
|---|---|---|
value | string | 必填,非空,选项的唯一值。 |
label | string | 必填,非空,显示名称。 |
sortOrder | integer | 必填,非负整数。 |
archived | boolean | 可选,是否归档该选项。 |
系统字段的可用配置是 customPlaceholder(可选字符串,最多 255 个字符);品牌、分类系统字段不接受自定义选项。受保护系统字段的配置不能变更。
空配置和系统配置拒绝未知属性;其他配置及选项会移除未知属性。完整机器可读定义可下载 OpenAPI JSON。
返回的模板定义
模板详情的 groups 和商品的 templateDefinition.groups 均包含分组与字段。商品返回的是创建时固定的版本,后续模板修改或删除不会改变它;未绑定模板时,templateDefinition 可为 null。
分组固定返回 id、name、fields,以及以下只读属性:
| 字段 | 类型 | 说明 |
|---|---|---|
isDefault | boolean | 是否为默认分组。 |
sortOrder | integer | 分组顺序。 |
每个字段固定返回 id、key、name、type、required、placeholder、sortOrder、config,以及以下属性;不返回写入参数 typeChangeConfirmed。
| 字段 | 类型 | 说明 |
|---|---|---|
isSystemField | boolean | 是否为系统字段。 |
systemKey | string 或 null | 系统身份:name、sku、brand、category、description、mainImage;自定义字段为 null。 |
placeholder 可为 null。配置中的媒体引用会返回安全的预览信息,不包含存储路径或凭据。读取商品的固定模板定义不需要 templates:read 权限。
Template 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | String | 资源 ID。最短 1 个字符;最长 128 个字符 |
| name | String | 名称。 |
| description | String | 说明。可为 null |
| enabled | Boolean | 是否启用模板。 |
| isSystemDefault | Boolean | 是否为系统默认模板。 |
| isLibraryDefault | Boolean | 是否为商品库默认模板。 |
| createdAt | String | RFC 3339 时间字符串;保留完整精度。 |
| updatedAt | String | RFC 3339 时间字符串;保留完整精度。 |
| boundBrandIds | List<Integer> | 绑定的品牌 ID。每个元素:正整数 ID,最大 2147483647。 |
| boundCategoryIds | List<Integer> | 绑定的分类 ID。每个元素:正整数 ID,最大 2147483647。 |
| groups | List<VersionGroup> | 模板分组。嵌套字段:模板分组与字段 |
获取模板列表
接口路径:/product-info-templates
请求方式:GET
接口描述:返回有效模板的元数据、绑定以及有序的分组/字段,包括仅预览配置。按 createdAt 降序再按 id 排序。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
响应参数: 200,data:List<Template>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/product-info-templates?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": "template_example",
"name": "Example template",
"description": null,
"enabled": true,
"isSystemDefault": false,
"isLibraryDefault": false,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"boundBrandIds": [],
"boundCategoryIds": [],
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_name",
"key": "name",
"name": "商品名称",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 0,
"isSystemField": true,
"systemKey": "name",
"config": {}
},
{
"id": "field_sku",
"key": "sku",
"name": "SKU",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 1,
"isSystemField": true,
"systemKey": "sku",
"config": {}
},
{
"id": "field_main_image",
"key": "mainImage",
"name": "商品主图",
"type": "image",
"required": true,
"placeholder": null,
"sortOrder": 2,
"isSystemField": true,
"systemKey": "mainImage",
"config": {}
},
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 3,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}创建模板
接口路径:/product-info-templates
请求方式:POST
接口描述:创建模板及不可变版本。syncStrategy 可省略,目前仅支持 newOnly;最多 200 个字段,不会更改任何现有商品。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | TemplateCreate | 是 | JSON 请求体:application/json |
TemplateCreate参数说明:
name/description 会去除首尾空白。所有分组合计最多 200 个字段。绑定必须属于同一商品库,会替换所提供的绑定集合,并可将绑定从其他模板移过来。当所选品牌非空时,所选分类必须属于这些品牌。仅支持 newOnly;绝不批量重新固定现有商品的版本。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 是 | 最短 1 个字符;最长 30 个字符 |
| description | String | 否 | 最长 50 个字符;可为 null |
| enabled | Boolean | 否 | — |
| groups | List<TemplateGroupInput> | 是 | 最少 1 项;最多 200 项。嵌套字段:模板分组字段 |
| boundBrandIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 10,000 项 |
| boundCategoryIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 10,000 项 |
| isLibraryDefault | Boolean | 否 | — |
| syncStrategy | String | 否 | 允许值:newOnly;默认值:"newOnly" |
响应参数: 201,data:Template。 字段说明
响应头:ETag
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/product-info-templates' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Example template",
"groups": [
{
"name": "Details",
"fields": [
{
"key": "color",
"name": "Color",
"type": "text",
"config": {}
}
]
}
]
}'响应示例
{
"success": true,
"data": {
"id": "template_example",
"name": "Example template",
"description": null,
"enabled": true,
"isSystemDefault": false,
"isLibraryDefault": false,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"boundBrandIds": [],
"boundCategoryIds": [],
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_name",
"key": "name",
"name": "商品名称",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 0,
"isSystemField": true,
"systemKey": "name",
"config": {}
},
{
"id": "field_sku",
"key": "sku",
"name": "SKU",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 1,
"isSystemField": true,
"systemKey": "sku",
"config": {}
},
{
"id": "field_main_image",
"key": "mainImage",
"name": "商品主图",
"type": "image",
"required": true,
"placeholder": null,
"sortOrder": 2,
"isSystemField": true,
"systemKey": "mainImage",
"config": {}
},
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 3,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}获取模板详情
接口路径:/product-info-templates/{id}
请求方式:GET
接口描述:返回指定未删除模板的元数据、绑定及分组/字段,包括仅预览配置。分组和字段按 sortOrder、id 升序排列。响应包含当前强 ETag,涵盖有效字段、分组、绑定集合及默认模板标记。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | String | 是 | 路径参数。不透明的模板 ID;请勿假定其为 UUID 格式。最短 1 个字符;最长 128 个字符 |
响应参数: 200,data:Template。 字段说明
响应头:ETag
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/product-info-templates/template_example' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": "template_example",
"name": "Example template",
"description": null,
"enabled": true,
"isSystemDefault": false,
"isLibraryDefault": false,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"boundBrandIds": [],
"boundCategoryIds": [],
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_name",
"key": "name",
"name": "商品名称",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 0,
"isSystemField": true,
"systemKey": "name",
"config": {}
},
{
"id": "field_sku",
"key": "sku",
"name": "SKU",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 1,
"isSystemField": true,
"systemKey": "sku",
"config": {}
},
{
"id": "field_main_image",
"key": "mainImage",
"name": "商品主图",
"type": "image",
"required": true,
"placeholder": null,
"sortOrder": 2,
"isSystemField": true,
"systemKey": "mainImage",
"config": {}
},
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 3,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}更新模板
接口路径:/product-info-templates/{id}
请求方式:PATCH
接口描述:使用与浏览器端共享的批量操作。省略 groups 字段时保留原定义;提供 groups 时整体替换分组和字段。会校验稳定 ID 以及受保护的系统/默认字段。创建新的不可变版本,但不会迁移现有商品的固定版本或字段值;绑定/默认设置的变更会影响后续的模板解析。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | String | 是 | 路径参数。不透明的模板 ID;请勿假定其为 UUID 格式。最短 1 个字符;最长 128 个字符 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | TemplatePatch | 是 | JSON 请求体:application/json |
TemplatePatch参数说明:
省略 groups 字段时保留原定义;提供 groups 时整体替换,数组中省略的旧分组和字段会被删除,但受默认/系统字段保护规则约束。请保留需要继续使用的分组和字段 ID。每次成功写入都会创建新的不可变版本,包括仅更新元数据的情况。
不接受未定义字段;至少提供字段数:1。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 否 | 最短 1 个字符;最长 30 个字符 |
| description | String | 否 | 最长 50 个字符;可为 null |
| enabled | Boolean | 否 | — |
| groups | List<TemplateGroupInput> | 否 | 最少 1 项;最多 200 项。嵌套字段:模板分组字段 |
| boundBrandIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 10,000 项 |
| boundCategoryIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 10,000 项 |
| isLibraryDefault | Boolean | 否 | — |
| syncStrategy | String | 否 | 允许值:newOnly;默认值:"newOnly" |
响应参数: 200,data:Template。 字段说明
响应头:ETag
请求示例:
curl --request PATCH \
'https://open.musedam.cc/api/product/product-info-templates/template_example' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": "Updated by API"
}'响应示例
{
"success": true,
"data": {
"id": "template_example",
"name": "Example template",
"description": "Updated by API",
"enabled": true,
"isSystemDefault": false,
"isLibraryDefault": false,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:05:00.000Z",
"boundBrandIds": [],
"boundCategoryIds": [],
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_name",
"key": "name",
"name": "商品名称",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 0,
"isSystemField": true,
"systemKey": "name",
"config": {}
},
{
"id": "field_sku",
"key": "sku",
"name": "SKU",
"type": "text",
"required": true,
"placeholder": null,
"sortOrder": 1,
"isSystemField": true,
"systemKey": "sku",
"config": {}
},
{
"id": "field_main_image",
"key": "mainImage",
"name": "商品主图",
"type": "image",
"required": true,
"placeholder": null,
"sortOrder": 2,
"isSystemField": true,
"systemKey": "mainImage",
"config": {}
},
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 3,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}删除模板
接口路径:/product-info-templates/{id}
请求方式:DELETE
接口描述:软删除有效模板,同时保留现有商品所使用的不可变版本。删除当前商品库默认模板时,必须显式指定替代模板或 null;默认/系统保护规则仍然适用。会移除绑定,但不会改写现有商品的固定版本。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | String | 是 | 路径参数。不透明的模板 ID;请勿假定其为 UUID 格式。最短 1 个字符;最长 128 个字符 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | TemplateDelete | 否 | JSON 请求体:application/json |
TemplateDelete参数说明:
可选请求体。若删除的是当前商品库默认模板,则此属性必填:取值为同一商品库中另一个有效模板的 ID,或显式 null 以清除默认模板。历史版本对固定了该版本的商品仍然可用。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| replacementForLibraryDefault | String | 否 | 最短 1 个字符;最长 128 个字符;可为 null |
响应参数: 200,data:DeletedTemplateId。 返回 data.id,即已删除的资源 ID。
响应头:ETag
请求示例:
curl --request DELETE \
'https://open.musedam.cc/api/product/product-info-templates/template_example' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"replacementForLibraryDefault": null
}'响应示例
{
"success": true,
"data": {
"id": "template_example"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}商品
模板版本与自定义字段
商品创建时保存模板版本。读取 templateDefinition 解释 templateFields;后续模板变更或删除不影响这个版本,普通 PATCH 不能更换模板。templateFields 以固定版本中的字段 ID 为键,更新时浅合并;null 清空单个字段。
显式 templateId 优先;否则,有 categoryId 时依次查找分类、祖先分类、品牌和商品库默认模板。没有分类时只考虑商品库默认模板,即使传入了品牌。
| 字段类型 | 输入格式 |
|---|---|
number、currency | JSON 数字 |
dateRange | 起止日期字符串组成的有序数组 |
checkbox | 选项值数组 |
image、file | FilePath ID 数组,或 null |
richtext | HTML 模式为字符串;delta 模式为 { "ops": [...] } |
草稿可缺少必填值,但提交和合并后的字段仍须满足类型/选项规则;发布或编辑已发布商品会校验完整商品。一次写入的全部媒体引用合计最多 100 个,只接受本商品库现有的 FilePath ID。媒体列表省略时保留,[] 清空;未传 coverAssetId 时,首张 imageAssetIds 图片成为封面。
同步与检查点
- 首次使用
sync=true,省略updatedAfter;增量周期传入上次完成的syncedUntil。 - 按商品
id和updatedAt合并,保留较新版本。 - 使用
sync=true&cursor=...跟随nextCursor直到 null;即使data为空,也要继续。 - 完成后原样保存
syncedUntil,不要改用最后一条商品的时间。
游标绑定密钥、角色、商品库、筛选条件和页大小;续页时不要改变它们。更换授权或筛选条件要开始新周期;范围扩大时重新全量同步。检查点和同步 updatedAt 保留完整六位小数,不要用 JavaScript Date 截断精度。每周期读取当前状态的 [updatedAfter, syncedUntil),上界为首次请求时服务端时间减 30 秒;长事务仍可能影响完整性,不提供每次变更的事件流。
清理已删除或不可见的商品
同步不会返回删除事件。定期将本地商品 ID 交给可见性接口,not_visible 时移除本地副本。该接口不检查品牌、分类或搜索等业务筛选;若只维护筛选后的副本,须定期全量核对筛选结果,或同步全部可见商品后在本地筛选。
预览与下载链接
展示商品媒体时使用 previewUrl。需要原文件时,检查 downloadUrl,或使用下一节的下载接口;能预览不等于有下载权限。
| 链接 | 返回条件 | 服务签发链接的有效期上限 |
|---|---|---|
| 派生预览 | 具备相应查看权限 | 3600 秒 |
| 图片原图预览回退 | 仅适用于图片,view_only 也可能返回 | 300 秒 |
downloadUrl | 关联可解析且可见,usable 或更高角色,同时具备 products:read 和 products:download | 300 秒 |
所有服务签发链接还受 API key 的到期时间限制。链接过期后重新获取商品数据,不要将签名 URL 当作素材 ID 保存。
封面、图片和关联素材返回哪些字段?
cover 是一个媒体对象,无封面时为 null;images、relatedAssets 为媒体对象数组。自定义图片/文件值可为数组或 null,未填写的字段可能省略。
| 字段 | 类型 | 说明 |
|---|---|---|
id | 整数或 null | 素材查询返回的 ID(FilePath ID),不是 AssetObject ID 或商品素材关联 ID |
name、mimeType | 字符串或 null | 文件名、MIME 类型 |
size | 字符串或 null | 十进制字节数,如 "2048",不是 JSON 数字 |
width、height、duration | 数字或 null | 媒体尺寸和时长 |
previewUrl | URL 或 null | 用于展示的预览地址;不可用时为 null |
downloadUrl | URL 或 null,可省略 | 原文件地址;返回条件见上表 |
downloadUrlExpiresAt | 时间字符串或 null,可省略 | 下载地址的到期时间,RFC 3339 格式 |
链接缺失、旧版媒体和外部预览如何处理?
- 非图片素材只返回派生预览,原始 PDF、压缩包和文档不会作为预览回退。素材库素材查询和模板配置只包含预览。
- 缺少下载权限或关联无法解析时,会省略
downloadUrl和downloadUrlExpiresAt;已授权但原文件不可用时,这些值可能为 null。 - 已存储的外部 DAM 缩略图或预览,只对未设置过期时间的 API key 返回,并先排除已知原文件 URL。它们的有效期由第三方控制,不保证短有效期,也不保证校验提供方签名。
- API key 设置了
expiresAt时,过期时间无法验证的外部预览返回 null。查询参数中形似签名的值不能作为可信的过期依据。 - 服务签发的链接仍遵守上表限制;签名失败时不会返回原始存储 URL。
ProductSummary 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Integer | 资源 ID。正整数 ID,最大 2147483647。 |
| name | String | 名称。 |
| spu | String | 商品 SKU。可为 null |
| description | String | 说明。可为 null |
| status | String | 当前状态。允许值:draft、published |
| brandId | Integer | 品牌 ID。正整数 ID,最大 2147483647。;可为 null |
| categoryId | Integer | 分类 ID。正整数 ID,最大 2147483647。;可为 null |
| ownerUserId | Integer | 所有者用户 ID。正整数 ID,最大 2147483647。;可为 null |
| publishedAt | String | RFC 3339 时间字符串;保留完整精度。草稿时为 null。 |
| createdAt | String | RFC 3339 时间字符串;保留完整精度。 |
| updatedAt | String | RFC 3339 时间字符串;保留完整精度。 |
| draftReason | String | 商品处于草稿状态的原因。可为 null |
| templateId | String | 模板 ID。最短 1 个字符;最长 128 个字符;可为 null |
| templateVersionId | String | 固定的模板版本 ID。最短 1 个字符;最长 128 个字符;可为 null |
| templateFields | Object | 以稳定模板字段 ID 为键的字段值。 |
| cover | Object | 商品封面。不接受未定义字段;可为 null。嵌套字段:封面媒体字段 |
| images | List<PublicAsset> | 商品图片。嵌套字段:媒体字段 |
| relatedAssets | List<PublicAsset> | 相关素材。嵌套字段:媒体字段 |
ProductDetail 返回字段
其他字段与商品列表返回字段相同。
| 字段名 | 类型 | 描述 |
|---|---|---|
| templateDefinition | NullableTemplateDefinition | 固定版本的模板定义。嵌套字段:商品模板定义 |
获取或同步商品列表
接口路径:/products
请求方式:GET
接口描述:普通分页按 updatedAt/id 降序排序。sync=true 时按 (updatedAt,id) 升序排序,使用包含的下界和不包含的固定上界(PostgreSQL 时钟减 30 秒)。全量扫描时省略 updatedAfter;请持续跟随每个 nextCursor,即使 data 页为空。游标绑定 key/角色/商品库/筛选条件/pageSize/边界。仅在遍历完毕后原样保存 syncedUntil;按 id 和 updatedAt 进行重放/去重。持续时间超过 30 秒安全窗口的事务属于 v1 已接受的限制。见同步说明。view_only/usable 仅可见已发布商品。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| page | Integer | 否 | 页码,正整数,默认 1;sync=true 时不可用。 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
| search | String | 否 | 查询参数。去除首尾空白、不区分大小写的子串匹配:商品名称/spu,或素材库素材名称。 |
| brandId | Integer | 否 | 查询参数。按本商品库内的品牌 ID 筛选。正整数 ID,最大 2147483647。 |
| categoryId | Integer | 否 | 查询参数。按精确的分类 ID 筛选,不包含其后代分类。正整数 ID,最大 2147483647。 |
| status | String | 否 | 查询参数。请求的商品状态;不会扩大角色可见范围。允许值:draft、published |
| sync | String | 否 | 查询参数。true 表示使用有界的键集同步;false 表示普通分页。见同步说明。允许值:true、false;默认值:"false" |
| updatedAfter | String | 否 | 查询参数。仅在 sync=true 时使用。包含的下界;RFC3339 格式,使用 Z 或时区偏移,0..6 位小数,日历日期/偏移须有效。请将 syncedUntil 作为字符串保存并复用。全量扫描时省略。格式:date-time |
| cursor | String | 否 | 查询参数。不透明的续页令牌,仅在 sync=true 时使用。绑定 key、角色、商品库、边界、筛选条件和每页条数。续页时省略其他参数,或重复传入等价的值。重复的同步参数会被拒绝。最短 1 个字符;最长 8,192 个字符 |
响应参数: 200,data:List<ProductSummary>。 字段说明 分页字段见响应与分页。
SyncPage
| 字段名 | 类型 | 描述 |
|---|---|---|
| pageSize | Integer | 每页数量。最小值:1;最大值:100 |
| syncedUntil | String | PostgreSQL 时钟减 30 秒,在整个周期内固定。仅在 nextCursor 为 null 后原样保存此字符串。格式:date-time;须匹配 ^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{6}Z$ |
| nextCursor | String | 下一页游标,扫描结束后为 null。最长 8,192 个字符;可为 null |
| hasMore | Boolean | 是否还有下一页同步数据。 |
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/products?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": []
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}响应示例(同步):
{
"success": true,
"data": [
{
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.123456Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": []
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"pageSize": 20,
"syncedUntil": "2026-10-08T10:01:00.123456Z",
"nextCursor": null,
"hasMore": false
}
}响应示例(空页续传):
{
"success": true,
"data": [],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"pageSize": 20,
"syncedUntil": "2026-10-08T10:01:00.123456Z",
"nextCursor": "opaque-continuation-token",
"hasMore": true
}
}创建草稿商品
接口路径:/products
请求方式:POST
接口描述:仅创建草稿。创建时解析并固定一个模板版本;模板字段依据该不可变定义进行校验。可关联同一商品库中现有的 FilePath ID;不支持上传、远程导入或回写到提供方。幂等重放会保留原始标量结果/ETag,并且仅对在当前同一槽位中仍然有效的原始媒体按当前权限重新投影。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | ProductCreate | 是 | JSON 请求体:application/json |
ProductCreate参数说明:
始终创建草稿。显式指定的 templateId 必须是同一商品库中的有效模板,且优先使用。当 templateId 省略/为 null 且提供了非 null 的 categoryId 时,解析顺序为:分类或其祖先分类的绑定,然后是该分类所属品牌的绑定,最后是商品库默认模板。当 categoryId 省略或为 null 时,即使提供了 brandId,也仅考虑商品库默认模板。若未解析出任何模板,则商品没有模板。分类必须与最终品牌匹配;owner 必须是同一团队成员,默认为 null,而非 key 创建者。cover/images/related/自定义媒体合计最多 100 个引用。图片槽位要求使用图片;自定义媒体必须满足固定版本的数量/大小/类型限制。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 否 | 会去除首尾空白;草稿可省略或为空。最长 255 个字符 |
| spu | String | 否 | 会去除首尾空白;null/空白表示清除。在商品库有效商品中唯一。最长 64 个字符;可为 null |
| description | String | 否 | 可为 null |
| brandId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| categoryId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| ownerUserId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| templateId | String | 否 | 最短 1 个字符;最长 128 个字符;可为 null |
| templateFields | Object | 否 | 按稳定的自定义字段 ID 浅合并;null 清除单个字段。未知/系统 ID 会被拒绝。即使是草稿也会校验类型/选项。image/file 的值为 FilePath ID 数组或 null,而非 URL/对象快照。PATCH 依据固定版本进行校验,即使其有效模板已被删除。 |
| coverAssetId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| imageAssetIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 100 项 |
| relatedAssetIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 100 项 |
响应参数: 201,data:ProductDetail。 字段说明
响应头:ETag
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/products' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Example product",
"spu": "EXAMPLE-001",
"brandId": 10,
"categoryId": 20,
"coverAssetId": 30,
"imageAssetIds": [
30
]
}'响应示例
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": [],
"templateDefinition": {
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 0,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}获取商品及其固定版本定义
接口路径:/products/{id}
请求方式:GET
接口描述:返回可访问的有效商品及其固定的不可变模板定义,即使有效模板已变更或被删除。不需要 templates:read。每次响应都会对媒体预览/下载进行授权;下载需要 products:read 加 products:download,且角色为 usable 或更高。草稿对 view_only/usable 不可见。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
响应参数: 200,data:ProductDetail。 字段说明
响应头:ETag
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/products/40' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": [],
"templateDefinition": {
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 0,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}响应示例(无模板或媒体):
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": null,
"templateVersionId": null,
"templateFields": {},
"cover": null,
"images": [],
"relatedAssets": [],
"templateDefinition": null
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}响应示例(含授权下载):
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example",
"downloadUrl": "https://media.example.test/original?signature=example",
"downloadUrlExpiresAt": "2026-10-08T10:05:00.000Z"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": [],
"templateDefinition": {
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 0,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}部分更新商品
接口路径:/products/{id}
请求方式:PATCH
接口描述:合并标量/自定义字段,并替换所提交的媒体列表。使用不可变的固定版本定义,包括有效模板已被删除的情况。已发布商品还需要 products:publish 权限,并保持已发布状态;必须以原子方式通过对最终状态的完整校验。此处不接受切换状态/模板。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | ProductPatch | 是 | JSON 请求体:application/json |
ProductPatch参数说明:
省略的字段保持不变;显式 null 清除可为 null 的字段,[] 清除列表。templateFields 采用合并;媒体数组替换其所在槽位。若提供 imageAssetIds 但未提供 coverAssetId,则第一张图片成为封面。已发布商品需要 products:publish 权限并保持已发布状态,且须通过对最终状态的完整校验。templateId、templateVersionId 和 status 会被拒绝。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | String | 否 | 会去除首尾空白;草稿可省略或为空。最长 255 个字符 |
| spu | String | 否 | 会去除首尾空白;null/空白表示清除。在商品库有效商品中唯一。最长 64 个字符;可为 null |
| description | String | 否 | 可为 null |
| brandId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| categoryId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| ownerUserId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| templateFields | Object | 否 | 按稳定的自定义字段 ID 浅合并;null 清除单个字段。未知/系统 ID 会被拒绝。即使是草稿也会校验类型/选项。image/file 的值为 FilePath ID 数组或 null,而非 URL/对象快照。PATCH 依据固定版本进行校验,即使其有效模板已被删除。 |
| coverAssetId | Integer | 否 | 正整数 ID,最大 2147483647。;可为 null |
| imageAssetIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 100 项 |
| relatedAssetIds | List<Integer> | 否 | 每个元素:正整数 ID,最大 2147483647。;最多 100 项 |
响应参数: 200,data:ProductDetail。 字段说明
响应头:ETag
请求示例:
curl --request PATCH \
'https://open.musedam.cc/api/product/products/40' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": null,
"templateFields": {
"field_color": "Blue"
}
}'响应示例
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "draft",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": null,
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": [],
"templateDefinition": {
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 0,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}软删除商品
接口路径:/products/{id}
请求方式:DELETE
接口描述:软删除一个可见的有效商品。草稿需要 delete 权限;已发布商品需要 delete 和 publish 权限。历史模板版本保持不变。不与提供方同步。重复删除返回 404。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
响应参数: 200,data:DeletedId。 返回 data.id,即已删除的资源 ID。
响应头:ETag
请求示例:
curl --request DELETE \ 'https://open.musedam.cc/api/product/products/40' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 40
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}发布商品或将商品退回草稿
接口路径:/products/{id}/status
请求方式:PATCH
接口描述:始终同时需要 update 和 publish 权限。发布时会校验固定版本的所有必填/类型/选项/媒体规则;状态无效时返回 422 及字段详情,且不做任何更改。重复发布会保留 publishedAt,退回草稿会清除该值。不会启动审批流程。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| If-Match | String | 否 | 可选请求头;使用读取时的 ETag,详见并发更新。 |
| - | ProductStatus | 是 | JSON 请求体:application/json |
ProductStatus参数说明:
任一状态转换(包括状态相同的请求)都同时需要 products:update 和 products:publish。发布会校验固定版本的所有必填字段以及当前媒体;失败时为原子操作。publishedAt 在首次发布时设置,重复发布时保留,退回草稿时清除。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| status | String | 是 | 允许值:draft、published |
响应参数: 200,data:ProductDetail。 字段说明
响应头:ETag
请求示例:
curl --request PATCH \
'https://open.musedam.cc/api/product/products/40/status' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"status": "published"
}'响应示例
{
"success": true,
"data": {
"id": 40,
"name": "Example product",
"spu": "EXAMPLE-001",
"description": null,
"status": "published",
"brandId": 10,
"categoryId": 20,
"ownerUserId": null,
"publishedAt": "2026-10-08T10:00:00.000Z",
"createdAt": "2026-10-08T10:00:00.000Z",
"updatedAt": "2026-10-08T10:00:00.000Z",
"draftReason": null,
"templateId": "template_example",
"templateVersionId": "version_one",
"templateFields": {
"field_color": "Blue"
},
"cover": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"images": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"relatedAssets": [],
"templateDefinition": {
"groups": [
{
"id": "group_details",
"name": "Details",
"isDefault": true,
"sortOrder": 0,
"fields": [
{
"id": "field_color",
"key": "color",
"name": "Color",
"type": "text",
"required": false,
"placeholder": null,
"sortOrder": 0,
"isSystemField": false,
"systemKey": null,
"config": {}
}
]
}
]
}
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}核对已知商品 ID
接口路径:/products/visibility
请求方式:POST
接口描述:在当前 key 的可见性下检查最多 100 个已知 ID。保留顺序和重复项,接受空数组。not_visible 不区分已删除、不存在、属于其他商品库以及因角色而隐藏的条目。由于同步不提供删除墓碑记录,请定期调用以清理本地的过期条目。此读操作不支持 Idempotency-Key 或 ETag。
所需角色:所有协作者角色。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| - | VisibilityInput | 是 | JSON 请求体:application/json |
VisibilityInput参数说明:
0..100 个 ID。输出保留输入顺序和重复项;[] 返回 []。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| ids | List<Integer> | 是 | 每个元素:正整数 ID,最大 2147483647。;最多 100 项 |
响应参数: 200,data:List<Visibility>。
Visibility
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Integer | 资源 ID。正整数 ID,最大 2147483647。 |
| visibility | String | 所提交商品 ID 的可见性。允许值:visible、not_visible |
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/products/visibility' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"ids": [
40,
41
]
}'响应示例
{
"success": true,
"data": [
{
"id": 40,
"visibility": "visible"
},
{
"id": 41,
"visibility": "not_visible"
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}素材
LibraryAsset 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Integer | 资源 ID。正整数 ID,最大 2147483647。 |
| name | String | 名称。可为 null |
| mimeType | String | MIME 类型。可为 null |
| size | String | 十进制字节数字符串;绝不是 JSON 数字。须匹配 ^\d+$;可为 null |
| width | Number | 宽度。可为 null |
| height | Number | 高度。可为 null |
| duration | Number | 时长。可为 null |
| previewUrl | String | 预览地址。格式:uri;可为 null |
查找现有素材库素材
接口路径:/assets
请求方式:GET
接口描述:列出 key 所属商品库中有效的非目录 FilePath 素材,按 id 排序。需要在 editable/manage 角色下具有 products:create 或 products:update 权限,而非 products:read。仅返回预览,绝不返回原始文件下载字段。在商品写入中使用 FilePath id;上传不在 v1 范围内。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
| search | String | 否 | 查询参数。去除首尾空白、不区分大小写的子串匹配:商品名称/spu,或素材库素材名称。 |
| mimeType | String | 否 | 查询参数。去除首尾空白、不区分大小写的 MIME 前缀,例如 image/ 或 application/pdf。 |
响应参数: 200,data:List<LibraryAsset>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/assets?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}获取现有素材库素材详情
接口路径:/assets/{id}
请求方式:GET
接口描述:返回同一商品库中有效的 FilePath 及仅预览的媒体元数据。与列表接口使用相同的 create 或 update 权限门槛。返回不透明的强 ETag,该 ETag 基于 FilePath 和关联 AssetObject 的标识以及所维护的更新时间戳;临时签名的变化不会改变此标签。
所需角色:editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
响应参数: 200,data:LibraryAsset。 字段说明
响应头:ETag
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/assets/30' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": {
"id": 30,
"name": "cover.jpg",
"mimeType": "image/jpeg",
"size": "9007199254740993",
"width": 1200,
"height": 900,
"duration": null,
"previewUrl": "https://media.example.test/preview?signature=example"
},
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}分享
记录中的商品快照有哪些字段?
分享和下载记录的 products 数组保留操作发生时的商品信息,不随商品后续修改更新。
| 字段 | 类型 | 说明 |
|---|---|---|
id | 正整数 | 商品 ID |
name | 字符串 | 当时的商品名称 |
spu | 字符串或 null | 当时的 SKU |
查询团队分享记录
接口路径:/product-shares
请求方式:GET
接口描述:按 createdAt 和 id 倒序列出当前团队所有浏览器操作者及 API key 的记录。可选 productId 返回完整的匹配操作;省略则查询全团队。仅接受 productId、page 和 pageSize,未知或重复参数返回 422。不会隐式限制为当前 API key 或创建者的记录。需要 manage 和 products:history,无需 products:read。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| productId | Integer | 否 | 查询参数。按一个商品 ID 筛选记录,仍返回包含其他商品和文件的完整操作。省略时查询当前团队全部记录。正整数 ID,最大 2147483647。 |
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
响应参数: 200,data:List<ProductShare>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/product-shares?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
创建商品分享
接口路径:/product-shares
请求方式:POST
接口描述:为固定的已发布商品集合创建有效期为 7/30/90 天或永久的分享。accessCode 可选且必须为四位数字。allowDownload 另需 products:download。访问者无需登录或 API key;未发布/已删除商品会从实时分享中隐藏。创建 key 的变化不会撤销独立的团队分享。可选的 24 小时幂等机制复用同一分享。
所需角色:usable、editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | ProductShareCreate | 是 | JSON 请求体:application/json |
ProductShareCreate参数说明:
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| productIds | List<Integer> | 是 | 最少 1 项;最多 100 项;每个 ID 为正整数,最大 2147483647。 |
| expiresInDays | Integer | 是 | 可为 null;允许值:7、30、90、null |
| accessCode | String | 否 | 须匹配 ^[0-9]{4}$ |
| allowDownload | Boolean | 是 | — |
响应参数: 201,data:ProductShare。 字段说明
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/product-shares' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"productIds": [
40
],
"expiresInDays": 7,
"allowDownload": false
}'撤销商品分享
接口路径:/product-shares/{id}
请求方式:DELETE
接口描述:撤销当前团队任意分享。需要 manage 和 products:share,无需 products:read。重复撤销返回原 revokedAt。未知或其他团队的 ID 返回 404。不使用 ETag 或 If-Match。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | String | 是 | 路径参数。不透明的分享标识符。最短 1 个字符;最长 128 个字符 |
响应参数: 200,data:RevokedProductShare。
RevokedProductShare
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | String | 资源 ID。 |
| revokedAt | String | 撤销时间。格式:date-time |
请求示例:
curl --request DELETE \ 'https://open.musedam.cc/api/product/product-shares/share-example' \ --header 'Authorization: Bearer your_api_key'
下载
选择文件、导出与记录
先查询商品下载候选,将返回的 key 放入 assetKeys,或 URL 编码后用作单文件路径参数 assetKey;它不是 FilePath ID。原文件下载仅一个文件时返回该文件,多个文件时返回 ZIP。每次选择 1–100 个商品、最多 200 个文件、合计不超过 500 MiB。
导出使用 kind: "export",格式为 xlsx(默认)、csv 或 json,不能传 assetKeys。includeAssetUrls 默认 true,导出的链接仍需要 Bearer 请求头;给免登录访客使用时应创建分享。locale 只影响系统标签和状态。
附件响应头 X-Download-Record-Id 是业务记录 ID。requested 仅表示请求已接受,不表示传输或本地保存完成。历史包含团队浏览器操作及其他 API Key 的操作;普通读取、预览和直接访问存储下载 URL 不计入历史。
下载记录中的文件快照有哪些字段?
下载记录的 files 数组保留首次接受操作时的文件信息。
| 字段 | 类型 | 说明 |
|---|---|---|
id | 字符串 | 文件快照标识 |
productId | 正整数 | 所属商品 ID |
name | 字符串 | 当时的文件名 |
ProductDownloadRecord 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | String | 资源 ID。 |
| kind | String | 操作类型。允许值:product_export、asset_download |
| status | String | 当前状态。允许值:requested、failed |
| actorType | String | 操作者类型。允许值:member、external、api_key |
| actorId | Integer | 操作者 ID。可为 null |
| apiKeyId | String | API key ID。可为 null |
| actorName | String | 操作者名称。 |
| shareId | String | 分享 ID。可为 null |
| products | List<ProductLabelSnapshot> | 商品快照。嵌套字段:商品快照字段 |
| files | List<FileLabelSnapshot> | 文件快照。嵌套字段:文件快照字段 |
| createdAt | String | 创建时间。格式:date-time |
ProductDownloadCandidate 返回字段
| 字段名 | 类型 | 描述 |
|---|---|---|
| key | String | 下载选择标识。 |
| name | String | 名称。 |
| productId | Integer | 商品 ID。正整数 ID,最大 2147483647。 |
| productName | String | 商品名称。 |
| category | String | 媒体类别。允许值:main、related、field |
| mimeType | String | MIME 类型。可为 null |
| size | String | 文件字节数,以十进制字符串表示。可为 null;须匹配 ^[0-9]+$ |
| downloadable | Boolean | 当前是否可下载此文件。 |
查询团队下载记录
接口路径:/product-downloads
请求方式:GET
接口描述:按 createdAt 和 id 倒序列出当前团队所有浏览器操作者及 API key 的记录。可选 productId 返回完整的匹配操作;省略则查询全团队。仅接受 productId、page 和 pageSize,未知或重复参数返回 422。不会隐式限制为当前 API key 或创建者的记录。需要 manage 和 products:history,无需 products:read。
所需角色:manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| productId | Integer | 否 | 查询参数。按一个商品 ID 筛选记录,仍返回包含其他商品和文件的完整操作。省略时查询当前团队全部记录。正整数 ID,最大 2147483647。 |
| page | Integer | 否 | 页码,正整数,默认 1 |
| pageSize | Integer | 否 | 每页条数,正整数,默认 20,上限 100。 |
响应参数: 200,data:List<ProductDownloadRecord>。 字段说明 分页字段见响应与分页。
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/product-downloads?page=1&pageSize=20' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"id": "download-example",
"kind": "product_export",
"status": "requested",
"actorType": "api_key",
"actorId": null,
"apiKeyId": "integration-key-id",
"actorName": "Catalog integration",
"shareId": null,
"products": [
{
"id": 40,
"name": "Example product",
"spu": "SKU-40"
}
],
"files": [
{
"id": "export:xlsx",
"productId": 40,
"name": "products.xlsx"
}
],
"createdAt": "2026-10-09T10:00:00.000Z"
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111",
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 1,
"totalPages": 1
}
}下载原文件或导出商品
接口路径:/product-downloads
请求方式:POST
接口描述:返回一个原文件、所选原文件的 ZIP,或 XLSX/CSV/JSON 业务表格导出。需要 usable 及以上角色的当前读取和下载权限;usable 只能访问已发布商品。已接受的操作在交付前记入记录。导出链接默认指向需认证的单文件 GET URL;每次接受的提取有自己的业务记录。可选 Idempotency-Key 在 24 小时内保留一条记录,每次重试仍重新鉴权并传输当前内容。商品读取、预览和旧存储 downloadUrl 的访问不会由此操作记入记录。
所需角色:usable、editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
| - | ProductDownloadCreate | 是 | JSON 请求体:application/json |
ProductDownloadCreate参数说明:
assets 省略 assetKeys 时选择全部原文件,否则仅选择提供的当前 key。export 不接受 assetKeys,并生成本地化业务表格。format、includeAssetUrls 和 locale 仅影响导出;素材下载接受这些选项但不据此改变交付内容。导出默认包含需要 Bearer 认证的链接,绝不包含 API key 密钥。locale 影响系统标签和状态,不改变用户自定义标签或内容。
不接受未定义字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| kind | String | 是 | 允许值:assets、export |
| productIds | List<Integer> | 是 | 最少 1 项;最多 100 项;每个 ID 为正整数,最大 2147483647。 |
| assetKeys | List<String> | 否 | 每个元素:最短 1 个字符;最长 256 个字符;最少 1 项;最多 200 项 |
| format | String | 否 | 允许值:xlsx、csv、json;默认值:"xlsx" |
| includeAssetUrls | Boolean | 否 | 默认值:true |
| locale | String | 否 | 允许值:zh-CN、en-US、zh-TW、ja-JP、ko-KR、pt-BR、ru-RU、id-ID、fr-FR、it-IT、pl-PL、vi-VN、tr-TR、th-TH、de-DE、es-ES、hi-IN;默认值:"zh-CN" |
响应参数: 200。成功返回附件,响应体为文件字节;JSON 仅用于交付前的错误。
响应头:Content-Disposition、X-Download-Record-Id、X-Idempotency-Replayed
请求示例:
curl --request POST \
'https://open.musedam.cc/api/product/product-downloads' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"kind": "export",
"productIds": [
40
],
"format": "xlsx",
"includeAssetUrls": true,
"locale": "zh-CN"
}' \
--output products.xlsx响应示例
HTTP/1.1 200 OK Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet Content-Disposition: attachment X-Download-Record-Id: <record-id>
响应体为文件字节。
查询商品下载候选素材
接口路径:/products/{id}/download-assets
请求方式:GET
接口描述:在读取和下载授权下返回当前候选素材的选择 key 和 downloadable 可用性。不产生业务下载记录,也不返回原文件或预览 URL。使用单文件路由或 POST product-downloads 获取文件字节。
所需角色:usable、editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
响应参数: 200,data:List<ProductDownloadCandidate>。 字段说明
请求示例:
curl --request GET \ 'https://open.musedam.cc/api/product/products/40/download-assets' \ --header 'Authorization: Bearer your_api_key'
响应示例
{
"success": true,
"data": [
{
"key": "p40:a2",
"name": "example.png",
"productId": 40,
"productName": "Example product",
"category": "main",
"mimeType": "image/png",
"size": "1024",
"downloadable": true
}
],
"code": null,
"message": null,
"requestId": "11111111-1111-4111-8111-111111111111"
}下载一个商品原文件
接口路径:/products/{id}/download-assets/{assetKey}
请求方式:GET
接口描述:通过编码后的候选 key 获取当前商品的一个原文件。需要 Bearer 请求头以及当前读取/下载授权;URL 不含 API key 密钥。交付前创建业务记录。可选的 24 小时幂等机制与 POST 下载使用不同作用域,复用记录时仍重新鉴权并传输当前字节。
所需角色:usable、editable 或 manage。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | Integer | 是 | 路径参数。正的有符号 32 位资源 ID。正整数 ID,最大 2147483647。 |
| assetKey | String | 是 | 路径参数。对商品下载候选列表返回的选择 key 进行 URL 编码;它不是 FilePath 或 AssetObject ID。最短 1 个字符;最长 256 个字符 |
| Idempotency-Key | String | 否 | 可选请求头;同一键和输入在 24 小时内重试,详见幂等重试。 |
响应参数: 200。成功返回附件,响应体为文件字节;JSON 仅用于交付前的错误。
响应头:Content-Disposition、X-Download-Record-Id、X-Idempotency-Replayed
请求示例:
示例使用下载候选 key p40:a2,URL 编码后为 p40%3Aa2。请使用您的下载候选列表返回的 key,它不是 FilePath 或 AssetObject ID。
curl --request GET \ 'https://open.musedam.cc/api/product/products/40/download-assets/p40%3Aa2' \ --header 'Authorization: Bearer your_api_key' \ --output product-asset.bin
响应示例
HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Disposition: attachment X-Download-Record-Id: <record-id>
响应体为文件字节。