# Ozon Seller API 鉴权与基础 > 官方文档:https://docs.ozon.ru/api/seller/zh/#tag/Introduction --- ## 1. 鉴权方式 Ozon Seller API 使用 **API Key 鉴权**(非 OAuth),每个请求需在请求头携带: ```http 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-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 ```bash 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) ```python 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) ```json { "result": { /* 业务数据 */ } } ``` 部分接口直接返回数组或对象,不包裹 `result`。 ### 错误响应(4xx/5xx) ```json { "code": 400, "message": "INVALID_ARGUMENT", "details": [ { "typeUrl": "type.googleapis.com/ozon.ValidationError", "value": "..." } ] } ``` 或简化版: ```json { "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 后: 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 的角色与权限 ```http POST https://api-seller.ozon.ru/v1/roles ``` **请求体**:空 `{}` **响应**: ```json { "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,非官方,更新滞后) --- ## 12. 相关链接 - [官方文档(中文)](https://docs.ozon.ru/api/seller/zh/) - [官方文档(俄文)](https://docs.ozon.ru/api/seller/) - [卖家后台](https://seller.ozon.ru/) - [API 状态页](https://status.ozon.ru/)(维护公告)