Market NinjaMarket Ninja

Обзор API

Как получить ключ, авторизоваться и начать работу с API Market Ninja — модель поиск → получение, лимиты, формат ошибок.

API Market Ninja даёт программный доступ на чтение к тому же краудсорсинговому датасету, который вы видите в интерфейсе расширения: товары, цены (текущие и исторические), продавцы и категории с Wildberries, Ozon, Яндекс Маркета и Lamoda.

API не собирает данные и не может запустить парсинг — это доступ только на чтение уже накопленного датасета. Новые товары в него добавляются исключительно через браузерное расширение Market Ninja: если нужного товара ещё нет в базе, сначала соберите его расширением, и только затем он станет доступен через API.
API предназначен только для серверных интеграций (server-to-server). Секретный ключ — это долгоживущий пароль, и он никогда не должен попадать в код, исполняемый в браузере (так же, как секретные ключи Stripe).

Получение ключа

Ключ выпускается в настройках расширения — раздел API-ключи, доступен на тарифе Premium. Полное значение ключа (mn_live_...) показывается только один раз, в момент создания — сохраните его сразу, восстановить позже нельзя (только отозвать и выпустить новый).

Авторизация

Каждый запрос должен содержать заголовок:

Authorization: Bearer mn_live_ваш_ключ
curl -H "Authorization: Bearer mn_live_..." \
  "https://data.marketninja.ru/v1/products?page_size=3"

Главная модель использования: «найти → получить»

Никто извне не знает внутренний id товара в нашей базе — он никому не известен заранее. Вместо этого вы всегда начинаете с того, что у вас уже есть:

Найдите товар через GET /products, передав то, что у вас есть: ссылку на товар (url), артикул маркетплейса (external_id + marketplace) или ваш собственный внутренний артикул (seller_code).

Получите id из поля data[].id в ответе — это наш внутренний идентификатор.

При необходимости обратитесь к товару напрямую по id (GET /products/{id}) или к истории его цен (GET /products/{id}/price-history) — но учтите, что текущая цена уже есть в ответе на шаге 1, отдельный запрос нужен только для анализа динамики.

Подробные сценарии с примерами — в разделах Поиск товаров, История цен, Продавцы, Категории, Бренды, Массовая выгрузка, Сессии парсинга (получение того, что вы только что спарсили через расширение) и Вебхуки (уведомление о завершении сессии вместо опроса). Полное описание параметров и ответов каждого эндпоинта — в разделе Справочник.

Формат ошибок

Любая ошибка возвращается в едином виде:

{ "error": { "code": "invalid_api_key", "message": "Invalid or revoked API key" } }
HTTP-статусerror.codeЗначение
400validation_errorНекорректные параметры запроса.
401invalid_api_keyКлюч отсутствует, некорректен, отозван или истёк.
403subscription_lapsedКлюч верный, но подписка Premium сейчас не активна.
404not_foundТовар с указанным id не найден.
429rate_limitedПревышен лимит запросов в минуту — см. Retry-After.
429quota_exceededИсчерпана дневная квота на объём данных — сбрасывается в полночь UTC.
500internal_errorВнутренняя ошибка сервера, можно повторить позже.
403 и 401 — разные проблемы для интегратора: «ключ неверный» (нужно проверить значение) и «нужно продлить подписку» (ключ рабочий, но доступ приостановлен). Не объединяйте их обработку в коде — сообщения пользователю должны различаться.

Лимиты: два независимых механизма

  • Лимит запросов (rate_limited) — ограничивает частоту обращений, сбрасывается каждую минуту. Заголовки X-RateLimit-Limit/X-RateLimit-Remaining/Retry-After.
  • Дневная квота на объём данных (quota_exceeded) — ограничивает, сколько записей товаров можно получить за сутки (считаются именно записи в ответе, а не количество запросов — один запрос с page_size=500 расходует квоту сильнее, чем page_size=10). Сбрасывается в полночь UTC. Заголовки X-Quota-Limit/X-Quota-Used.

Оба заголовочных набора присутствуют только в ответе 429 — не в успешных ответах.

Полезно знать

  • Кешируйте найденный id. Он не меняется — если вы регулярно опрашиваете один и тот же товар (например, бренд ежедневно сверяет свой каталог), сохраните id после первого поиска и в следующий раз обращайтесь сразу по нему, не повторяя GET /products — это экономит и запросы, и квоту.
  • unverified/flagged данные не скрываются по умолчанию. Поле trust_status всегда присутствует в ответе — решение, доверять ли ещё не подтверждённой записи, остаётся за вами.
  • Постраничная разбивка не требует явного знания общего числа страниц — ориентируйтесь на meta.total в ответе и продолжайте, пока не соберёте нужное количество записей.

Last updated on

On this page