Коды ошибок Ozon Seller API и обработка ошибок
Обзор
Ozon Seller API использует комбинированную систему кодов ошибок, включающую:
- HTTP статусы - основные коды состояния HTTP
- Числовые коды ошибок Ozon - специфические коды ошибок платформы
- Строковые коды ошибок - описательные коды для конкретных сценариев
HTTP Статус коды
400 Bad Request - Ошибка клиента
Python исключение: OzonAPIClientError
Описание: Неверный формат запроса, невалидные данные или параметры.
Частые причины:
- Неверный JSON формат в теле запроса
- Отсутствие обязательных полей
- Неверные значения параметров
- Нарушение валидации данных
Пример ответа:
{
"code": 400,
"message": "Bad Request",
"details": [
{
"field": "price",
"message": "Ставка не входит в диапазон допустимых значений"
}
]
}
403 Forbidden - Ошибка доступа
Python исключение: OzonAPIForbiddenError
Описание: Доступ запрещён или недостаточно прав.
Частые причины:
- Offer not signed - в личном кабинете продавца отсутствует подписанная офферта
- Обращение к методу, недоступному в текущей роли
- Недостаточно прав для выполнения операции
Пример ответа:
{
"code": 403,
"message": "Forbidden",
"details": "Offer not signed"
}
404 Not Found - Ресурс не найден
Python исключение: OzonAPINotFoundError
Описание: Запрашиваемый ресурс не существует или недоступен.
Частые причины:
- Invalid Api-Key - неверный API ключ
- Несуществующий endpoint URL
- Удалённый ресурс (товар, заказ и т.д.)
Пример ответа:
{
"code": 404,
"message": "Not Found",
"details": "Invalid Api-Key, please contact support"
}
409 Conflict - Конфликт
Python исключение: OzonAPIConflictError
Описание: Конфликт состояния ресурса с выполняемой операцией.
Частые причины:
- Попытка создать уже существующий ресурс
- Конфликт версий при обновлении
- Нарушение бизнес-логики
Пример ответа:
{
"code": 409,
"message": "Conflict",
"details": "Product already exists"
}
429 Too Many Requests - Превышение лимита запросов
Числовой код ошибки Ozon: 8
Описание: Превышен лимит частоты запросов.
Глобальные лимиты (на 19 мая 2025):
- 50 запросов в секунду на Client ID
Пер-Endpoint лимиты:
/v2/posting/fbo/product-list: 5 запросов в секунду/v3/posting/fbo/list: 5 запросов в секунду- Информационные запросы штрихкодов: 2 запроса в секунду
- Аналитика: различные лимиты по типу отчёта
Пример ответа:
{
"code": 8,
"message": "Too many requests",
"details": "Rate limit exceeded. Please retry later."
}
500 Internal Server Error - Ошибка сервера
Python исключение: OzonAPIServerError
Описание: Внутренняя ошибка сервера Ozon.
Частые причины:
- Временные сбои на стороне Ozon
- Ошибка в обработке запроса
- Проблемы с инфраструктурой
Рекомендация: Повторить запрос через некоторое время.
Пример ответа:
{
"code": 500,
"message": "Internal Server Error",
"details": "An unexpected error occurred. Please try again later."
}
Специфические коды ошибок Ozon
"Circle is open" - Блокировка метода
Описание: Система блокирует работу метода на несколько минут при выполнении слишком большого количества запросов.
Тип ошибки: Rate limiting / Request throttling
Причина: Превышение порога частоты запросов
Длительность блокировки: Несколько минут
Решение:
- Реализовать rate limiting на стороне клиента
- Использовать экспоненциальную задержку (exponential backoff)
- Оптимизировать код для уменьшения количества запросов
- Мониторить частоту запросов
Строковые коды ошибок
Ошибки API ключей (обновлено февраль 2025)
- INVALID_API_KEY - Неверный API ключ
- API_KEY_DISABLED - API ключ отключён
- API_KEY_EXPIRED - Срок действия API ключа истёк
Ошибки товаров и цен
- PRICE_IS_NOT_SENT - товар ещё не создан или находится на стадии обновления
- MP_DELIVERY_ONLY_3PL_ERROR - товар нельзя размещать на складе с методом доставки «Ozon»
- PRODUCT_NOT_FOUND - товар не найден
- INVALID_PRODUCT_ID - неверный ID товара
Ошибки атрибутов товаров
- MISSING_REQUIRED_ATTRIBUTE - отсутствует обязательный атрибут
- INVALID_ATTRIBUTE_VALUE - неверное значение атрибута
- TYPE_ID_REQUIRED - не указан тег type_id
Ошибки категорий
- INVALID_CATEGORY_ID - неверная категория
- CATEGORY_NOT_FOUND - категория не найдена
Структура ошибок в ответах API
Базовая структура ошибки
{
"code": <числовой_код>,
"message": "<текст_ошибки>",
"details": [<дополнительная_информация>]
}
Пример полной структуры ошибки
{
"code": 5,
"message": "Validation error",
"details": [
{
"code": "MISSING_REQUIRED_FIELD",
"field": "barcode",
"message": "Поле 'barcode' обязательно для заполнения"
},
{
"code": "INVALID_VALUE",
"field": "price",
"message": "Цена должна быть больше 0"
}
]
}
Структура ошибок в операциях с товарами
{
"product_id": 12345,
"offer_id": "PRODUCT-001",
"errors": [
"Ошибка 1: описание ошибки",
"Ошибка 2: описание ошибки"
]
}
Обработка ошибок
Python (с библиотекой ozon-api)
from ozon_api import OzonAPIError, OzonAPIClientError, OzonAPIForbiddenError
from ozon_api import OzonAPINotFoundError, OzonAPIConflictError, OzonAPIServerError
try:
response = await api.product_list(request)
except OzonAPIClientError as e:
print(f"Ошибка клиента (400): {e.message}")
except OzonAPIForbiddenError as e:
print(f"Ошибка доступа (403): {e.message}")
print("Проверьте подписанную офферт в личном кабинете")
except OzonAPINotFoundError as e:
print(f"Ресурс не найден (404): {e.message}")
print("Проверьте API ключ")
except OzonAPIConflictError as e:
print(f"Конфликт (409): {e.message}")
except OzonAPIServerError as e:
print(f"Ошибка сервера (500): {e.message}")
print("Повторите запрос позже")
except OzonAPIError as e:
print(f"Общая ошибка API: {e.message}")
Обработка rate limiting (429)
import asyncio
from asyncio import sleep
async def call_with_retry(api_call, max_retries=5):
for attempt in range(max_retries):
try:
return await api_call()
except Exception as e:
if e.code == 8 or e.status == 429: # Rate limit
wait_time = 2 ** attempt # Экспоненциальная задержка
print(f"Rate limit exceeded. Waiting {wait_time}s...")
await sleep(wait_time)
else:
raise e
raise Exception("Max retries exceeded")
Go (с библиотекой ozon-api-client)
package main
import (
"fmt"
"github.com/diphantxm/ozon-api-client/ozon"
)
func handleError(err error) {
if ozonErr, ok := err.(*ozon.Error); ok {
switch ozonErr.StatusCode {
case 400:
fmt.Printf("Client Error: %s\n", ozonErr.Message)
case 403:
fmt.Printf("Forbidden: %s\n", ozonErr.Message)
case 404:
fmt.Printf("Not Found: %s\n", ozonErr.Message)
case 429:
fmt.Printf("Rate Limit: %s\n", ozonErr.Message)
case 500:
fmt.Printf("Server Error: %s\n", ozonErr.Message)
default:
fmt.Printf("Unknown Error: %s\n", ozonErr.Message)
}
}
}
Стратегии обработки ошибок
1. Retry Logic (Повторные попытки)
Применимо для:
- HTTP 429 (Too Many Requests)
- HTTP 500 (Internal Server Error)
- Временных сетевых ошибок
Стратегия:
- Экспоненциальная задержка (exponential backoff)
- Максимум 3-5 попыток
- Увеличение времени ожидания между попытками
2. Логирование ошибок
Рекомендации:
- Логировать все ошибки с контекстом
- Сохранять request ID для трассировки
- Записывать параметры запроса (без чувствительных данных)
- Фиксировать timestamp для анализа
3. Мониторинг
Метрики для отслеживания:
- Частота ошибок по типам
- Время ответа
- Процент неудачных запросов
- Количество retry операций
4. Обработка специфических ошибок
Invalid Api-Key (404):
- Проверить корректность API ключа
- Убедиться, что ключ не отозван
- Проверить права доступа роли
Offer not signed (403):
- Подписать офферту в личном кабинете
- Проверить роль пользователя
"Circle is open":
- Уменьшить частоту запросов
- Реализовать пакетную обработку
- Добавить задержки между запросами
Лучшие практики
1. Rate Limiting на стороне клиента
import asyncio
from asyncio import Semaphore
sem = Semaphore(10) # Максимум 10 одновременных запросов
async def limited_request(api_call):
async with sem:
return await api_call()
2. Пакетная обработка запросов
# Вместо множества одиночных запросов
for product_id in product_ids:
await api.get_product(product_id)
# Используйте пакетные запросы
await api.get_products(product_ids)
3. Асинхронная обработка
# Используйте асинхронные библиотеки
# для эффективной обработки множественных запросов
tasks = [api.get_product(id) for id in product_ids]
results = await asyncio.gather(*tasks)
4. Circuit Breaker Pattern
from circuitbreaker import circuit
@circuit(failure_threshold=5, recovery_timeout=60)
async def api_call_with_circuit_breaker():
return await api.some_method()
Диагностика и устранение неполадок
Типичные сценарии ошибок
Сценарий 1: Множественные ошибки 400
Симптомы: Частые ошибки Bad Request
Причины:
- Неверная структура данных
- Отсутствие обязательных полей
- Неверные типы данных
Решение:
- Проверить схему JSON для endpoint
- Валидировать данные перед отправкой
- Использовать TypeScript или Pydantic для проверки типов
Сценарий 2: Ошибки 403 Forbidden
Симптомы: Доступ запрещён к определённым методам
Причины:
- Недостаточно прав роли
- Не подписана оферта
- Метод недоступен для текущего типа аккаунта
Решение:
- Проверить права в личном кабинете
- Подписать офферту
- Связаться с поддержкой
Сценарий 3: Частые ошибки 429
Симптомы: Превышение лимитов запросов
Причины:
- Слишком высокая частота запросов
- Отсутствие rate limiting на клиенте
- Неоптимизированные алгоритмы
Решение:
- Реализовать rate limiting
- Использовать пакетные запросы
- Кэшировать результаты
- Оптимизировать логику приложения
Полезные ресурсы
Официальная документация
Клиентские библиотеки
- ozon-api (Python) - Асинхронная Python библиотека
- ozon-api-client (PyPI) - Swagger клиент
- gam6itko/ozon-seller (PHP) - PHP клиент
- diphantxm/ozon-api-client (Go) - Go клиент
Сообщество
- Telegram: Ozon Seller API Notification - Новости и обновления
- Ozon Developer Community - Форум разработчиков
Дополнительные материалы
Резюме
Основные HTTP статусы
- 400 - Ошибка клиента (невалидные данные)
- 403 - Доступ запрещён (нет прав или не подписана оферта)
- 404 - Ресурс не найден (неверный API ключ)
- 409 - Конфликт (дубликаты, version conflicts)
- 429 - Превышение лимитов (код ошибки 8)
- 500 - Ошибка сервера
Специфические коды
- "Circle is open" - Блокировка за превышение частоты запросов
- Invalid Api-Key - Неверный API ключ (404)
- Offer not signed - Не подписана оферта (403)
Лучшие практики
- Реализовать rate limiting на клиенте
- Использовать exponential backoff для 429 и 500 ошибок
- Логировать все ошибки с контекстом
- Использовать асинхронные запросы
- Применять пакетную обработку данных
- Мониторить метрики ошибок
Дата создания: 2025-02-10 Версия API: Актуально на 2025 год