ВАЙБ-КОММЕРС ← О Радаре

Радар маркетплейсов · справочник API

Справочник API

Пять операций — status, overview, find, rates, changes — в двух обёртках: MCP и REST. Агенту достаточно подключить MCP (строки подключения); здесь — всё, что нужно, чтобы вызывать операции руками или писать свой клиент.

Подключение

Адрес

https://radar.vibecommerce.ru. С другим Host Радар отвечает 400.

MCP

POST /mcp — streamable HTTP, JSON-RPC. Инструменты называются как операции (status, find, …), параметры те же. Ответ инструмента — тот же конверт в result.structuredContent; отказ предметной области приходит с isError: true и тем же телом. Заголовок Accept: application/json, text/event-stream обязателен. Готовые вызовы tools/call и tools/list — в примерах curl.

REST

POST /v1/<операция> с JSON-телом или GET /v1/<операция>?параметры.

Авторизация

Заголовок Authorization: Bearer $RADAR_API_KEY. Ключ вида rdr_… выдаётся после оплаты. В адресе запроса ключ не принимается.

Лимит

60 вызовов в минуту на ключ; в каждом ответе заголовки X-RateLimit-Limit и X-RateLimit-Remaining, при превышении — 429 с Retry-After. Ответ concise — до 4 КБ, списки — до 8 КБ; у detailed бюджета нет (цифры).

Свежесть

Источники проверяются ежедневно, релиз данных пересобирается каждый час. Не поток в реальном времени.

Порядок работы агента: status → find (слова → ключ) → rates (ключ → числа) или overview → changes (что изменилось). Если find вернул ambiguous: true — кандидатов несколько с равной оценкой или одинаковым названием: спросите пользователя, а не берите первого.

Машиночитаемая схема. GET /v1/schema с вашим ключом отдаёт JSON: схемы параметров всех операций, перечисления, формы ключей, лимиты и коды ошибок — для своего клиента или агента.

Конверт ответа

Каждый ответ — один и тот же конверт: число всегда приходит вместе с источником, датой и слепыми зонами.

ok

true — ответ получен; false — отказ, причина в error.

op

Имя операции: status, overview, find, rates, changes.

data

Полезная нагрузка операции (null при отказе). Чужие строки — названия категорий, складов, заголовки — только здесь и не длиннее 200 символов. Состав — в разделе каждой операции.

error

null или { code, message, next_step, candidates }. Коды — в разделе «Ошибки».

basis

"nominal" — число взято из справочника площадки как есть: без скидок, уровня продавца, СПП и соинвеста. Это верхняя оценка расхода, а не ваш фактический платёж.

provenance

Откуда числа: список { source, changed_at, effective_from } (в detailed ещё observed_at и url). Три даты: effective_from — когда редакция вступила в силу (у WB её нет — null, а не дата снапшота); changed_at — когда менялось содержание источника; observed_at — когда сторож последний раз успешно проверил источник (null — не наблюдается).

release_id

Версия наблюдения, по которой построен ответ: по ней ответ воспроизводится. Релиз пересобирается каждый час.

stale

true — данные могли измениться незаметно: сторож не подтверждал хотя бы один источник ответа дольше 48 часов (или зеркало без изменений дольше 3 суток, пока нет отметки проверки), либо есть неопубликованные изменения. Ставки при этом отдаются, пока наблюдению не больше 30 дней; старше — отказ stale. Причина названа в caveats и blind_spots.

caveats

Оговорки к числам (кратко в concise, полный текст в detailed). Агент обязан показать их пользователю.

blind_spots

Чего Радар не видит — в каждом ответе: ключ, что именно не видно, вид (structural — класса данных нет; operational — временно не читается). На такие вопросы отвечайте «сервис этого не видит», а не числом. Пустой список — видим всё.

cursor

Продолжение длинного списка (changes) или null.

concise и detailed. concise — по умолчанию: числа, источник, даты и короткие оговорки. detailed — полный конверт: ссылки на источники, observed_at, подробности и полный текст оговорок. У всех операций один параметр response_format.

Слепые зоны. Слепые зоны — это то, чего Радар не видит: на такие вопросы отвечайте «сервис этого не видит», а не числом. Примеры: процент СПП Wildberries и соинвеста Ozon по конкретному товару (данные кабинета продавца), приёмка WB (метод отключила сама WB), склады WB в России поштучно, Яндекс Маркет (вне сервиса). Полный актуальный перечень — в blind_spots каждого ответа.

Известная слепота. Если площадка сама отключила метод (так с 14.08 у приёмки WB), сторож один раз сообщает об этом и дальше молчит; в status и overview такой источник не делает stale истинным, а назван в data.known_blind (источник, класс, дата последнего успеха, ключ слепой зоны). Когда метод оживёт, поле исчезнет.

status

Можно ли верить ответам прямо сейчас. Вызывайте первым в сессии и когда ответ кажется устаревшим.

response_format string необязателен

"concise" (по умолчанию) — числа, источник и даты, до 4 КБ (списки — до 8 КБ); "detailed" — полный конверт: url, observed_at, подробности, полный текст оговорок. У detailed бюджета размера нет — цифры в разделе «Лимиты».

В data: release (релиз и дата снапшота), platforms, not_covered (["ym"] — Яндекс Маркет не входит), heartbeat, sources[] (по каждому источнику changed_at — когда файлы менялись, и observed_at — когда сторож последний раз успешно его проверил; null — не наблюдается), fail_streak (сколько прогонов сторожа подряд не удались — прогонов, не дней), known_blind (источники, которые площадка отключила сама, — см. «Известная слепота» в конверте). Слепые зоны — в поле blind_spots конверта, все сразу.

overview

Сводка для начала работы: сколько изменений за 30 дней по доменам и площадкам, главные из них, что вступает в силу в ближайшие 45 дней.

platform string необязателен

"wb", "ozon" или "all". Без параметра — все площадки.

response_format string необязателен

"concise" (по умолчанию) — числа, источник и даты, до 4 КБ (списки — до 8 КБ); "detailed" — полный конверт: url, observed_at, подробности, полный текст оговорок. У detailed бюджета размера нет — цифры в разделе «Лимиты».

В data: as_of, snapshot_date, window, counts (домен × площадка), top (до 8 главных событий), took_effect, announced, next. Подробности по любому событию — через changes.

find

Переводит слова пользователя в ключ справочника площадки. Возвращает до 10 кандидатов с ключами и без ставок. Ставку по строке Радар не отдаёт — только по ключу из find.

platform string обязателен

"wb" или "ozon".

kind string обязателен

Что искать. category — категория (WB: subject_id; Ozon: category_path); warehouse — склад (только wb); cluster — кластер доставки (только ozon); express_service — услуга службы rFBS Express (только ozon: ожидание курьера, отказ, возврат); api_method — метод API площадки. У wb нет вида cluster, у ozon — warehouse: отказ invalid.

query string обязателен

Слова пользователя, 1–120 символов. Нет совпадений — короче и существительным («наушники», «платье»).

limit integer необязателен

1–10, по умолчанию 10.

response_format string необязателен

"concise" (по умолчанию) — числа, источник и даты, до 4 КБ (списки — до 8 КБ); "detailed" — полный конверт: url, observed_at, подробности, полный текст оговорок. У detailed бюджета размера нет — цифры в разделе «Лимиты».

В data: candidates[] — поля кандидата в таблице ниже; у метода API ещё summary и deprecated, у услуги Express — edition. Рядом: total (сколько нашлось), truncated (нашлось больше, чем показано), ambiguous (правило — ниже), groups (при пустом списке — родительские ветки, в которые попал запрос). Ставок в ответе нет — только ключи.

Нет совпадений — not_found: переформулируйте короче и существительным («платье», а не «красивые платья на лето»).

Поля кандидата

key

Берётся в rates целиком, как есть (раздел «Ключи rates»).

label, context

Название и родитель — строки площадки.

match

exact — название совпало с запросом полностью (порядок слов, склонение, «для» и «и» не мешают); partial — совпала часть слов или опечатка; path — у методов API совпал путь.

score

Оценка 0–1.

same_label

Сколько кандидатов с таким же названием в справочнике. Больше 1 — одно название в разных ветках.

unmatched

Слова запроса, которых нет в названии кандидата. Поля нет — нашлись все слова.

current

Ozon, категория: путь есть в действующей редакции прайса.

editions, price_plans

Только detailed. Ozon, категория: даты вступления редакций прайса, где путь есть, и прайсы (base, select), где он есть.

directions

Кластер Ozon: где допустим — from (отгрузка), to (доставка).

Когда переспрашивать: ambiguous

ambiguous: true — первого кандидата нельзя брать без вопроса: переспросите пользователя. Правило одно для всех видов поиска и площадок; true при любом из трёх условий:

  1. у лучшего кандидата есть unmatched — часть слов запроса не нашлась;
  2. у двух лучших одинаковая оценка или одинаковое название (same_label больше 1);
  3. лучший — partial, а второй отстаёт меньше чем на 0,05.

Один кандидат, в названии которого нашлись все слова запроса, — false, даже если он partial («Москва» → «Москва, МО и Дальние регионы»).

Кластер → ключ для rates

find(kind=cluster) отдаёт ключ {"cluster": …}, а в rates кластер кладётся под именем направления — cluster_from (откуда отгрузка) или cluster_to (куда доставка), рядом с category_path. Кластер с directions без нужного направления отвергается.

Ответ find(kind="cluster", query="москва") — ключ с directions:

{ "candidates": [ { "key": { "cluster": "Москва, МО и Дальние регионы" },
    "label": "Москва, МО и Дальние регионы", "match": "partial",
    "directions": ["from", "to"], "same_label": 1 } ],
  "ambiguous": false }

Тело rates: значение из key.cluster идёт в cluster_from и/или cluster_to рядом с category_path (готовый вызов — пример 7):

{ "platform": "ozon", "liters": 2,
  "key": { "category_path": ["Электроника", "Наушники и гарнитуры", "Наушники"],
           "cluster_from": "Москва, МО и Дальние регионы",
           "cluster_to": "Санкт-Петербург и СЗО" } }

rates

Комиссия, логистика, хранение и приёмка — только по ключу из find. У каждого числа источник и дата.

platform string обязателен

"wb" или "ozon".

key object обязателен

Ключ кандидата из find. Формы — в разделе «Ключи rates» ниже. Строка вместо ключа — отказ needs_key с кандидатами.

model string необязателен

Одна модель продаж вместо всех, до 40 символов. WB: paidStorageKgvp (FBW, склад WB), kgvpMarketplace (FBS), kgvpSupplier (DBS, витрина продавца), kgvpPickup (C&C, самовывоз), kgvpBooking (бронирование), kgvpSupplierExpress (eDBS); принимаются и алиасы FBW, FBS, DBS, DBW, C&C, eDBS. Ozon: FBO, FBO ПВЗ, FBO Fresh, FBS, RFBS (и написания FBO_PVZ, FBO_FRESH); бывают частные группы со своим порогом цены — их название в поле model ответа. Неизвестная модель — отказ с перечнем допустимых.

price number необязателен

Ozon: цена товара, ₽ (больше 0, до 100 000 000) — выбирает ценовой сегмент. Без price — ставки всех сегментов. Для групп с порогом цены (например, «RFBS Мототехника свыше 500 тыс.руб.») ставка идёт с условием.

price_plan string необязателен

Ozon: "base" (по умолчанию) — базовый прайс; "select" — прайс программы «Селект», только для продавцов программы.

liters number необязателен

Объём единицы товара, л (больше 0, до 100 000). WB: к «первый литр + каждый следующий» добавляется итог. Ozon: логистика FBO/FBS считается по литрам, в том числе для КГТ.

part string необязателен

Ozon: "storage" — вместо комиссии и логистики только хранение (нужен category_path); "acceptance" — только приёмка FBO. Для WB не применяется: part="acceptance" — отказ not_available (WB отключила метод приёмки для всех продавцов, данных нет и не будет, пока WB его не вернёт), прочие значения — invalid.

as_of string необязателен

Ozon: дата YYYY-MM-DD, на которую выбирается редакция тарифов (по умолчанию — сегодня по Москве). Дата раньше первой редакции — отказ invalid.

response_format string необязателен

"concise" (по умолчанию) — числа, источник и даты, до 4 КБ (списки — до 8 КБ); "detailed" — полный конверт: url, observed_at, подробности, полный текст оговорок. У detailed бюджета размера нет — цифры в разделе «Лимиты».

В data: WB: commission (по моделям продаж), для склада — logistics (первый литр и каждый следующий; с liters — итог), возврат продавцу, монопалета (логистика по литрам, хранение за паллету в сутки). Ozon: commission (по моделям и сегментам цены), logistics и delivery (кластеры, последняя миля, обработка), для категорий «Мебель» и «Строительство и ремонт» — компенсация rFBS за КГТ; с part — free_days и after_free_period (хранение) либо acceptance (приёмка). Блок ставок одного файла несёт source, effective_from и единицу один раз. «—» в справочнике приходит как available: false, а не ноль.

Ошибка «маршрута нет» у логистики Ozon не роняет ответ: logistics.available: false, комиссия остаётся.

Что отдаёт rates

Wildberries

  • key {subject_id} — комиссия по всем моделям продаж (раздел «Значения перечислений»), %.
  • key {warehouse} — по складу: логистика короба (первый литр и каждый следующий; с liters — итог), хранение короба в сутки, возврат продавцу, монопаллета (логистика по литрам, хранение за паллету в сутки). available: false — тарифа на это сочетание нет; это не ноль.
  • part у WB не применяется: part=acceptance — отказ not_available (WB отключила метод приёмки для всех продавцов: данных нет и не будет, пока WB его не вернёт), прочие значения — invalid.

Ozon

  • key {category_path} — комиссия по моделям (FBO, FBO ПВЗ, FBO Fresh, FBS, RFBS) и ценовым сегментам. Без price — все сегменты; с price — один. Для «Мебели» и «Строительства и ремонта» — ещё компенсация rFBS за доставку КГТ (₽ за заказ).
  • liters — логистика FBO/FBS. Кластеры кладутся в ключ: cluster_from (отгрузка) и cluster_to (доставка). Без кластеров отдаётся тариф «по умолчанию» (default_tariff: true) — он отличается от маршрутного. Крупногабаритный товар на FBO/FBS отдельного тарифа не имеет — считается по объёму общей таблицей.
  • part=storage — срок хранения без платы в днях (по категории; нужен category_path) и плата после него, ₽ за литр в сутки. part=acceptance — приёмка FBO: ₽ за литр единицы, потолок, первый литр.
  • key {express} — тариф службы rFBS Express на дополнительную услугу (ожидание, отказ, возврат). Ячейка не число («100% стоимости прямого потока») — available: false и исходный текст в value_text. Базовой цены экспресс-доставки в публичных файлах нет.

Ценовые сегменты Ozon

В официальном прайсе комиссия Ozon растёт с ценой товара: верхние сегменты дороже нижних. Это номинал по прайсу, а не ошибка Радара. В прайсе от 07.10.2026 медиана столбца «свыше 300 ₽» — 51 %, у 94 % строк не меньше 40 %; в прайсе от 06.04.2026 у категории по шести сегментам 36–38 % — ставка растёт с ценой. Сегмент выбирается параметром price; без него отдаются все.

segment — ценовой сегмент прайса Ozon (цена товара в российских рублях, ₽), model — модель продаж, as_of — дата, на которую выбрана редакция, effective_from — дата вступления этой редакции. У логистики: price_segment — ценовой сегмент по цене товара (до и свыше 300 ₽), liters — объём, для которого посчитано, default_tariff: true — кластеры не заданы, отдан тариф «по умолчанию» (он отличается от маршрутного: укажите cluster_from и cluster_to).

Дата, объявленная редакция и срок действия

  • Ставка выдаётся на as_of (по умолчанию сегодня). Если Ozon уже объявил следующую редакцию прайса или логистики, в блоке commission или logistics есть next_edition: effective_from — с какой даты, changed — какие ставки меняются (value — новая, now — действующая; до 5 строк, сколько всего — n_changed), пустой changed — ставки те же. readable: false — редакция объявлена, но сервис её разобрать не смог. Блока нет — объявленной редакции нет. Редакция, объявленная на будущую дату, видна и в changes.announced.
  • У ставок со сроком (хранение, срок размещения без платы, приёмка) есть valid_until — последний день действия редакции: период назван площадкой («с 01.10.2026 по 31.12.2026») или за ней уже стоит следующая. Нет поля — редакция действует, пока не опубликована новая.
  • Дата as_of в будущем, а следующей редакции нет: берётся последняя опубликованная, и в caveats сказано, что будущие редакции не опубликованы.
  • Ставки — номинал справочника площадки: верхняя оценка расхода. Категорийные скидки, уровень продавца, СПП Wildberries и соинвест Ozon в справочниках отсутствуют, сервис их не знает.

Ключи rates

Ключ — объект, который отдал find; его кладут в key без изменений. Ставка выдаётся только по ключу: по похожему названию Радар не гадает и вернёт кандидатов.

WB, комиссия

{"subject_id": 593}

subject_id — число, предмет из find(kind="category"). Комиссия по всем моделям продаж.

WB, логистика и хранение

{"warehouse": "Склад WB РФ"}

warehouse — строка из find(kind="warehouse"), до 120 символов. Можно указать вместе с subject_id. Склады РФ с 15.08.2026 есть только сводными строками («Склад WB РФ», «Свой склад РФ» и т. п.).

Ozon, комиссия, хранение, приёмка

{"category_path": ["Электроника", "Наушники и гарнитуры", "Наушники"]}

category_path — только массив из 2–3 уровней, как отдал find. Строкой с «/» нельзя: слэш бывает внутри уровня («с/х животных»).

Ozon, логистика по кластерам

{"category_path": […], "cluster_from": "Москва, МО и Дальние регионы", "cluster_to": "…"}

Кластер из find(kind="cluster") кладётся по направлению: cluster_from — откуда отгрузка, cluster_to — куда доставка; поле directions у кандидата говорит, где он допустим. Кластер с directions без нужного направления отвергается; голый cluster без направления — отказ invalid с подсказкой. Без кластеров — тариф Ozon «по умолчанию». Пример — в разделе find и в примерах curl.

Метод API (оба маркетплейса)

find(kind="api_method") — ключа для rates нет

Это каталог методов с ссылкой на документацию площадки: ответ find несёт summary и deprecated, ставок у метода нет.

Ozon, служба rFBS Express

{"express": {"carrier": "Ozon Express", "service": "Возврат отправления", "region": "Москва, Санкт-Петербург"}}

Объект express — целиком, как отдал find(kind="express_service"): carrier, service и region обязательны.

changes

События изменений условий за окно дат: что мы увидели, что вступило в силу, что вступит в ближайшие 45 дней.

from string необязателен

Начало окна, YYYY-MM-DD. По умолчанию — 30 дней назад. Для регулярной проверки передавайте data.snapshot_date из прошлого ответа, а не дату вызова: релиз может отставать, и событие иначе выпадет из окна. События того же дня повторятся — сверяйте по id.

to string необязателен

Конец окна, YYYY-MM-DD. По умолчанию — сегодня.

domain string необязателен

tariffs — редакции и ставки; api — методы API (добавлены, удалены, объявлены устаревшими); offers — смена редакции оферт (дата, ссылка, номера изменённых, добавленных и удалённых пунктов; трактовка смысла правок пока не подключена: в событии interpretation_status = pending, а номера пунктов надо читать по тексту документа по ссылке); law — публикации права РФ; news — новости площадок (дата, заголовок, теги; ссылка url есть только у новостей Ozon, у новостей WB url = null — портал WB закрыт входом). Новости приходят только с domain=news.

platform string необязателен

"wb", "ozon" или "all".

cursor string необязателен

Продолжение списка happened из прошлого ответа, до 200 символов. Передавайте те же фильтры: с другими фильтрами — отказ invalid.

response_format string необязателен

"concise" (по умолчанию) — числа, источник и даты, до 4 КБ (списки — до 8 КБ); "detailed" — полный конверт: url, observed_at, подробности, полный текст оговорок. У detailed бюджета размера нет — цифры в разделе «Лимиты».

В data: window, snapshot_date, total, happened (событий на странице: 8 в concise, 20 в detailed), на первой странице ещё took_effect (5 последних) и announced (до 10). Событие: id, observed_at, effective_from (только у редакций Ozon), domain, platform, kind, significance и поля по виду — title, published, tags, topics, url, sections (у оферт), interpretation_status (пока pending — трактовки смысла нет). Тексты оферт и новостей в ответ не попадают — только факт, номера пунктов и ссылка (у новостей WB ссылки нет).

  • happened — что увидели в окне: новые редакции тарифов и смены ставок, методы API (добавлены, удалены, deprecated), смена редакции оферт (факт, версия, ссылка, номера изменённых пунктов; текста оферт нет), публикации права РФ. Страница: 8 событий в concise, 20 в detailed; дальше — cursor с теми же фильтрами. Сколько всего — total.
  • took_effect — редакции, вступившие в силу в окне (последние 5; сколько всего — truncated).
  • announced — что вступит в силу в ближайшие 45 дней после to (до 10).
  • Новости площадок (WB, Ozon) — только с domain=news: дата публикации, заголовок и теги. Ссылка (url) есть только у новостей Ozon; у новостей WB её нет (url: null) — портал WB закрыт входом, адрес новости назвать нельзя.
  • Трактовка смысла изменений оферт (interpretation) — машинная, с пометкой, когда шаг подключён; пока её нет, в событии interpretation_status: pending, а в caveats сказано, что номера изменённых пунктов и разделов надо читать по тексту документа по ссылке.
  • Для регулярной проверки передавайте from = data.snapshot_date из прошлого ответа, а не дату вызова: релиз может отставать. События того же дня повторятся — сверяйте по id.

Поля события

id

Устойчивый идентификатор; по нему сверяют повторы.

observed_at

День, когда изменение увидел сторож (до суток после публикации), а не день анонса площадки.

effective_from

Дата вступления — только у редакций тарифов Ozon и объявленных сеток WB.

domain, platform

Область и площадка.

kind

Вид события — см. ниже.

sub

Подтип: раздел API и т. п.

significance

high — меняет ставки или условия, публикует документ, право РФ по платформенной торговле и маркировке; normal — штатное (дрейф коэффициентов, новости, налоги и таможня); low — служебное, в changes не выходит.

n_keys, bulk

Сколько ключей затронуто (складов, категорий, методов); bulk: true — 20 и больше.

samples

Примеры затронутых ключей {key, label, field, old, new}: в concise три, в detailed до двадцати; samples_note говорит, сколько всего.

field

Какое поле справочника площадки изменилось (например, boxDeliveryBase); у rate_enabled — первое из изменившихся.

title, tags, topics, published, url

Заголовок, теги, темы, дата публикации и ссылка — у новостей, актов права и оферт.

version, version_old

Версия оферты сейчас и раньше.

pdfs

Новые PDF-редакции оферты (kind=new_pdf).

sections

Оферты: changed, added, removed — номера пунктов (до 10), n_changed, n_added, n_removed — сколько всего, total — пунктов в документе, sections — затронутые разделы, renumbered — сколько пунктов только сменили номер при том же тексте (изменением не считаются).

interpretation, interpretation_status

Трактовка смысла изменения оферты и её статус (pending — не подключена).

Виды событий

Тарифы: edition_published (новая редакция прайса или логистики Ozon, объявленная сетка складских тарифов WB), rate_changed, rate_enabled и rate_disabled (склад начал или перестал принимать: «не принимает» ↔ число; одно событие на склад), warehouse_added, warehouse_removed, category_added, category_moved, category_removed, page_rates_changed (справка Ozon: последняя миля, обработка, хранение, приёмка), edition_added (новая редакция тарифа хранения или приёмки на странице Ozon), storage_terms_published и storage_terms_changed (опубликован или изменён файл сроков размещения без платы), mechanics_changed (изменилось число механики баллов за скидки: баллы за рубль, потолок доли услуг, условия отказа от участия), rules_text_changed (изменён текст правил программы баллов). API: method_added, method_removed, method_deprecated, method_undeprecated, method_changed. Оферты: sections_changed, new_version, new_pdf, doc_unavailable. Право: act_published. Новости: news_published.

Ошибки и лимиты

Отказ — тот же конверт с ok: false и объектом error: { code, message, next_step, candidates }. В MCP — isError: true с тем же телом. Текст исключений, пути и внутренности наружу не отдаются.

invalid 400

Параметр не по схеме: тип, диапазон, неизвестное значение или неизвестное поле запроса (в message — перечень допустимых). Текст message называет поле.

needs_key 422

Ставка спрошена строкой, а не ключом из find. В candidates — кандидаты: выберите нужный вместе с пользователем и повторите rates с key.

not_found 422

Ключа нет в справочнике или модели нет в редакции. next_step и candidates подсказывают, что выбрать. У find: нет совпадений — переформулируйте короче и существительным.

ambiguous 422

Ключ встречается с разными значениями — угадывать нельзя.

unsupported 422

Площадка или вид данных вне сервиса.

stale 422

Наблюдение старше 30 дней — ставку не отдаём.

unavailable 503

Релиза нет или он не читается — временно, повторить позже можно. Текст исключения и пути наружу не отдаются.

not_available 422

Площадка не публикует эти данные (например, приёмку WB: метод отключила сама WB). Повторять бесполезно, пока площадка их не вернёт; что именно не видно — в blind_spots.

Ответы транспорта

401

Нет заголовка Authorization или ключ неверный, отозван либо с истёкшим сроком. В next_step — как передать ключ. В MCP отказ по ключу — ошибка протокола с тем же текстом.

400

Ключ передан в адресе запроса (api_key, token, значение rdr_…) — не принимается, только заголовок Authorization: Bearer. Либо тело запроса — не JSON или не JSON-объект. В обоих случаях error.code = invalid и полный конверт с next_step.

404

Неизвестная операция: /v1/<имя>, которого нет. error.code = invalid, полный конверт, в next_step — список операций. Служебных адресов снаружи нет.

429

Больше 60 вызовов в минуту на ключ. Тот же конверт (error.code = rate_limited) и заголовок Retry-After — через сколько секунд повторить.

Лимиты

  • 60 вызовов в минуту на ключ. В каждом ответе заголовки X-RateLimit-Limit (сколько всего в минуту) и X-RateLimit-Remaining (сколько осталось); при превышении — 429 с Retry-After и тем же конвертом.
  • find: query до 120 символов, limit до 10.
  • changes: страница — 8 событий (concise) или 20 (detailed); took_effect — 5, announced — 10; горизонт анонсов — 45 дней.
  • Чужие строки в data — не длиннее 200 символов.
  • Ответ concise укладывается в 4 КБ, списки — в 8 КБ.
  • У detailed такого бюджета нет. На 15.10.2026: status около 13 КБ, overview около 15 КБ, страница changes (20 событий) до 20 КБ, rates и find около 7 КБ. Агентам с небольшим контекстом — concise; detailed — когда нужна деталь конкретного события.

Чего Радар не делает

  • Не считает деньги клиента: ставка → рубли на единицу — работа вашего агента.
  • Не знает вашего кабинета: ни продаж, ни остатков, ни фактических удержаний.
  • Не отдаёт тексты оферт и документов площадок — только факт изменения, дату, версию, номера пунктов и ссылку.
  • Не пишет числа языковой моделью: числа только из наблюдения. Трактовки изменений оферт, когда шаг подключат, будут помечены как трактовки.
  • Не гадает: нет точного совпадения — отказ со списком кандидатов. Ставка по «похожему» названию могла бы отличаться на 3–7 п. п., и сервис её не подставляет.

Примеры curl

Ключ — в переменной окружения RADAR_API_KEY (export RADAR_API_KEY='rdr_…'). Каждый пример проверен на боевом Радаре.

1. Можно ли верить данным: status

Релиз, свежесть источников и слепые зоны. Вызывайте первым.

curl -s https://radar.vibecommerce.ru/v1/status \
  -H "Authorization: Bearer $RADAR_API_KEY"

2. Найти ключ категории WB: find

Возвращает кандидатов с subject_id — он нужен для rates.

curl -s https://radar.vibecommerce.ru/v1/find \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"wb","kind":"category","query":"наушники беспроводные"}'

Ответ (сокращённо)

{ "candidates": [ { "key": { "subject_id": 593 }, "label": "Наушники беспроводные",
      "context": "Смартфоны и гаджеты", "match": "exact", "score": 1.0, "same_label": 1 } ],
  "total": 1, "truncated": false, "ambiguous": false, "groups": [] }

3. Найти кластер Ozon: find (kind=cluster)

Ключ приходит как {"cluster": …}; в rates он идёт под cluster_from и/или cluster_to — следующий пример.

curl -s https://radar.vibecommerce.ru/v1/find \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"ozon","kind":"cluster","query":"москва"}'

Ответ (сокращённо)

{ "candidates": [ { "key": { "cluster": "Москва, МО и Дальние регионы" },
    "label": "Москва, МО и Дальние регионы", "match": "partial",
    "directions": ["from", "to"], "same_label": 1 } ],
  "ambiguous": false }

4. Комиссия WB по предмету: rates

Ставки по моделям продаж FBW, FBS, DBS, C&C, бронирование, eDBS — с источником и датой. Здесь два элемента из шести. effective_from: null — WB дату вступления не публикует, сервис её не выдумывает.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"wb","key":{"subject_id":593}}'

Ответ (сокращённо)

{ "commission": { "unit": "pct", "source": "wb/tariffs/commission.json", "effective_from": null,
    "rates": [ { "model": "paidStorageKgvp", "model_label": "FBW (склад WB)", "value": 30.5 },
               { "model": "kgvpMarketplace", "model_label": "FBS (маркетплейс)", "value": 35.0 } ] } }

5. Логистика WB по складу и объёму: rates

С liters приходит итог. available: false — тарифа на это сочетание нет; это не ноль.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"wb","key":{"warehouse":"Склад WB РФ"},"liters":3}'

Ответ (сокращённо)

{ "logistics": [ { "what": "logistics", "model": "paidStorageKgvp", "first_liter": 78.2, "extra_liter": 23.8,
      "unit": "rub", "liters": 3, "value": 125.8, "source": "wb/tariffs/box.json" },
    { "what": "logistics", "model": "kgvpMarketplace", "available": false } ] }

6. Комиссия Ozon для цены: rates

price выбирает ценовой сегмент (без него отдаются все), model оставляет одну модель: "model":"FBO". Про рост ставки с ценой — абзац «Ценовые сегменты Ozon» выше.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"ozon","key":{"category_path":["Электроника","Наушники и гарнитуры","Наушники"]},"price":1500}'

Ответ (сокращённо)

{ "as_of": "2026-10-15", "price_plan": "base",
  "commission": { "unit": "pct", "effective_from": "2026-10-07",
    "rates": [ { "model": "FBO", "segment": "свыше 300 ₽", "value": 47.0 },
               { "model": "FBS", "segment": "свыше 300 ₽", "value": 47.0 } ] } }

7. Логистика Ozon по маршруту: rates с кластерами

cluster_from — откуда отгрузка, cluster_to — куда доставка, liters — объём единицы. next_edition есть, когда Ozon уже объявил следующую редакцию логистики: здесь с 30.10 ставка «свыше 300 ₽» вырастет со 100 до 130 ₽.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"ozon","key":{"category_path":["Электроника","Наушники и гарнитуры","Наушники"],
       "cluster_from":"Москва, МО и Дальние регионы","cluster_to":"Санкт-Петербург и СЗО"},"liters":2}'

Ответ (сокращённо)

{ "logistics": { "default_tariff": false, "unit": "rub", "effective_from": "2026-08-28",
    "rates": [ { "price_segment": "до 300 ₽", "liters": 2.0, "value": 32.0 },
               { "price_segment": "свыше 300 ₽", "liters": 2.0, "value": 100.0 } ],
    "next_edition": { "effective_from": "2026-10-30",
      "changed": [ { "price_segment": "свыше 300 ₽", "value": 130.0, "now": 100.0 } ] } } }

8. Хранение Ozon: срок без платы и плата после него

part: "storage" вместо комиссии и логистики. Для приёмки FBO — "acceptance". valid_until — последний день действия редакции.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"ozon","key":{"category_path":["Электроника","Наушники и гарнитуры","Наушники"]},"part":"storage"}'

Ответ (сокращённо)

{ "part": "storage",
  "free_days": { "unit": "days", "effective_from": "2026-10-01", "valid_until": "2026-12-31",
    "rates": [ { "goods": "regular", "value": 344.0 }, { "goods": "kgt", "value": 39.0 } ] },
  "after_free_period": { "unit": "rub_per_liter_day",
    "rates": [ { "goods": "regular", "value": 2.5 }, { "goods": "kgt", "value": 0.08 } ] } }

9. Приёмка WB: отказ not_available

WB отключила метод приёмки для всех продавцов — данных нет. HTTP 422; повторять бесполезно, пока WB его не вернёт. Для WB part не применяется, кроме этого отказа.

curl -s -w '\nHTTP %{http_code}\n' https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"wb","key":{"subject_id":593},"part":"acceptance"}'

Ответ (сокращённо)

{ "ok": false, "op": "rates", "data": null,
  "error": { "code": "not_available",
    "message": "WB отключила этот метод для всех продавцов; данных нет и не будет, пока WB его не вернёт",
    "next_step": "повторять не нужно: слепая зона wb.acceptance в blind_spots; ставки склада WB
                  (логистика, хранение, возврат, палета) — rates(key={warehouse}) без part",
    "candidates": [] }, … }
HTTP 422

10. Что изменилось в офертах с 15 сентября: changes

Домены: tariffs, api, offers, law, news. Остальные страницы — по cursor. У оферт interpretation_status пока pending: номера пунктов читать по ссылке.

curl -s https://radar.vibecommerce.ru/v1/changes \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"domain":"offers","from":"2026-09-15"}'

11. Тарифные изменения Ozon за две недели: changes

Дата считается от сегодняшней. Событие — id, observed_at, effective_from, kind, significance, title, url (поля — в разделе changes).

FROM=$(date -u -v-14d +%F 2>/dev/null || date -u -d '14 days ago' +%F)
curl -s https://radar.vibecommerce.ru/v1/changes \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d "{\"from\":\"$FROM\",\"domain\":\"tariffs\",\"platform\":\"ozon\"}"

Ответ (сокращённо)

{ "total": 2, "happened": [ { "id": "fa7f79d5f762", "observed_at": "2026-10-07",
      "effective_from": "2026-10-07", "domain": "tariffs", "platform": "ozon",
      "kind": "edition_published", "significance": "high",
      "title": "вознаграждение Ozon (базовый прайс)", "url": "https://seller-edu.ozon.ru/…" }, … ] }

12. MCP напрямую, без клиента: tools/call и tools/list

Так проверяют подключение. Протокол — JSON-RPC, ответ приходит обычным JSON; заголовок Accept обязателен. Ответ инструмента — тот же конверт в result.structuredContent, отказ предметной области — с result.isError: true. Список инструментов — тот же запрос с "method":"tools/list" и без params: status, overview, find, rates, changes.

curl -s https://radar.vibecommerce.ru/mcp \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"find","arguments":{"platform":"wb","kind":"category","query":"наушники беспроводные"}}}'

Ответ (сокращённо)

{ "jsonrpc": "2.0", "id": 1,
  "result": { "isError": false,
    "content": [ { "type": "text", "text": "{\"ok\": true, \"op\": \"find\", …}" } ],
    "structuredContent": { "ok": true, "op": "find", "data": { … }, "error": null, … } } }

13. MCP: список инструментов

Те же операции, что в REST, — с параметрами и описаниями для агента.

curl -s https://radar.vibecommerce.ru/mcp \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

14. Остаток лимита: заголовки X-RateLimit-*

Каждый ответ несёт сколько вызовов в минуту разрешено и сколько осталось. При превышении — 429 с Retry-After.

curl -s -D - -o /dev/null https://radar.vibecommerce.ru/v1/status \
  -H "Authorization: Bearer $RADAR_API_KEY"

Ответ (сокращённо)

HTTP/2 200
content-type: application/json
x-ratelimit-limit: 60
x-ratelimit-remaining: 59

Машиночитаемая схема: GET /v1/schema

JSON Schema параметров всех операций, перечисления, формы ключей, лимиты и коды ошибок — одним ответом.

curl -s https://radar.vibecommerce.ru/v1/schema \
  -H "Authorization: Bearer $RADAR_API_KEY"

То же через GET: параметры в адресе

Любую операцию можно вызвать GET с параметрами в query-строке; для ключей rates удобнее POST с JSON.

curl -s -G https://radar.vibecommerce.ru/v1/find \
  -H "Authorization: Bearer $RADAR_API_KEY" \
  --data-urlencode "platform=wb" --data-urlencode "kind=category" \
  --data-urlencode "query=платье" --data-urlencode "limit=2"

Что будет, если передать строку вместо ключа

HTTP 422, error.code = "needs_key", в candidates — подходящие ключи. Ставку по строке Радар не отдаёт.

curl -s https://radar.vibecommerce.ru/v1/rates \
  -H "Authorization: Bearer $RADAR_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"wb","key":"наушники"}'

Неизвестная операция: HTTP 404 с полным конвертом

Тело не JSON-объект даёт HTTP 400. Оба отказа — код invalid, полный конверт и next_step со списком операций; разбирать HTML не придётся.

curl -s -w '\nHTTP %{http_code}\n' https://radar.vibecommerce.ru/v1/nope \
  -H "Authorization: Bearer $RADAR_API_KEY"

Ответ (сокращённо)

{ "ok": false, "op": "nope", "data": null,
  "error": { "code": "invalid",
    "message": "нет операции 'nope'; есть: ['changes', 'find', 'overview', 'rates', 'status']",
    "next_step": "операции — status, overview, find, rates, changes; справочник — GET /v1",
    "candidates": [] }, … }
HTTP 404

Чего Радар не видит и что сейчас читается — на странице Радара, а агент получает это в каждом ответе (поле blind_spots) и по вызову status. Вопросы по API — в Telegram.