5.6 KiB
5.6 KiB
Ozon Seller API 鉴权与基础
1. 鉴权方式
Ozon Seller API 使用 API Key 鉴权(非 OAuth),每个请求需在请求头携带:
Client-Id: <你的 Client ID>
Api-Key: <你的 API Key>
Content-Type: application/json
获取凭证
- 登录 Ozon 卖家后台
- 进入「设置」→「Seller API」
- 点击「生成 API Key」
- 选择权限级别:
- 只读(Read):仅查询
- 读写(Read & Write):查询 + 创建/更新商品
- 管理员(Admin):所有权限
- 保存
Client-Id和Api-Key(Api-Key 仅显示一次)
安全约束
- ⚠️ Api-Key 等同密码:泄露后任何人可操作你的店铺
- 🔒 服务端存储:加密落库(AES-GCM),前端永不传输/回显明文
- 🔄 定期轮换:建议每 90 天更换一次
- 🚫 前端禁用:插件/studio 不得持有店铺凭证,只能持有用户 token
2. Base URL
https://api-seller.ozon.ru
所有接口路径都基于此 URL,例如:
POST https://api-seller.ozon.ru/v3/product/import
3. 请求示例
cURL
curl -X POST "https://api-seller.ozon.ru/v1/description-category/tree" \
-H "Client-Id: 123456" \
-H "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"language":"RU"}'
Python (httpx)
import httpx
headers = {
"Client-Id": "123456",
"Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"Content-Type": "application/json"
}
async with httpx.AsyncClient(timeout=30.0) as client:
resp = await client.post(
"https://api-seller.ozon.ru/v1/description-category/tree",
headers=headers,
json={"language": "RU"}
)
data = resp.json()
4. 通用响应结构
成功响应(200/201)
{
"result": { /* 业务数据 */ }
}
部分接口直接返回数组或对象,不包裹 result。
错误响应(4xx/5xx)
{
"code": 400,
"message": "INVALID_ARGUMENT",
"details": [
{
"typeUrl": "type.googleapis.com/ozon.ValidationError",
"value": "..."
}
]
}
或简化版:
{
"error": {
"code": "INVALID_PARAMETER",
"message": "offer_id is required"
}
}
5. 错误码
| HTTP 状态码 | 含义 | 常见原因 | 处理建议 |
|---|---|---|---|
| 400 | 参数错误 | 必填字段缺失 / 格式错误 / 枚举值非法 | 检查请求体字段,读 details 定位 |
| 401 | 未鉴权 | 请求头缺 Client-Id 或 Api-Key |
检查请求头 |
| 403 | 权限不足 | Api-Key 权限级别不够(如只读 key 调创建接口) | 重新生成读写权限 key |
| 404 | 资源不存在 | product_id / category_id 不存在 |
检查 ID 是否正确 |
| 409 | 资源冲突 | offer_id 重复 / 商品已存在 |
改用唯一 offer_id 或走更新接口 |
| 429 | 限流 | 请求频率超限 | 指数退避重试(1s → 2s → 4s) |
| 500 | 服务端错误 | Ozon 内部错误 | 重试 1-2 次,仍失败则联系支持 |
| 503 | 服务不可用 | 维护中 | 稍后重试 |
6. 限流规则
官方未公开明确的限流阈值,根据社区经验:
- 常规接口:~10 req/s
- 批量接口(如
/v3/product/list):~5 req/s - 同一 task_id 轮询:建议间隔 ≥5s
触发 429 后:
- 解析响应头
Retry-After(秒数) - 若无此头,使用指数退避:1s → 2s → 4s → 8s
- 最多重试 3 次
7. 超时建议
| 接口类型 | 超时时间 | 理由 |
|---|---|---|
| 查询类(类目/属性/商品列表) | 30s | 轻量请求 |
导入类(/v3/product/import) |
60-90s | 后端需校验 + 入库 |
轮询状态(/v1/product/import/info) |
30s | 单次轮询快,但需多次 |
| 图片上传 | 90s | 网络传输耗时 |
8. 测试凭证有效性
/v1/roles —— 获取当前 Key 的角色与权限
POST https://api-seller.ozon.ru/v1/roles
请求体:空 {}
响应:
{
"result": [
{
"role_name": "Seller",
"permissions": [
"read:products",
"write:products",
"read:categories",
...
]
}
]
}
用途:
- ✅ 验证凭证有效性(200 = 有效,401/403 = 无效)
- ✅ 查看权限范围(判断是否有
write:products) - ✅ 零业务副作用(不消耗额度,不修改数据)
V2 集成点:POST /api/shops/:id/test 调此接口作连通性校验。
9. 请求 ID 追踪
部分接口响应包含 request_id(如图生图、导入任务),用于:
- 问题排查:联系 Ozon 支持时提供此 ID
- 幂等重试:某些接口可根据
request_id避免重复创建
建议:每次请求在日志里记录 request_id(若有)与请求体摘要,便于回溯。
10. 环境
Ozon Seller API 仅生产环境,无测试沙箱。调试时需注意:
- ⚠️ 所有操作都在真实店铺
- 💡 建议用「测试商品」标识(如 offer_id 前缀
TEST-) - 🗑️ 测试后及时删除/归档测试商品
11. SDK 与工具
官方未提供 Python SDK,社区方案:
- 自封装
httpx客户端(V2 采用,见server/services/ozon_client.py) - 第三方库:
ozon-api(PyPI,非官方,更新滞后)