Files
ozon-seller-kit/docs/ozon-seller-api/01-authentication.md
T

5.6 KiB
Raw Blame History

Ozon Seller API 鉴权与基础

官方文档:https://docs.ozon.ru/api/seller/zh/#tag/Introduction


1. 鉴权方式

Ozon Seller API 使用 API Key 鉴权(非 OAuth),每个请求需在请求头携带:

Client-Id: <你的 Client ID>
Api-Key: <你的 API Key>
Content-Type: application/json

获取凭证

  1. 登录 Ozon 卖家后台
  2. 进入「设置」→「Seller API」
  3. 点击「生成 API Key」
  4. 选择权限级别:
    • 只读Read):仅查询
    • 读写Read & Write):查询 + 创建/更新商品
    • 管理员Admin):所有权限
  5. 保存 Client-IdApi-KeyApi-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-IdApi-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 后:

  1. 解析响应头 Retry-After(秒数)
  2. 若无此头,使用指数退避:1s → 2s → 4s → 8s
  3. 最多重试 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-apiPyPI,非官方,更新滞后)

12. 相关链接