Построение надежной интеграции с Lamoda API
Рекомендации по построению надёжной интеграции с Lamoda API, основанные на опыте партнёров.
Авторизация
Обновляйте токен заранее
TTL токена — 15 минут (для обоих API: Seller и Lamoda B2B Platform Partner API). Обновляйте его за 1 минуту до истечения, не дожидаясь 401.
import time
class TokenManager:
def __init__(self):
self.token = None
self.token_expires_at = 0
def get_token(self):
if self.token and time.time() < self.token_expires_at - 60:
return self.token
self._refresh_token()
return self.token
def _refresh_token(self):
response = requests.post(
"https://api-b2b.lamoda.ru/auth/token",
json={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"grant_type": "client_credentials"
}
)
data = response.json()
self.token = data["access_token"]
self.token_expires_at = time.time() + data["expires_in"]
Кэшируйте токен, но не credentials
Храните токен в памяти или Redis, но client_id/secret — только в защищённом хранилище (env, vault).
Логирование
Логируйте всё
Обязательно сохраняйте для каждого запроса:
- Время запроса (с часовым поясом)
- Метод и URL с query-параметрами
- Тело запроса (для POST)
- Заголовки запроса
- Код и тело ответа
- Время выполнения
Это критически важно для разбора инцидентов с поддержкой.
Не логируйте секреты
Маскируйте в логах: client_secret, access_token, персональные данные клиентов.
Обработка ошибок
Повторяйте запросы с нарастающей задержкой
При 5xx или timeout — повторяйте с увеличением интервала. При 401 — обновите токен. При 429 — выждите паузу.
import time
import random
import requests
def request_with_retry(method, url, token_manager, max_retries=3, **kwargs):
"""Выполнение запроса с retry, обработкой 401 и 429."""
headers = kwargs.pop("headers", {})
for attempt in range(max_retries):
headers["Authorization"] = f"Bearer {token_manager.get_token()}"
try:
response = requests.request(
method, url, headers=headers, timeout=30, **kwargs
)
if response.status_code == 401:
# Токен истёк — принудительно обновляем
token_manager.token = None
continue
if response.status_code == 429:
# Rate limit — ждём Retry-After или 30 секунд
wait = int(response.headers.get("Retry-After", 30))
time.sleep(wait)
continue
if response.status_code < 500:
return response
except requests.Timeout:
pass
# Exponential backoff для 5xx и timeout
sleep_time = (2 ** attempt) + random.uniform(0, 1)
time.sleep(sleep_time)
raise Exception("Max retries exceeded")
Различайте типы ошибок
| Код | Действие |
| 400 | Исправьте запрос, повтор не поможет |
| 401 | Обновите токен и повторите |
| 404 | Ресурс не существует, не повторяйте |
| 429 |
Rate limit — подождите Retry-After секунд (или 30 сек) и повторите
|
| 500-503 | Повторите с нарастающей задержкой |
Работа с заказами
Используйте webhooks вместо polling
Webhooks быстрее и надёжнее. Polling используйте как fallback.
| Подход | Задержка | Нагрузка |
| Webhooks | ~секунды | Минимальная |
| Polling | 5-10 минут | Высокая |
Отслеживайте статусы товаров, не только заказов
При частичном выкупе статус заказа "Delivered", но у отдельных товаров может быть "Not bought". Используйте itemStatusChanged нотификации.
Соблюдайте cutOff
Отгружайте заказы максимально близко к cutOff. Если cutOff = null — включите заказ в ближайшую запланированную отгрузку (подробнее: Создание отгрузки).
Работа с ценами
Используйте batch-методы (FBS)
Для FBS: вместо 1000 отдельных запросов set-price используйте один set-prices с массивом.
Примечание: Пакетный метод set-prices доступен только для FBS. Для FBO batch-метода update-price нет — обновляйте цены поштучно.
Не снижайте цену более чем на 70% без подтверждения
Передавайте force: true только если уверены. Иначе цена попадёт в карантин.
Синхронизация остатков
Используйте дельту, не полную выгрузку
Параметр updatedAt возвращает только изменённые записи. Это быстрее в 10-100 раз.
# Плохо: весь сток
GET /api/v1/stock/goods?page=1&limit=1000
# Хорошо: только изменения за последний час
GET /api/v1/stock/goods?updatedAt=2025-12-02+09:00:00
Полная спецификация: GET /api/v1/stock/goods
Rate limits
Формальных задокументированных лимитов нет — ограничения определяются общими настройками nginx на уровне инфраструктуры.
Рекомендации:
- Не более 100 SKU в одном запросе
- Пауза 1-3 секунды между запросами
- Не более 10-20 запросов в минуту
При превышении лимитов API вернёт 429 Too Many Requests. Используйте значение заголовка Retry-After (если присутствует) или выждите 30-60 секунд перед повтором.
Надёжность
Делайте идемпотентные запросы
Используйте уникальные ID в запросах. При повторе с тем же ID результат должен быть тот же.
Храните состояние локально
Не полагайтесь только на API — дублируйте критические данные (заказы, отгрузки) в своей БД.
Мониторьте API-вызовы
Отслеживайте:
- Количество ошибок в минуту
- Время ответа (p50, p95, p99)
- Rate limit hits (429)
- Статус webhook-доставки
Чек-лист перед запуском
- Токен обновляется автоматически до истечения (за 60 секунд)
- Логи пишутся для всех запросов/ответов
- Реализованы повторные запросы с нарастающей задержкой для 5xx
- Webhook endpoint отвечает быстро (рекомендуется < 5 секунд), обрабатывает нотификации асинхронно
- Webhook endpoint возвращает 2xx и ставит обработку в очередь
- Обрабатываются дубли нотификаций (по
sequenceNumberдляstatusChanged/itemStatusChanged; для FBO-нотификаций поле может отсутствовать) - warehouseCode передаётся во всех отгрузках
- Правильный метод для модели (FBS:
set-price/set-prices, FBO:update-price) - Цены кратны 10 рублям
- Материалы в правильном формате (пробел-тире-пробел)
- Есть алерты на рост ошибок
- Документированы все интеграционные точки
Рекомендуемая архитектура

Ключевые компоненты:
| Компонент | Назначение |
| API Gateway | Повторные запросы, логирование, управление токенами, ограничение частоты |
| Ваша БД | Локальная копия заказов, остатков, отгрузок |
| Webhook Handler | Приём нотификаций от Lamoda, быстрый 200 OK, асинхронная обработка |
| Логи | Все запросы/ответы API для разбора инцидентов (Elastic, Loki, etc.) |
См. также
Помогла эта информация?
Спасибо за отзыв