开发者文档
从拿到密钥到完成第一次库存同步,最快 5 分钟。以下是完整接入路径与接口参考。
快速开始
接入流程分三步:创建密钥、安装 SDK、调用接口。不需要提交工单,也不需要人工审批。
- 登录后台,在「设置 → 开发者 → API 密钥」中创建 Access Key / Secret Key;
- 把密钥写入环境变量,不要硬编码进代码仓库;
- 调用
/v1/ping验证连通性,然后开始正式接入。
export XXSKU_KEY="sk_live_****************"
export XXSKU_SECRET="********************************"
curl https://api.xxsku.cn/v1/ping \
-H "Authorization: Bearer $XXSKU_KEY"
# → {"ok": true, "shop": "mianji-flagship", "quota": {"sku_used": 3204}}
密钥安全:Secret Key 仅在创建时完整显示一次。 生产环境建议使用临时凭证(STS Token),并遵循最小权限原则——只申请实际需要的 scope。
身份认证
所有请求通过 Authorization 头认证。支持两种方式:长期密钥(适合服务端)与临时 Token(适合前端或第三方代运营)。
| 请求头 | 是否必填 | 说明 |
|---|---|---|
| Authorization | 是 | 格式为 Bearer <api_key> |
| X-XXSKU-Shop | 否 | 多店铺账号下指定操作的店铺;缺省为默认店铺 |
| Idempotency-Key | 否 | 写操作幂等键。重复提交同一次请求不会产生重复数据 |
| Content-Type | 是 | 固定为 application/json |
商品与 SKU
商品以 SPU 为单位管理,每个 SPU 下有若干 SKU。规格维度在 SPU 层定义,SKU 记录具体组合与编码。
from xxsku import Client
client = Client(api_key="sk_live_****************")
spu = client.products.create(
title="男士休闲衬衫",
category_id="cate_10231",
specs=[
{"name": "颜色", "values": ["白色", "浅蓝", "藏青", "黑色"]},
{"name": "尺码", "values": ["M", "L", "XL"]},
],
# 不传 skus 时,服务端按 specs 的笛卡尔积自动生成 12 个 SKU
price_rule={"base": 19900, "step_up": {"XL": 1000}}, # 单位:分
sku_code_pattern="SKU-{seq:04d}",
)
print(spu["sku_count"]) # → 12
print(spu["skus"][0])
# → {"sku_code": "SKU-0001", "specs": {"颜色": "白色", "尺码": "M"}, "price": 19900}
库存与价格
库存支持「绝对值覆盖」与「增量增减」两种语义,通过 mode 字段区分。默认是绝对值覆盖。
result = client.skus.update_stock(
mode="delta", # absolute | delta
sync_channels=True, # 是否推送到已绑定的渠道
items=[
{"sku_code": "SKU-0001", "stock": -2}, # delta 模式下表示减 2
{"sku_code": "SKU-0002", "stock": 50},
],
)
print(result["updated"]) # → 2
print(result["synced"]) # → {"taobao": 2, "jd": 2}
批量改价
改价接口支持「按条件圈选」与「按 SKU 列表」两种入参。推荐先调用 /price/preview 预览差异,确认后再执行。
# 1. 预览:按标签圈选,整体降价 20%
preview = client.prices.preview(
filter={"tags": ["秋季上新"]},
adjust={"type": "percent", "value": -20},
floor_price=12900, # 价格下限保护,低于此值的项会被标出
)
print(preview["changes"]) # 逐条列出 原价 → 新价
print(preview["below_floor"]) # 触发下限保护的 SKU
# 2. 确认无误后执行
client.prices.apply(preview_id=preview["id"], sync_channels=True)
渠道同步
渠道绑定通过官方 OAuth 完成,API 只能查询状态与触发同步,不能代为授权。
channels = client.channels.list()
# → [{"code": "taobao", "status": "active", "pending": 0}, ...]
job = client.channels.sync(
channel="taobao",
scope="full", # full | incremental
product_ids=["spu_8871", "spu_8872"],
)
print(job["status"]) # → "queued"
Webhook
订阅事件后,平台会在事件发生时向你的回调地址推送 JSON。所有推送带 HMAC-SHA256 签名,务必校验。
| 事件名 | 触发时机 | 典型用途 |
|---|---|---|
| stock.changed | 任一渠道库存发生变动 | 同步到自建 ERP 或 WMS |
| sku.created | 新建 SKU 成功 | 生成条形码、打印价签 |
| sync.failed | 向某渠道同步失败 | 告警通知、人工介入 |
| stock.threshold | 库存低于安全阈值 | 触发补货流程或自动下架 |
import hmac, hashlib
def verify(raw_body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
# Flask 示例:注意必须用原始 body,不能先 json.loads 再序列化
@app.post("/xxsku/webhook")
def hook():
if not verify(request.get_data(), request.headers["X-XXSKU-Signature"], SECRET):
return "", 401
event = request.json
if event["type"] == "stock.changed":
handle_stock_change(event["data"])
return "", 204
重试策略:推送失败会按 1s / 10s / 1min / 10min / 1h 的间隔重试 5 次。 请保证回调接口幂等——同一条事件可能被投递多次。超过 5 次仍失败会触发告警并记录在后台。
接口清单
接口根地址为 https://api.xxsku.cn/v1。所有接口遵循统一响应结构。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /v1/products | 分页查询商品(SPU)列表 |
| POST | /v1/products | 创建商品,可自动生成规格矩阵 |
| PATCH | /v1/products/{id} | 更新商品基础信息 |
| GET | /v1/skus | 按商品、规格、库存状态筛选 SKU |
| PATCH | /v1/skus/stock | 批量更新库存(支持绝对值 / 增量) |
| POST | /v1/prices/preview | 批量改价预览,返回差异与风控提示 |
| POST | /v1/prices/apply | 执行已预览的改价任务 |
| GET | /v1/channels | 查询渠道绑定状态与待同步数量 |
| POST | /v1/channels/sync | 手动触发渠道同步任务 |
| DELETE | /v1/webhooks/{id} | 取消一个 Webhook 订阅 |
统一响应结构
{
"request_id": "req_9f31c7a20b",
"data": {
"id": "spu_8871",
"title": "男士休闲衬衫",
"sku_count": 12,
"channel_status": { "taobao": "synced", "jd": "pending" },
"created_at": "2026-09-11T10:24:03Z"
},
"meta": { "quota": { "sku_used": 3204, "sku_limit": 30000 } }
}
错误码
所有错误遵循 HTTP 状态码 + 业务错误码 双层语义。请按业务错误码分支处理,不要依赖状态码文案。
| 错误码 | HTTP | 含义 | 处理建议 |
|---|---|---|---|
| InvalidApiKey | 401 | 密钥无效或已被撤销 | 检查密钥是否正确、是否已被轮换 |
| SkuQuotaExceeded | 403 | SKU 配额不足 | 归档无效 SKU,或升级套餐 |
| DuplicateSkuCode | 409 | SKU 编码重复 | 更换编码,或改用服务端自动生成 |
| ChannelAuthExpired | 409 | 渠道授权已过期 | 引导商家重新完成 OAuth 授权 |
| BelowFloorPrice | 422 | 改价结果低于价格下限 | 调整下限设置,或排除相关 SKU |
| RateLimited | 429 | 请求频率超限 | 指数退避重试;或申请提高限额 |
| InternalError | 500 | 服务端异常 | 携带 request_id 提交工单,我们会优先排查 |
{
"request_id": "req_2c81adf903",
"error": {
"code": "BelowFloorPrice",
"message": "3 个 SKU 的改价结果低于价格下限 129.00",
"retryable": false,
"details": { "sku_codes": ["SKU-0007", "SKU-0011", "SKU-0012"] }
}
}
SDK 与限额
官方 SDK 覆盖 Python、Node.js 与 Java,封装了鉴权、幂等键、自动重试与分页遍历。
| 语言 | 安装方式 | 最低版本 |
|---|---|---|
| Python | pip install xxsku | Python 3.9+ |
| Node.js | npm i @xxsku/sdk | Node 18+ |
| Java | implementation 'cn.xxsku:sdk:2.x' | JDK 17+ |
| 套餐 | 读接口 | 写接口 | Webhook 频次 |
|---|---|---|---|
| 标准版 | 60 次 / 分钟 | 20 次 / 分钟 | 10 次 / 秒 |
| 专业版 | 300 次 / 分钟 | 100 次 / 分钟 | 50 次 / 秒 |
| 旗舰版 | 不限 | 不限 | 不限 |
技术支持:接口对接过程中遇到问题, 把 request_id 和请求示例发到 dev@xxsku.cn, 工程团队会在 1 个工作日内回复。旗舰版客户可使用专属技术支持群。