Документація · API v1

Пошук AItransform для розробників

Один тег підключає віджет із фільтрами, підказками під час введення, бейджами та блоком статей. Три HTTP-методи дають повний доступ до пошуку з вашого коду: результати по категоріях, фільтри й фасети (зокрема за атрибутами фіду), підказки, події кліку та покупки. Усі приклади нижче — реальні відповіді демо-каталогу.

JSON / UTF-8 Без SDK CORS увімкнено Зміни лише додаткові

Початок роботи

Базова адреса
https://api.aitransform.fun
Формат
JSON у тілі запиту та відповіді, UTF-8
Автентифікація
поле key у тілі JSON
Перевірка доступності
GET /v1/health{"ok": true}

Ключ

Ключ видається в кабінеті після активації акаунта. Він передається у полі key тіла запиту — заголовків авторизації немає. Один ключ = один каталог (індекс).

Невідомий, вимкнений або прострочений ключ не дає помилки на пошуку: /v1/search і /v1/suggest відповідають 200 з порожнім результатом. Лише /v1/event повертає 404 unknown key. Тому під час інтеграції перевіряйте total і наявність поля lang — у відповіді за невідомим ключем його немає.

CORS і дозволені домени

API відповідає Access-Control-Allow-Origin: * на методи POST, GET, OPTIONS: викликати його з браузера можна напряму, без проксі. Обмеження задається не CORS, а списком доменів у кабінеті («Налаштування»):

  • Хост береться із заголовка Origin, якщо його немає — з Referer. Запит без обох (сервер-сервер) проходить перевірку.
  • Порожній список — обмежень немає.
  • Запис shop.ua дозволяє shop.ua і всі піддомени; запис =shop.ua — лише точний збіг. Схема, порт, шлях і регістр не враховуються.
  • Не в списку — 403 {"detail": "origin not allowed for this key"}.

SDK не потрібен

Достатньо fetch або curl. Перший запит:

curl -s https://api.aitransform.fun/v1/search \
  -H "Content-Type: application/json" \
  -d '{"key": "ВАШ_КЛЮЧ", "q": "шолом", "per_category": 1}'

Версіонування

Версія зафіксована у шляху: /v1. Зміни в межах v1 лише додаткові — з'являються нові необов'язкові параметри та нові поля відповіді, наявні поля не перейменовуються і не зникають. Ігноруйте невідомі поля та не покладайтеся на порядок ключів у JSON. Поля, позначені нижче як «лише коли…», можуть бути відсутні.

Віджет

Найшвидший спосіб підключення: один тег наприкінці <head>. Сніпет із вашим ключем є в кабінеті.

<script defer src="https://aitransform.fun/cdn/widget.js" data-key="ВАШ_КЛЮЧ"></script>

Атрибути data-*

АтрибутЗа замовчуваннямЗначення
data-keyобов'язковийКлюч каталогу. Без нього лоадер пише в консоль [AItransform] data-key не указан в <script> і нічого не завантажує.
data-langukМова інтерфейсу та голосового вводу: uk або ru (будь-яке інше значення = uk).
data-currencyгрнПідпис валюти біля ціни. data-currency="" — без валюти.
data-in-stockувімкненоПоказувати лише товари в наявності. 0 або false — показувати й відсутні.
data-input-selectorавтовизначенняCSS-селектор поля пошуку на сайті, до якого прив'язується віджет (клік відкриває панель). Без атрибута шукається input[type="text"], input[type="search"] або поле з placeholder «Поиск» / «Search».
data-datalayerвимкнено1 або true — дублювати події aitransform_search / aitransform_click / aitransform_purchase у window.dataLayer (GTM).
data-suggestяк у кабінеті (типово вимкнено)Рядок підказок «Можливо, ви шукаєте» під час введення: 1 — показувати, 0 — ні. Без атрибута діє перемикач кабінету (нижче).
data-filtersяк у кабінеті (типово вимкнено)Панель фільтрів (сортування, ціна, бренди, атрибути): 1 — показувати, 0 — ні. Без атрибута діє перемикач кабінету.

Перемикачі в кабінеті

Підказки «Можливо, ви шукаєте» і панель фільтрів типово вимкнені (покупець бачить результати й категорії, як раніше); вони вмикаються в кабінеті («Налаштування») для всього каталогу. Сервер повідомляє поточний стан у полі widget ({suggest, filters}) кожної відповіді /v1/search і /v1/suggest, а віджет застосовує його з наступної відповіді — без перезбирання й без змін на сайті. Атрибути data-suggest / data-filters на тезі перевизначають кабінет для конкретного сайту; без атрибута діє налаштування кабінету. З вимкненими підказками віджет не викликає /v1/suggest під час набору (лише при відкритті, для блоку «Популярні запити»); з вимкненою панеллю не надсилає facets: true, а обрані фільтри й сортування скидаються.

Що бачить покупець

Панель віджета показує все, що повертає /v1/search, — окремої розмітки на сайті не потрібно:

  • Фільтри й сортування. Поруч із результатами — панель з вибором сортування (за релевантністю, спочатку дешевші, спочатку дорожчі), полями «від — до» та чипами цінових діапазонів із гістограми facets.price, брендами з facets.brands (перші 12, далі «Показати ще») та групами атрибутів фіду з facets.params (Колір, Розмір… — перші 6 ключів, далі «Показати ще»). Активні фільтри зібрані чипами над панеллю, кожен знімається окремо, «Скинути» прибирає все. На телефоні панель захована за кнопкою «Фільтри» з лічильником активних фільтрів. Групи без значень не показуються, а чипи діапазонів зникають, коли розкиду цін немає, тож каталог без атрибутів бачить лише те, що має сенс. Панель можна вимкнути в кабінеті або атрибутом data-filters="0".
  • Підказки під час введення. Від 2 символів, через 150 мс після останньої клавіші, віджет питає /v1/suggest і показує рядок «Можливо, ви шукаєте»: до 6 популярних запитів і до 4 категорій («у категорії …»). Клік підставляє запит (для категорії — одразу відкриває її), а сам набраний текст підказкою не вважається. Рядок можна вимкнути в кабінеті або атрибутом data-suggest="0".
  • Бейджі на картках. З поля badges товару: «Акція» (sale; не дублюється, коли поруч уже закреслена стара ціна), «Новинка» (new), «Хіт» (hit); закріплений правилом товар (pinned) отримує «Рекомендовано».
  • «Статті та сторінки». Коли у відповіді є блок content (клієнт підключив контент-фід, нижче), над категоріями з'являється список до 5 статей, сторінок, акцій чи пунктів FAQ зі сніпетом і типом. Клік відкриває сторінку в новій вкладці й дає подію aitransform:click з content: true; до /v1/event такий клік не надсилається, щоб не змішувати сторінки з артикулами.
  • Порядок. Категорії віджет упорядковує сам, крім відповідей із rules_applied category або pin — тоді зберігається порядок сервера. Сортування за ціною переставляє товари всередині категорій, порядок категорій не змінює.
  • Уточнення — не новий пошук. Зміна фільтра чи сортування перезапитує сервер одразу (без затримки), але не породжує нову подію aitransform:search і не запускає редирект правила; в аналітику кабінету такі запити теж не потрапляють.

Як монтується

  • Лоадер захищений від подвійного підключення (window.__aitransformLoaded) і зберігає конфігурацію у window.AITRANSFORM.
  • Стилі додаються у <head>; контейнер <div id="aitransform-root"> створюється наприкінці <body> автоматично — окремий контейнер розмічати не потрібно.
  • Віджет прив'язується до наявного поля пошуку сайту. Панель також відкривається за хешем #/search/ в URL.
  • Ідентифікатор сесії (session_id) — UUID у sessionStorage["ait_sid"]; останні запити — localStorage["ait_recent"] (до 5).
  • До API віджет надсилає POST /v1/search з тілом {key, q, in_stock, session_id, facets: true} (facets: true — лише поки панель фільтрів увімкнена); коли покупець щось обрав у панелі, додаються filters (лише непорожні частини: price_min, price_max, brands, params) і sort (лише price_asc / price_desc). При відкритті — POST /v1/suggest з {key, q: "", limit: 5} для блоку «Популярні запити», під час набору — з {key, q, limit: 6}. Виправлення розкладки, одруків, склейку слів і морфологію виконує сервер.
Запит віджета з фільтрами
{
  "key": "ВАШ_КЛЮЧ",
  "q": "шолом",
  "in_stock": true,
  "session_id": "3f1c…",
  "facets": true,
  "filters": {"price_min": 500, "price_max": 5000, "brands": ["LS2 Helmets"], "params": {"Колір": ["чорний"]}},
  "sort": "price_asc"
}

Події для сайту

Віджет надсилає window.dispatchEvent(new CustomEvent("aitransform:<name>", {detail})). З data-datalayer="1" той самий об'єкт потрапляє у window.dataLayer з полем event.

CustomEventdataLayer eventПоля detailКоли
aitransform:searchaitransform_searchq (string), total (number), corrected (string | null), match_mode (string | null)Через 1,5 с після останньої відповіді пошуку (запит «устоявся»), або одразу при кліку на товар чи редиректі.
aitransform:clickaitransform_clickq (string), mpn (string), pos (number), link (string); для кліку по статті додатково content: true, а mpn = URL сторінкиКлік по картці товару (після відправки /v1/event) або по пункту блоку «Статті та сторінки» (без /v1/event).
aitransform:purchaseaitransform_purchasempns (string[]), order_id (string), value (number | null), q (string)Після виклику window.AITRANSFORM.track("purchase", …)нижче.
window.addEventListener("aitransform:search", (e) => {
  const { q, total, corrected, match_mode } = e.detail;
  if (total === 0) analytics.track("search_no_results", { q });
  if (corrected) console.log(`«${q}» показано як «${corrected}» (${match_mode})`);
});

window.addEventListener("aitransform:click", (e) => {
  const { q, mpn, pos, link } = e.detail;
  analytics.track("search_click", { q, mpn, pos, link });
});

Події магазину: window.AITRANSFORM.track()

Лоадер публікує window.AITRANSFORM.track(type, payload) — спосіб повідомити пошук про покупку, додавання в кошик чи перегляд без власного коду для /v1/event. Викликати можна одразу після тега віджета: до завантаження бандла виклики стають у чергу й надсилаються, щойно віджет завантажиться. Ключ і session_id підставляються самі.

АргументЗначення
typepurchase, add_to_cart, view або click. Інший тип — виклик ігнорується, повертається false.
payload.mpnsМасив артикулів (як mpn у відповіді пошуку), до 20; порожні та дублікати відкидаються, довші за 128 символів обрізаються. Можна передати один payload.mpn.
payload.order_idНомер замовлення у вашому магазині, до 64 символів. Необов'язковий.
payload.valueСума замовлення, число ≥ 0 (рядок «2500.50» теж приймається), округлюється до копійок. Необов'язкова.
payload.q, payload.posЗапит (до 200 символів) і позиція — для click / add_to_cart, коли ви їх знаєте.

Функція повертає true, якщо подію надіслано (sendBeacon, не блокує сторінку), і false для purchase без жодного артикула — сервер відповів би 400. Для purchase віджет додатково генерує aitransform:purchaseaitransform_purchase у dataLayer при data-datalayer="1").

Сторінка «Дякуємо за замовлення»
<script defer src="https://aitransform.fun/cdn/widget.js" data-key="ВАШ_КЛЮЧ"></script>
<script>
  // артикули замовлення — ті самі mpn, що у фіді та у відповіді пошуку
  window.AITRANSFORM.track("purchase", { mpns: ["184216", "345625"], order_id: "A-1", value: 2500 });
</script>
Кошик і подія для GTM
// кнопка «В кошик» на сторінці товару
window.AITRANSFORM.track("add_to_cart", { mpn: "184216" });

// власна аналітика
window.addEventListener("aitransform:purchase", (e) => {
  const { mpns, order_id, value, q } = e.detail;   // ["184216", "345625"], "A-1", 2500, ""
  analytics.track("purchase", { order_id, value, items: mpns.length });
});

Покупка важить у популярності товару 5 кліків і формує бейдж «Хіт»; сума value у ранжування не потрапляє ніколи — вона лише підсумовується у звіті (докладніше у /v1/event).

Редирект і правила мерчандайзингу

Якщо у відповіді /v1/search є redirect.url (правило «редирект» з кабінету), віджет переходить за адресою лише за явним Enter або після того, як запит простояв без змін 1,5 с. Приймаються тільки адреси http(s)://; будь-яка нова літера, взаємодія з результатами, зміна фільтра або закриття панелі скасовує перехід; адреса поточної сторінки ігнорується. Коли rules_applied містить category або pin, віджет зберігає порядок категорій сервера; інакше впорядковує їх сам.

Підказки

POST https://api.aitransform.fun/v1/suggest

Автодоповнення для поля вводу: популярні запити покупців, категорії та товари за префіксом. Відповіді кешуються на 60 с.

Поле запитуТипЗа замовчуваннямЗміст
keystringобов'язковеКлюч каталогу.
qstring""Префікс (до 200 символів; нижній регістр, одинарні пробіли).
limitint5Кількість запитів і товарів. Тихо обмежується діапазоном 1…10, помилки не буде.
Поле відповідіЗміст
queries[]{q, count}Популярні запити з результатами за останні 30 днів, чия показана форма (після виправлення) починається з q; до limit. Одруки складаються у своє виправлення.
categories[]{name, count}До 5 категорій серед товарів, назви яких відповідають префіксу. Не залежить від limit.
products[]{mpn, title, price, image_link, link}До limit товарів за автодоповненням назви. Полів availability і product_type тут немає.
widget{suggest, filters}Перемикачі віджета з кабінету (bool), ті самі, що й у /v1/search (вище); є і при порожньому q, у кеш не потрапляє. Відсутнє лише у відповіді за невідомим ключем.

Порожній q повертає 8 найпопулярніших запитів за 30 днів і порожні categories та products — так віджет будує блок «Популярні запити». Невідомий ключ — 200 {"queries": [], "categories": [], "products": []}.

Запит
{"key": "ВАШ_КЛЮЧ", "q": "шол", "limit": 2}
Відповідь
{
  "queries": [
    {"q": "шолом", "count": 190},
    {"q": "шолом до 1000 грн", "count": 33}
  ],
  "categories": [
    {"name": "Шоломи закриті (інтеграл)", "count": 645},
    {"name": "Шоломи відкриті (без підборіддя)", "count": 248},
    {"name": "Шоломи кросові (ендуро)", "count": 173},
    {"name": "Шоломи трансформери (модуляр)", "count": 137},
    {"name": "Скло для шоломів (візор)", "count": 92}
  ],
  "products": [
    {
      "mpn": "345625",
      "title": "Шлем 111 №44 Шолом 111 №44",
      "price": "3054",
      "image_link": "https://aitransform.fun/imgcache/e6/e60166f45acc782996fb7049561ff5727ab7853f.webp",
      "link": "https://motozilla.com.ua/product/shlem-111-44/"
    },
    {
      "mpn": "235205",
      "title": "Шлем 111 №18 Шолом 111 №18",
      "price": "3054",
      "image_link": "https://aitransform.fun/imgcache/a1/a120e8346debb4bf016f7b1664fdfc51e0c38744.webp",
      "link": "https://motozilla.com.ua/product/shlem-111-18-mtch-10-01770/"
    }
  ],
  "widget": {"suggest": true, "filters": true}
}

GET-форма

GET https://api.aitransform.fun/v1/suggest?key=ВАШ_КЛЮЧ&q=шол&limit=5

Та сама відповідь. У GET-запиті ключ потрапляє до URL і журналів доступу, тому з браузера й віджета використовуйте POST.

Події

POST https://api.aitransform.fun/v1/event

Повідомляє серверу про дію покупця з результатами пошуку. Віджет надсилає click сам, а покупку, кошик і перегляд сайт передає через window.AITRANSFORM.track(); при власній інтеграції надсилайте події ви.

ПолеТипЗа замовчуваннямОбмеження та зміст
keystringобов'язковеКлюч каталогу, до 64 символів.
typestringобов'язковеclick, add_to_cart, view або purchase.
qstring""Запит, за яким показано результати, до 200 символів.
mpnstring""Артикул товару з відповіді пошуку, до 128 символів.
mpnsstring[] | nullnullКілька артикулів однією подією (замовлення з кількох товарів): до 20, кожен до 128 символів; порожні й дублікати відкидаються, mpn і mpns об'єднуються. Приймається для будь-якого типу; на кожен артикул пишеться окремий запис.
order_idstring | nullnullНомер замовлення у магазині, до 64 символів. Пишеться в кожен запис події.
valuenumber | nullnullСума замовлення, 0…1012, зберігається з двома знаками. Ніколи не впливає на ранжування — лише підсумовується у звіті.
posint | nullnullПозиція товару у видачі, 0…10000.
session_idstring | nullnullТой самий ідентифікатор сесії, що й у пошуку, до 64 символів.

Успіх — 204 No Content з порожнім тілом. Перевірки йдуть у порядку: тип → довжини → posvalue → артикули → ключ → домен, тому неправильний тип з невідомим ключем дає 400, а не 404. purchase без жодного артикула — 400 purchase needs mpn or mpns; mpns не масивом або value не числом — 422. Тексти помилок цього методу англійські (це помилка інтеграції, а не повідомлення покупцеві).

Що живить. Події формують звіт «Аналітика» в кабінеті: кліки, додавання в кошик, CTR, таблиця кліків за артикулами. Покупки рахуються окремо в даних звіту: кількість, конверсія (покупки ÷ пошуки) і таблиця куплених артикулів із сумою замовлень — сума береться з value, як його передав сайт, і не перевіряється; у кабінеті ці плитки поки не показуються. view приймається і зберігається, у звітах поки не показується.

Популярність товарів. У рушій закладено бонус за подіями: click важить 1, add_to_cart — 3, purchase — 5, події за 30 днів із періодом напіврозпаду 14 днів; пошук множить релевантність на коефіцієнт не більше 1,05, тож популярність переставляє лише товари з близькою релевантністю і ніколи не витягує нерелевантні (view і value не враховуються). Той самий перерахунок позначає топ-5 % товарів бейджем hit. Перерахунок виконується щоночі (о 04:45 за часом сервера) за подіями останніх 30 днів, тож нові кліки й покупки впливають на видачу після наступного перерахунку.

Покупка — один виклик на замовлення
{
  "key": "ВАШ_КЛЮЧ",
  "type": "purchase",
  "mpns": ["184216", "345625"],
  "order_id": "A-1",
  "value": 2500,
  "session_id": "3f1c…"
}
const payload = JSON.stringify({
  key: "ВАШ_КЛЮЧ",
  type: "click",
  q: "шолом",
  mpn: "345625",
  pos: 0,
  session_id: sessionId
});
// не блокує перехід на сторінку товару
if (!navigator.sendBeacon("https://api.aitransform.fun/v1/event", new Blob([payload], { type: "application/json" }))) {
  fetch("https://api.aitransform.fun/v1/event", { method: "POST", headers: { "Content-Type": "application/json" }, body: payload, keepalive: true });
}

Помилки

Тіло помилки — {"detail": "…"}. Для 422 поле detail — масив об'єктів {type, loc, msg, input} (валідація типів).

КодМетодКолиdetail
200search, suggestНевідомий, вимкнений або прострочений ключпорожній результат: total: 0, query_used: "", без lang; для suggest — порожні масиви
204eventПодію прийнятотіла немає
400searchНекоректний sortsort must be one of relevance, price_asc, price_desc
400searchper_category поза 1…100per_category must be 1..100
400searchНекоректний filters.availabilityfilters.availability must be one of in_stock, out_of_stock
400searchПонад 20 брендівfilters.brands: at most 20 values
400searchВід'ємна, нескінченна або більша за 1012 межа ціниfilters.price_min/price_max must be >= 0
400searchПонад 10 ключів у filters.paramsfilters.params: забагато ключів: 11 (максимум 10)
400searchПорожній, задовгий або з крапкою ключ у filters.paramsfilters.params: ключ не може бути порожнім, filters.params: ключ задовгий (максимум 64 символи), filters.params: ключ «a.b» не може містити крапку
400searchПонад 20 значень або задовге значення у filters.paramsfilters.params: «Колір»: забагато значень: 21 (максимум 20), filters.params: «Колір»: значення задовге (максимум 256 символів)
400searchpage без категоріїpage.category is required
400searchpage.from поза 0…10000page.from must be 0..10000
400searchpage.size поза 1…100page.size must be 1..100
400searchfrom + size понад 10000page.from + page.size must be <= 10000
400eventНевідомий typetype must be one of click, add_to_cart, view, purchase
400eventЗадовге поле (key > 64, q > 200, mpn або елемент mpns > 128, session_id > 64, order_id > 64)field too long
400eventpos поза 0…10000pos out of range
400eventПонад 20 елементів у mpnsmpns: at most 20 items
400eventvalue від'ємне, NaN або понад 1012value must be >= 0
400eventpurchase без mpn і mpnspurchase needs mpn or mpns
403search, suggest, eventХост із Origin/Referer не в списку дозволених доменівorigin not allowed for this key
404eventНевідомий або неактивний ключunknown key
422усіНеправильний тип поля або відсутнє обов'язкове полемасив, наприклад [{"type": "int_parsing", "loc": ["body", "per_category"], "msg": "Input should be a valid integer, unable to parse string as an integer", "input": "abc"}]
502search, suggestПошукове ядро недоступнеsearch backend unavailable

Ліміти та обмеження

ПараметрОбмеженняПоведінка при перевищенні
q (search, suggest, event)200 символівобрізається по останньому пробілу (search, suggest); 400 в event
Слів у запиті12; слово до 32 символівзайві слова відкидаються мовчки
key64 символиобрізається (search, suggest); 400 в event
session_id64 символиобрізається (search); 400 в event
per_category1…100, за замовчуванням 100400
filters.brands20 значень по 64 символи400 понад 20; значення обрізаються
filters.price_min/max0…1012400
filters.params10 ключів по 64 символи, 20 значень на ключ по 256 символів400 з українським текстом
facets.params у відповіді8 ключів по 12 значеньрешта не повертається
content у відповіді5 документів, сніпет до 200 символіврешта не повертається
page.from / page.size0…10000 / 1…100, сума до 10000400
page.category256 символівобрізається
Категорій у відповіді10категорію поза топ-10 можна запитати через page, якщо ви знаєте її назву (з фіду)
limit у suggest1…10, за замовчуванням 5тихо приводиться до діапазону
mpn / pos в event128 символів / 0…10000400
mpns / order_id / value в event20 артикулів по 128 символів / 64 символи / 0…1012400
Кеш відповідейsearch 180 с, suggest 60 с
Тайм-аут пошукового ядра15 с на виклик502
Частота запитів. Сьогодні API не має ліміту кількості запитів на ключ. Захист — обмеження розмірів полів, кеш і список дозволених доменів. Ключі, домени, мову каталогу, інтервал оновлення фіду та термін зберігання логу ви керуєте в кабінеті. Ліміт частоти може з'явитися в майбутньому — це буде додатковою зміною з окремим кодом відповіді.

Фіди й оновлення каталогу

Каталог завантажується з вашого фіду за URL (http/https, gzip підтримується; адреси приватних мереж не приймаються). URL і формат задаються в кабінеті, там же кнопка «Індексувати».

ФорматЩо читається
yml (Prom.ua, Яндекс YML)<offer>: name або model, vendorCode або @idmpn, vendor, price, oldprice, categoryId → назва з дерева <category>, picture, url, @available (за замовчуванням в наявності), label або sales_notes, <param name>.
google (Google Merchant RSS)<item>: g:title/title, g:id або g:mpn, g:brand, g:price (за наявності g:sale_price вона стає ціною, а g:price — старою ціною), g:product_type або g:google_product_category, g:image_link, g:link/link, g:availability, g:custom_label_0 → мітка, g:product_detail → параметри.
csv (UTF-8, заголовки без урахування регістру)назва title|name|название|назва; артикул id|sku|mpn|артикул|код; бренд brand|vendor|бренд; ціна price|цена|ціна; категорія category|product_type|категория|категорія; зображення image|image_link|picture; посилання link|url|ссылка; наявність availability|available; стара ціна oldprice|old_price|старая цена|стара ціна; мітка label|метка|мітка; опис description|опис|описание. Рядки без назви пропускаються.
  • Документ у каталозі: mpn (ідентифікатор), title (назва + бренд, якщо його ще немає в назві), brand, price, product_type, image_link, link, availability, за наявності oldprice (лише коли більша за ціну), label (до 64 символів), description (до 2000 символів; товар без опису ранжується трохи нижче в своїй категорії), params (до 50; ключ до 64 символів, значення до 256 — саме вони стають фасетами facets.params).
  • Розмір фіду: до 512 МБ (і стиснутого, і розпакованого).
  • Оновлення: планове завдання раз на 6 годин перевіряє каталоги й оновлює ті, чий інтервал минув; інтервал обирається в кабінеті — 1, 2, 3, 6, 12 або 24 години (за замовчуванням 6). Оскільки завдання запускається раз на 6 годин, інтервали 1–3 години фактично дають оновлення кожні 6 годин. Ручне оновлення — кнопка «Індексувати».
  • Без простою: кожне оновлення будує новий версійний індекс і атомарно перемикає на нього псевдонім — пошук працює весь час.
  • Зображення: після індексації картинки завантажуються, зменшуються та зберігаються у WebP за адресою https://aitransform.fun/imgcache/<2 символи>/<sha1>.webp; саме вона повертається в image_link. Доки конвертація триває, віддається оригінальна адреса з фіду.

Контент-фід: статті, сторінки, акції, FAQ

Другий, необов'язковий фід — сторінки сайту, які варто показувати поруч із товарами: блог, умови доставки, акції, відповіді на питання. Підключається в кабінеті: «Каталог» → картка «Контент» → URL і формат → «Зберегти» → «Індексувати контент». На картці видно кількість документів, час останнього оновлення й останню помилку; далі фід перечитується за тим самим інтервалом, що й товарний. Порожній URL + «Зберегти» відключає фід. Результат — блок content у відповіді /v1/search і «Статті та сторінки» у віджеті.

ФорматЩо читається
rss<item>: title, link або guid, description або content:encoded, category → тип, enclosure / media:content / media:thumbnail → зображення, pubDate або dc:date.
atom<entry>: title, link rel="alternate", content або summary, category term|label → тип, link rel="enclosure" → зображення, updated або published. Формат визначається за кореневим тегом, тож Atom, збережений як rss, теж індексується.
csv (UTF-8, колонки в будь-якому порядку)назва title|назва|название|name; адреса url|link|посилання|ссылка; текст text|body|текст|опис|описание|description|content; тип type|тип|category|категорія|категория; зображення image|picture|зображення|картинка; дата updated|date|дата|pubdate.
jsonМасив об'єктів із тими самими ключами, що й у CSV, або об'єкт з масивом у items, entries, content чи data.
  • Документ: title (до 300 символів), url (ідентифікатор; лише http(s); при повторі адреси залишається останній), text (до 4000 символів, HTML-теги прибираються), type, image, updated. Пункт без назви або з адресою не http(s) пропускається.
  • Тип зводиться до article / page / promo / faq / other: саме значення або підказки в назві категорії («статті», «blog», «новини» → article; «сторінка» → page; «акці», «знижк», «sale» → promo; «faq», «питання» → faq); порожня категорія — article.
  • Ліміти: файл до 20 МБ (стиснутий і розпакований), до 20 000 адрес; ті самі перевірки URL, що й для товарного фіду (лише публічні адреси).
  • Індекс: окремий, з псевдонімом <індекс>_content, з тими самими аналізаторами й синонімами, що й товарний; оновлюється без простою, а якщо новий фід «схуд» понад 10 % — залишається попередній. Синоніми з кабінету застосовуються і до контенту.

Приватне API

Кабінет https://aitransform.fun/cabinet/ працює через маршрути /cab/* із сесійною кукою. Це внутрішній інтерфейс сторінки кабінету, а не публічний контракт: він може змінюватися без попередження і не призначений для інтеграцій. Публічними є лише /v1/search, /v1/suggest, /v1/event і /v1/health.

Зміни

Усі зміни в межах v1 додаткові: старі поля відповіді та параметри запиту зберігаються.

v0.182026-09-24

Перемикачі віджета в кабінеті («Налаштування»): підказки «Можливо, ви шукаєте» і панель фільтрів. Відповіді /v1/search і /v1/suggest отримали поле widget: {suggest, filters}; атрибути лоадера data-suggest / data-filters перевизначають кабінет для сайту.

v0.152026-09-24

Віджет: панель фільтрів (сортування, ціна з діапазонами, бренди, атрибути фіду; на телефоні — за кнопкою «Фільтри»), підказки «Можливо, ви шукаєте» під час введення, бейджі «Акція / Новинка / Хіт / Рекомендовано», блок «Статті та сторінки», хелпер window.AITRANSFORM.track() і подія aitransform:purchase. Запит віджета до /v1/search тепер містить facets: true та обрані filters / sort; aitransform:click для статті має content: true.

v0.142026-09-24

Розуміння запиту: склейка і розбиття слів (match_mode: "compound"), розкладка по окремих словах, українська морфологія в кожному слові, виправлення за контекстом. /v1/search: filters.params і facets.params (атрибути фіду), products[].badges, блок content; товари без ціни чи опису ранжуються нижче в категорії. /v1/event: тип purchase, поля mpns, order_id, value; покупка важить 5 у популярності. Кабінет: контент-фід (RSS / Atom / CSV / JSON), пропозиції синонімів із журналу запитів. Фіди: поле description, ліміт 512 МБ.

v0.122026-09-23

Правила мерчандайзингу в /v1/search: нові поля redirect, rules_applied, products[].pinned; порядок категорій за правилами top/bottom/hide. Список дозволених доменів і мова каталогу з кабінету; термін зберігання логу по клієнту. Віджет: редирект за Enter або після 1,5 с, серверний порядок категорій.

v0.112026-09-07

API v2 запиту: filters (ціна, бренди, наявність), sort, page, per_category, facets; у відповіді — lang, page, facets, title_display, oldprice, label. Синоніми по клієнту, популярність товарів за подіями (перерахунок — окреме планове завдання, поки не ввімкнене).

v0.92026-09-07

Бекенд пошуку, етап 1: додаткові поля відповіді match_mode, took_ms, price_filter, query_used, suggestion, cached; ціна з тексту запиту; кеш 180 с; аналітика запитів і /v1/event; /v1/suggest; оновлення фідів без простою.

v0.82026-09-06

Віджет: події aitransform:search / aitransform:click і dataLayer, атрибути data-* лоадера, історія запитів, ізоляція CSS.