ibiza
CPM · CTR …
/

Почему проиграл аукцион RTB: коды loss reason и min_to_win

≈ 9 мин чтения · обновлено

Аукцион проигрывают по трем группам причин: ставка оказалась ниже конкурента или флора (цена), ответ не прошел проверки биржи (креатив, формат, блокировки) либо не уложился во время (таймаут, техническая ошибка). Биржа сообщает причину через уведомление о проигрыше lurl и макрос ${AUCTION_LOSS}, а при ценовом проигрыше может подсказать, сколько не хватило, — макросом ${AUCTION_MIN_TO_WIN}.

Как биржа сообщает о проигрыше: lurl и макросы

В OpenRTB DSP сама задает адреса уведомлений в каждой ставке. Для выигрыша это nurl (см. win notice) и burl, для проигрыша — lurl. Спецификация определяет lurl как адрес, который биржа вызывает, когда известно, что ставка проиграла. Поле появилось в версии 2.5 вместе с макросом ${AUCTION_LOSS}; макрос ${AUCTION_MIN_TO_WIN} добавлен в 2.6.

{
  "id": "resp-1",
  "seatbid": [{
    "bid": [{
      "id": "b-1",
      "impid": "1",
      "price": 120.0,
      "crid": "cr-42",
      "nurl": "https://dsp.example/win?a=${AUCTION_ID}&p=${AUCTION_PRICE}",
      "burl": "https://dsp.example/bill?a=${AUCTION_ID}&p=${AUCTION_PRICE}",
      "lurl": "https://dsp.example/loss?a=${AUCTION_ID}&l=${AUCTION_LOSS}&m=${AUCTION_MIN_TO_WIN}"
    }]
  }],
  "cur": "RUB"
}

Перед вызовом биржа ищет в URL макросы и подставляет значения. Если значения нет (например, цена выигрыша не раскрывается), макрос заменяется пустой строкой — обработчик на стороне DSP должен это переживать.

Макрос Что подставляется С какой версии
${AUCTION_LOSS} Код причины проигрыша из списка Loss Reason Codes 2.5
${AUCTION_MIN_TO_WIN} Минимальная ставка, нужная для выигрыша, в валюте и единицах ставки 2.6
${AUCTION_PRICE} Цена клиринга; при проигрыше обычно пустая ранние версии
${AUCTION_ID} BidRequest.id — ключ для склейки с логом ставки ранние версии

Важно. Поддержка lurl — политика конкретной биржи. Спецификация прямо допускает, что биржа не шлет уведомления о проигрыше или не раскрывает цены. Отсутствие lurl не значит, что вы все выиграли.

Коды причин проигрыша: что означает каждый

Список Loss Reason Codes впервые появился в OpenRTB 2.5 (раздел 5.25), в версии 2.6 перечисления вынесены в справочник AdCOM, а описание макроса ${AUCTION_LOSS} ссылается на список из OpenRTB 3.0. Коды сгруппированы по сотням.

Код Название Группа Что это значит на практике
0 Bid Won — Ставка выиграла (служебный код)
1 Internal Error Техническая Ошибка на стороне биржи
2 Impression Opportunity Expired Техническая Ответ опоздал, показ уже ушел
3 Invalid Bid Response Техническая Ответ не разобрался или не прошел валидацию
4 Invalid Deal ID Техническая Ставка с dealid, которого нет в запросе
5 Invalid Auction ID Техническая Ответ не соответствует запросу
6 Invalid Advertiser Domain Техническая Нет или неверен adomain
7 Missing Markup Техническая Нет adm и нет способа получить разметку
8 Missing Creative ID Техническая Нет crid
9 Missing Bid Price Техническая Нет цены
10 Missing Minimum Creative Approval Data Техническая Не хватает данных для модерации креатива
100 Bid was Below Auction Floor Ценовая Ставка ниже флора площадки
101 Bid was Below Deal Floor Ценовая Ставка ниже флора сделки
102 Lost to Higher Bid Ценовая Кто-то предложил больше
103 Lost to a Bid for a Deal Ценовая Приоритет отдан ставке по сделке
104 Buyer Seat Blocked Блокировка Место покупателя заблокировано
200–215 Creative Filtered — … Креатив Креатив отфильтрован: модерация, размер, формат, категория, атрибуты, язык, рекламодатель, приложение
500+ — Своя у биржи Значения конкретной биржи, их описание должно быть передано покупателю заранее

Внутри группы 200 полезно различать: 201 — креатив еще на модерации или перекодировании, 202 — отклонен биржей, 203 — размер не разрешен, 204 — неверный формат, 205 — исключения по рекламодателю, 206 и 215 — исключения по магазину или bundle ID приложения, 207 — небезопасный (не HTTPS) креатив, 209 — исключенная категория, 210 — запрещенные атрибуты, 213 — креатив не разрешен в сделке.

min_to_win: сколько не хватило

${AUCTION_MIN_TO_WIN} отвечает на главный вопрос медиабайера: «на сколько надо было поднять ставку». Спецификация 2.6 описывает три случая:

  • ставка проиграла другой ставке — подставляется минимальная цена, при которой вы сравнялись бы с победителем;
  • ставка выиграла — минимальная цена, чтобы сравняться со следующей по величине ставкой или с флором, если ставка была одна;
  • биржа не хочет или не может раскрыть цену — пустая строка.

Пустое значение допустимо, когда ставку не пустили на торги (блокировки места или рекламодателя), когда по коду проигрыша цена не была решающей или когда так требуют правила приватности.

Пример: одна и та же тройка ставок в двух типах аукциона

Флор 50 ₽ за тысячу показов, три конкурирующие ставки — 80, 72 и 60 ₽. Для наглядности считаем, что во второй цене клиринг равен второй ставке плюс 0,01 ₽.

Ставка, ₽ CPM Первая цена: AUCTION_PRICE Первая цена: MIN_TO_WIN Вторая цена: AUCTION_PRICE Вторая цена: MIN_TO_WIN
80 80 72 72,01 72
72 пусто 80 пусто 72,01
60 пусто 80 пусто 72,01

В первой цене проигравшему с 72 ₽ сообщают 80 ₽: чтобы выиграть, нужно было сравняться с победителем. Во второй цене иллюстрация спецификации дает проигравшим цену клиринга. Победитель в первой цене узнает, что переплатил: хватило бы 72 ₽. Этот сигнал — сырье для bid shading.

Флоры: проигрыш еще до сравнения ставок

Коды 100 и 101 значат, что ставка не дотянула до минимальной цены. Флор приходит в запросе: imp.bidfloor и imp.bidfloorcur для открытого аукциона, deal.bidfloor для сделки (см. что такое bidfloor). Для видео и аудио OpenRTB 2.6 добавил флоры за секунду (mincpmpersec) и по длительности (durfloors).

Типичные ошибки, которые дают код 100 без видимой причины:

  1. Валюта. bidfloorcur по умолчанию — USD. Если биржа прислала флор в одной валюте, а DSP ставит в другой без пересчета, ставка «проваливается».
  2. Единицы. price и bidfloor — это CPM, цена за тысячу. Ставка «за показ» вместо CPM в тысячу раз ниже.
  3. Флор сделки. Для ставки с dealid действует deal.bidfloor, а не флор показа — проигрыш будет с кодом 101.

Если ставка выше флора из запроса, а код 100 все равно приходит, значит, у площадки есть правила, которых нет в запросе. Это вопрос к SSP, а не к стратегии.

Таймауты и технические причины

Код 2 — ответ пришел, когда показ уже разыгран. Бюджет времени задает поле tmax: максимальное время в миллисекундах, за которое биржа ждет ставки, включая сетевую задержку. Опоздавший ответ биржа может вообще не учесть, и тогда lurl не придет — смотрите собственные метрики таймаутов. Подробно — в статье «tmax и задержки в RTB».

Коды 3–10 — ошибки в ответе: нет adm, crid, adomain, неверный dealid. Они чинятся один раз в коде и обычно дают резкий скачок win rate без изменения ставок.

Фильтрация креатива (200–215)

Это самая «дешевая» потеря: деньги не тратятся, но показ не случается. Частые сценарии:

  • креатив новый и еще на модерации у биржи (201) — проигрыши уйдут сами;
  • креатив отклонен (202) — нужно запросить причину у SSP;
  • размер не совпадает с banner.format в запросе (203) — проверьте, что вы отвечаете на размер из запроса;
  • креатив по HTTP при требовании HTTPS (207);
  • категория или атрибуты креатива в списках bcat и battr запроса (209, 210) — DSP должна фильтровать такие запросы до ставки;
  • рекламодатель в badv или приложение в bapp (205, 206, 215).

Как превращать loss reason в действия

Доминирующая причина Действие Чего не делать
102 — проиграли более высокой ставке Смотреть распределение min_to_win, повышать ставку там, где отрыв мал Повышать ставку на всех площадках разом
100/101 — ниже флора Сверить валюту и единицы; отключить площадки, где флор выше ценности показа Поднимать ставку до флора, не считая окупаемость
103 — проиграли сделке Принять как данность или договариваться о сделке Пытаться перебить сделку ценой
2 — опоздали Профилировать задержку, урезать работу на горячем пути Игнорировать: это платный трафик, который вы уже обработали
3–10 — невалидный ответ Исправить формирование ответа Ждать, что пройдет само
200–215 — креатив отфильтрован Модерация, размеры, HTTPS, учет bcat/battr/badv/bapp Поднимать ставку

Пример разбора

Допустим, за сутки DSP сделала 10 000 ставок на одном слоте, выиграла 1 800 и получила 7 400 уведомлений о проигрыше (на остальные 800 ставок уведомления нет). Разбивка: 102 — 5 200, 100 — 1 300, 2 — 600, 202 — 300. Выводы:

  • 300 проигрышей с кодом 202 — один отклоненный креатив, исправляется без денег;
  • 600 таймаутов — 6 % ставок, работа для инженеров;
  • 1 300 проигрышей по флору — проверить валюту; если все верно, флор слота выше вашей оценки показа;
  • по 5 200 ценовым проигрышам смотрим min_to_win: если медиана на 5 % выше ваших ставок, точечный подъем даст больше выигрышей, чем общий.

Цифры здесь условные — важен порядок разбора: сначала бесплатные причины, потом цена.

Почему уведомления приходят не всегда

  • Биржа не поддерживает lurl или шлет его только части покупателей.
  • Ставку отсеяли до аукциона, и биржа считает, что «проигрыша» не было.
  • Уведомление — обычный HTTP-запрос по открытой сети: часть теряется, часть может прийти повторно. Обработчик должен быть идемпотентным, а склейка с логом ставок — идти по ${AUCTION_ID} и id ставки.
  • Цена не раскрывается: ${AUCTION_PRICE} и ${AUCTION_MIN_TO_WIN} пустые по политике площадки.

Поэтому win rate считают от числа ставок, а не от суммы «выигрыши + проигрыши из lurl».

Причины проигрыша в отчетах Ibiza

DSP Ibiza в каждой ставке указывает lurl с макросами ${AUCTION_LOSS}, ${AUCTION_MIN_TO_WIN}, ${AUCTION_PRICE} и ${AUCTION_ID} и записывает пришедшие уведомления отдельно от выигрышей. На бюджеты и лимиты проигрыш не влияет — он нужен для аналитики. В расчет снижения ставки идут только ценовые проигрыши с кодом 102 и непустым min_to_win: bid shading считает по ним квантили для пары «объявление × слот» и добавляет маржу, а автобид калибрует ставку под целевой win rate. Какие макросы подставлять в трекеры, описано в документации: макросы и трекеры, снижение ставки (bid shading).

Частые вопросы

Что такое lurl в OpenRTB?

Это поле bid.lurl в ответе DSP: адрес, который биржа вызывает, когда точно известно, что ставка проиграла. Поле появилось в OpenRTB 2.5, в URL можно подставить макросы ${AUCTION_LOSS} и ${AUCTION_MIN_TO_WIN}.

Что означает код проигрыша 102?

Lost to Higher Bid — ставка прошла все проверки, но другой покупатель предложил больше. Это единственная причина, которую лечат именно ценой.

Почему ${AUCTION_MIN_TO_WIN} приходит пустым?

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

Можно ли выигрывать чаще, не поднимая ставку?

Да, если проигрыши не ценовые: отклоненный креатив, неверный размер, таймаут или блокировки рекламодателя лечатся исправлением креатива и интеграции, а не деньгами.