Перейти к содержимому
Разделы документации
HTTP APIВеб

Веб: HTTP API

HTTP API для получения рекламы и обработки интерактивных действий в веб-приложениях.

Авторизация

Источник запросаАвторизацияИдентификатор
БраузерID площадки и разрешённый адрес сайта. Заголовок Origin добавляется браузером.visitor_id
СерверAuthorization: Bearer sk_live_…stable_user_id или visitor_id

API-ключ доступен в настройках паблишера. Храните его на сервере. Серверный запрос к Sidekick отправляется без Origin.

Передавайте ровно один ID пользователя. Допустимые символы: A–Z, a–z, 0–9, _, ., :, -. Сохраняйте ID между запросами; не используйте email или телефон.

Требования к площадке и адресам сайта →

Запрос рекламы

POST /api/v1/web/ads

ПолеТипОписание
platform_idобязательноstringПубличный ID площадки.
visitor_idstringID посетителя, 16–128 символов. Обязателен для браузерных запросов.
stable_user_idstringID пользователя, 1–128 символов. Доступен для серверных запросов вместо visitor_id.
request_idstringID запроса, 1–128 символов. Повторная передача не предотвращает новую выдачу.
placementstringЗарегистрированное место показа. По умолчанию chat.
language_codestringЯзык рекламы. По умолчанию en.
accept_formatsstring[]text, image, response, card, consent, quiz. По умолчанию все форматы.
contextobjectКонтекст показа. Поля зависят от context.type.
testbooleanТестовая реклама без списаний. По умолчанию false.
test_formatstringФормат тестовой рекламы при test: true.

Обязательные поля.

Content-Type: application/json. Максимальный размер тела — 64 КиБ.

Запрос с сервера

POST /api/v1/web/ads
POST /api/v1/web/ads
Authorization: Bearer sk_live_EXAMPLE
Content-Type: application/json
{
"platform_id": "plt_example",
"stable_user_id": "customer_42",
"context": {
"question": "Headphones?",
"answer": "Here are some options…"
},
"test": true,
"test_format": "card"
}

Запрос из браузера

visitorId — сохранённый ID посетителя. Запрос отправляется без API-ключа и cookies.

fetch()
const response = await fetch("https://sidekick-ads.com/api/v1/web/ads", {
method: "POST",
credentials: "omit",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
platform_id: "plt_example",
visitor_id: visitorId,
request_id: "chat-42-message-7",
test: true,
test_format: "card"
})
});
if (!response.ok) throw new Error("Ad request failed");
const payload = await response.json();

Контекст

context.typeПоляОграничения
conversationquestion, answerОба поля необязательны: до 4 096 и 16 384 символов. Тип по умолчанию.
articletitle, contentОба поля обязательны: до 4 096 и 16 384 символов.
feedtextОбязательное поле, до 16 384 символов.
static—Без текстового контекста.

Тематический подбор опирается на вопрос пользователя: question или title. У feed и static вопроса нет, поэтому туда приходит только реклама без тематического таргетинга.

Ответ

ПолеТипОписание
has_adbooleanНаличие рекламы в ответе.
adobject | nullРекламный объект; null при отсутствии рекламы.
ad.delivery_idstringID выдачи для интерактивных действий.
ad.expires_atstringСрок действия рекламы в формате ISO 8601.
ad.formatstringФормат рекламы.
ad.disclosurestringОбязательная рекламная маркировка.
ad.testbooleanПризнак тестовой рекламы.
ad.blocksobject[]Блоки text, media, gallery и buttons в порядке отображения.
ad.viewstringКвитанция для подтверждения просмотра. Есть только у оплачиваемой рекламы. Просмотр
200 OK · Нет рекламы
{
"has_ad": false,
"ad": null
}

Показ оплачивается, когда реклама увидена, а не при выдаче. Браузерный SDK подтверждает просмотр сам; при своей отрисовке отправьте подтверждение просмотра.

Отрисовка

Отобразите все блоки и маркировку из ответа. Для стандартной карточки используйте mountSidekickAd из браузерного SDK. В примере payload получен от вашего сервера, а /my-ad-interaction — обработчик действий в вашем приложении.

mountSidekickAd()
const view = Sidekick.mountSidekickAd(document.querySelector("#ad-slot"), {
onAction: async (ad, action) => {
const response = await fetch("/my-ad-interaction", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ delivery_id: ad.delivery_id, action })
});
if (!response.ok) throw new Error("Interaction failed");
return (await response.json()).ad;
}
});
view.setAd(payload.has_ad ? payload.ad : null);

Интерактивные действия

POST /api/v1/web/interact

Для consent и quiz передайте action из нажатой кнопки, delivery_id и исходный ID пользователя. Авторизация совпадает с запросом рекламы.

POST /api/v1/web/interact
{
"platform_id": "plt_example",
"stable_user_id": "customer_42",
"delivery_id": "imp_example",
"action": "signed-action-from-button"
}

Ответ: {ok: true, ad}. Замените карточку объектом ad из ответа. Переход к следующей сцене не создаёт новый платный показ.

Если у кнопки задан url, открывайте его по нажатию. Предварительная загрузка рекламных ссылок не допускается.

Подтверждение просмотра

POST /api/v1/web/seen

Показ оплачивается после просмотра: не меньше половины карточки на экране не меньше секунды. Браузерный SDK отправляет запрос сам. При своей отрисовке вызовите trackView(ad) или отправьте запрос с той же авторизацией и тем же ID пользователя.

POST /api/v1/web/seen
{
"platform_id": "plt_example",
"stable_user_id": "customer_42",
"delivery_id": "imp_example",
"view": "view-receipt-from-ad"
}

Ответ: {ok: true}. Квитанция view действует час. Запрос раньше чем через секунду после выдачи вернёт 409. Нажатие кнопки или переход по рекламной ссылке тоже засчитывают показ. Реклама, которую так и не увидели, не оплачивается.

Ошибки

СтатусЗначение
400Неверные поля запроса или идентификатор пользователя.
401Отсутствует или недействителен API-ключ.
403Площадка отключена, адрес сайта не разрешён или ключ принадлежит другому паблишеру.
409Подтверждение просмотра отправлено раньше чем через секунду после выдачи.
410Действие или квитанция просмотра недействительны либо истекли.
413Размер тела запроса превышает 64 КиБ.
429Превышен лимит запросов.
503Сервис временно недоступен.

При ошибке сохраняйте ответ приложения. Не повторяйте запрос рекламы автоматически после сетевой ошибки или 5xx: каждый запрос — новая выдача.