Імпорт товарів
Ендпоінт створює нові або оновлює існуючі товари за унікальним source_id (upsert). Тіло запиту — JSON-масив: один елемент = один товар.
Ендпоінт
POST https://smartsearch.spefix.com/api/v2/content/product/bulk/
Content-Type: application/json
X-Secret-Token: <secret_token домену>
Усі запити мають містити заголовок X-Secret-Token з вашим секретним токеном. Детальніше — у розділі Огляд API імпорту.
Upsert-ключ
| Поле | Опис |
|---|---|
source_id | Зовнішній ID товару (як <offer id="..."> у фіді). За ним визначається create чи update |
- Якщо
source_idвже є в Spefix — товар оновлюється (200). - Якщо
source_idновий — товар створюється (201).
Поля товару
Обов’язкові (на кожен запит, включно з update)
| Поле | Тип | Опис |
|---|---|---|
source_id | string | ID товару в системі магазину |
code | string | Артикул / vendor code |
source_category_id | string | ID категорії; категорія має вже існувати в Spefix |
currency_code | string | UAH, USD або EUR |
translations | array | Мінімум один переклад (див. нижче) |
Опціональні (product)
| Поле | Тип | Опис |
|---|---|---|
new_price | number | Поточна ціна (> 0) |
old_price | number | Стара ціна (> 0, ≥ new_price) |
picture | string | URL зображення |
availability | boolean | Необов’язкове. Якщо поля немає — товар у наявності. Якщо є — береться значення з параметра (true / false). |
vendor | string | Виробник (max 255) |
group_id | string | ID групи варіантів; змінити через API не можна |
is_main | boolean | Головний варіант у групі |
warehouses | array | Склади (create і update). Див. Мультисклади |
Переклад (translations[])
| Поле | Обов’язкове | Тип | Опис |
|---|---|---|---|
language | ✅ | string | uk, ru, en |
name | ✅ | string | Назва |
url | ✅ | string | URL сторінки товару |
description | — | string | Опис |
labels | — | array | Мітки |
keywords | — | array | Ключові слова |
synonyms | — | array | Синоніми |
params | — | array | Атрибути товару |
Структура елемента params
{
"name": "Колір",
"value": "Чорний",
"is_filter": true,
"is_variation": false,
"color": "#000000",
"swatch_image": "https://example.com/swatch-black.jpg"
}
| Поле | Опис |
|---|---|
name | Назва атрибута (наприклад, «Колір») |
value | Значення атрибута (наприклад, «Чорний») |
is_filter | Якщо true, атрибут використовується у фільтрах пошуку |
is_variation | Якщо true, атрибут є варіаційним |
color | HEX-колір для swatch у фільтрах |
swatch_image | URL зображення swatch |
Мультисклади (warehouses[])
Поле можна передавати і на create, і на update. Невідомий external_id створює склад автоматично.
Детальніше про складський облік — у розділі Мультискладський облік. external_id складу має збігатися з ID у фіді та з wid у віджеті.
| Поле | Обов’язкове | Тип | Опис |
|---|---|---|---|
external_id | ✅ | string | ID складу (як у фіді / wid у віджеті) |
available | — | boolean | Наявність на складі (default: false) |
quantity | — | integer | Кількість (≥ 0, default: 0) |
new_price | — | number | Ціна на складі |
old_price | — | number | Стара ціна на складі |
currency_code | — | string | Валюта для складу (locale-channel) |
Поведінка:
- склади з payload — upsert;
- склади, яких немає в payload — видаляються для цього товару;
Product.availability= OR поwarehouses[].available.
Якщо передаєте warehouses, у масиві мають бути усі склади, які потрібно зберегти. Відсутні в запиті склади буде видалено для цього товару.
Правила валідації
source_category_idмає відповідати існуючій категорії в вашому домені.- Обов’язкові поля (
source_id,code,source_category_id,currency_code,translations) потрібно надсилати в кожному запиті, включно з update. new_priceтаold_price— додатні значення (> 0);old_price≥new_price.currency_code— лишеUAH,USDабоEUR.availability— необов’язкове boolean. Якщо поля немає — товар у наявності; якщо є — використовується значення з запиту.- Поле
vendor— до 255 символів. group_idможна задати при створенні; змінити через API не можна.warehousesдозволені на create і на update.- Масив
translationsповинен містити щонайменше один переклад; коди мов без дублікатів. language—uk,ruабоen.- Усі URL (
url,picture) починаються зhttp://абоhttps://.
Приклади
Приклад 1 — мінімальне оновлення ціни
[
{
"source_id": "580756609",
"code": "DEMO-580756609",
"source_category_id": "4660599",
"new_price": 37777,
"currency_code": "UAH",
"translations": [
{
"language": "uk",
"name": "Ноутбук Apple MacBook Neo 13\" A18 Pro 8/512GB 2026",
"url": "https://shop.example/product/580756609"
}
]
}
]
Приклад 2 — ціна + мультисклади
[
{
"source_id": "580756609",
"code": "DEMO-580756609",
"source_category_id": "4660599",
"new_price": 41199,
"old_price": 45999,
"currency_code": "UAH",
"availability": true,
"picture": "https://cdn.example/image.jpg",
"vendor": "Apple",
"warehouses": [
{
"external_id": "kyiv-main",
"available": true,
"quantity": 3,
"new_price": 41199,
"old_price": 45999
},
{
"external_id": "lviv-1",
"available": false,
"quantity": 0
}
],
"translations": [
{
"language": "uk",
"name": "Ноутбук Apple MacBook Neo 13\" A18 Pro 8/512GB 2026",
"url": "https://shop.example/product/580756609"
}
]
}
]
Приклад 3 — кілька товарів одним запитом
[
{
"source_id": "580756609",
"code": "DEMO-580756609",
"source_category_id": "4660599",
"new_price": 37777,
"currency_code": "UAH",
"translations": [
{ "language": "uk", "name": "MacBook Neo", "url": "https://shop.example/580756609" }
]
},
{
"source_id": "569726152",
"code": "DEMO-569726152",
"source_category_id": "4660596",
"new_price": 23999,
"currency_code": "UAH",
"translations": [
{ "language": "uk", "name": "HP 255R G10", "url": "https://shop.example/569726152" }
]
}
]
Відповіді
Успішний update (200)
{
"successful": [
{
"index": 0,
"status": 200,
"data": { "...": "..." }
}
]
}
Create, якщо товару не було (201)
{
"successful": [
{
"index": 0,
"status": 201,
"data": { "...": "..." }
}
]
}
Помилка валідації (400)
{
"errors": [
{
"index": 0,
"errors": {
"currency_code": ["This field is required."]
}
}
],
"successful": []
}
У відповіді можуть бути два масиви:
successful— елементи, оброблені без помилокerrors— деталі помилок для кожного індексу вихідного масиву
Після часткового успіху виправте дані відповідно до повідомлень у полі errors та повторіть запит.
Невалідний / відсутній токен (401)
{
"detail": "Authentication credentials were not provided."
}
Поведінка після запиту
| Ситуація | БД | OpenSearch |
|---|---|---|
Update (source_id існує) | Оновлюється | Асинхронний patch (зазвичай секунди) |
Create (source_id новий) | Створюється | Той самий асинхронний patch, якщо весь батч без помилок |
Зміна в пошуку не миттєва — індексація асинхронна. Patch ставиться в чергу лише коли всі елементи батча успішні. Якщо в запиті є хоч одна помилка валідації, успішні товари зберігаються в БД, але в OpenSearch не патчаться. Patch застосовується до вже існуючого індексу домену; якщо індексу ще немає, товар з’явиться після reindex фіду.
curl
curl -X POST 'https://smartsearch.spefix.com/api/v2/content/product/bulk/' \
-H 'Content-Type: application/json' \
-H 'X-Secret-Token: YOUR_SECRET_TOKEN' \
-d @payload.json
Приклади робочих процесів
Створення нового каталогу
- Створіть категорії (див. Імпорт категорій):
curl -X POST https://smartsearch.spefix.com/api/v2/content/category/bulk/ \
-H "X-Secret-Token: ваш-токен" \
-H "Content-Type: application/json" \
-d '[{"source_category_id": "1", "translations": [...]}]'
- Створіть продукти:
curl -X POST https://smartsearch.spefix.com/api/v2/content/product/bulk/ \
-H "X-Secret-Token: ваш-токен" \
-H "Content-Type: application/json" \
-d '[{"code": "PROD-001", "source_id": "1", "source_category_id": "1", "currency_code": "UAH", "translations": [...]}]'
Нові товари потрапляють у пошук через асинхронний patch (якщо батч повністю успішний і індекс домену вже існує). Інакше — після reindex фіду.
Оновлення цін і наявності
Надішліть той самий source_id з оновленими new_price / old_price / availability (і за потреби warehouses). Обов’язкові поля все одно потрібно передати. Зміна в пошуку з’явиться після асинхронного patch індексу.