Товары и артикулы
Товары с фото, характеристиками и вариантами, поиск артикула по коду и штрихкоду, номера всех товаров для сверки, вид описания.
На этой странице
Товар приходит одним объектом, в котором есть всё для карточки на вашем
сайте. В нём названия и описания на всех языках, фото полными адресами,
характеристики, ссылка на товар в магазине и все артикулы. Если у ключа есть право
prices:read, у каждого артикула есть блок price с ценой, а если есть право
inventory:read, то и блок stock с наличием.
Все адреса на этой странице требуют права catalog:read и принимают общие
параметры locale и storefront_id, а списки ещё limit и offset. Что от них зависит и
какие товары вы видите, описано на странице
«Каталог: видимость и синхронизация».
GET /api/v1/products
Опубликованные товары с артикулами. Право: catalog:read. Порядок: по номеру
товара, по возрастанию.
Параметры
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
limit |
целое | 50 | товаров на странице, от 1 до 200 |
offset |
целое | 0 | сколько товаров пропустить. Вместе с after_id не передаётся |
after_id |
целое | нет | товары с номером больше указанного. after_id=0 — с самого начала. Подробно на странице «Запросы и ответы» |
category_id |
целое | нет | товары категории, как в разделе на витрине |
brand_id |
целое | нет | товары бренда. Номер бренда берётся из /brands |
type_id |
целое | нет | товары этого типа |
sku |
строка | нет | товар, у которого есть артикул с таким кодом |
barcode |
строка | нет | товар, у которого есть артикул с таким штрихкодом |
updated_since |
дата и время ISO 8601 | нет | только товары, изменённые начиная с этого момента. Подробно в разделе «Изменения: updated_since» |
locale |
строка | основной язык магазина | язык ссылок и названий характеристик |
storefront_id |
целое | основная витрина | витрина ответа |
Фильтры можно сочетать, тогда товар должен подойти под все сразу.
category_id выбирает товары так же, как раздел на витрине. В обычную
категорию входят товары, привязанные к ней, и товары, у которых она главная.
Товары подкатегорий входят, только если в настройках категории включён показ
товаров подразделов. В категорию «по условиям» входят товары, подходящие под её
условия. Если категория на этой витрине не видна, список будет пустым.
brand_id по бренду, страница которого выключена или отдана другой
витрине, возвращает пустой список.
sku и barcode ищут совпадение всего кода или штрихкода, а не его
части. Регистр букв не важен: ab-12 найдёт артикул AB-12. Пробелы по краям
отбрасываются, а остальные знаки должны совпасть: AB12 артикул AB-12 не
найдёт. Латинская и кириллическая буквы, даже одинаковые на вид, считаются
разными, поэтому код с кириллической «А» не найдёт артикул с латинской «A».
Чтобы найти сам артикул, а не товар, удобнее /skus.
updated_since находит товар, если изменился он сам, любой его артикул
или остаток любого артикула. Сюда же входят переименование характеристики или
бренда, новый курс валюты, начало акции, правка в дополнении «Оптовые цены» и
другие изменения, которые перечислены в разделе
«Изменения: updated_since».
Правка того, чего в ответе нет, например рейтинга или числа продаж, товар
изменённым не делает.
| Ошибка 422 | Поле в errors |
Сообщение |
|---|---|---|
| неизвестный параметр | имя параметра | «Такого параметра у этого адреса нет. Допустимые параметры: …» |
category_id, brand_id или type_id не целое положительное число |
имя параметра | «Нужен номер записи — целое положительное число.» |
sku или barcode передан списком (sku[]=…) |
имя параметра | «Значение должно быть одной строкой.» |
updated_since без времени, без пояса или не дата |
updated_since |
«Нужны дата и время в формате ISO 8601, например 2026-10-17T09:00:00Z.» |
after_id не целое число от 0 |
after_id |
«after_id — номер записи, целое число от 0.» |
after_id вместе с offset |
offset |
«offset и after_id вместе не передаются. Листайте страницы чем-то одним.» |
limit вне 1–200, offset меньше 0 |
limit, offset |
«limit — целое число от 1 до 200.», «offset — целое число от 0.» |
неверный storefront_id |
storefront_id |
«Витрины с таким номером нет или она выключена. Номера витрин отдаёт адрес /storefronts.» |
Если такой категории, бренда или типа нет, ошибки не будет, придёт пустой список.
Пример
curl "https://shop.example.ua/api/v1/products?category_id=313&after_id=0&limit=1" \
-H "Authorization: Bearer <ключ>"
Ключ в примере имеет права catalog:read, prices:read и inventory:read, а
остатки у него настроены «По каждому складу».
{
"data": [
{
"id": 1045,
"slug": "lampa-svetodiodnaya-g9",
"url": "https://shop.example.ua/electrics-and-lighting/lampochki/lampa-svetodiodnaya-g9/",
"type_id": 83,
"main_category_id": 313,
"category_ids": [313, 340],
"brand": { "id": 2368, "name": "Philips" },
"name": { "ru": "Лампа светодиодная G9", "uk": "Лампа світлодіодна G9" },
"summary": { "ru": "Тёплый или холодный свет, 10 Вт", "uk": "Тепле або холодне світло, 10 Вт" },
"description": {
"ru": "<p>Светодиодная лампа для люстр и бра.</p><ul><li>Цоколь G9</li><li>Ресурс 25 000 часов</li></ul>",
"uk": "<p>Світлодіодна лампа для люстр і бра.</p><ul><li>Цоколь G9</li><li>Ресурс 25 000 годин</li></ul>"
},
"meta_title": { "ru": "Лампа G9 светодиодная купить" },
"meta_description": null,
"meta_keywords": null,
"unit": "pcs",
"qty_step": "1.000",
"qty_min": "1.000",
"pack_only": false,
"images": [
{
"id": 710,
"url": "https://shop.example.ua/storage/products/1045/710/g9.jpg",
"preview": "https://shop.example.ua/storage/products/1045/710/conversions/g9-preview.jpg",
"sku_id": null,
"locales": []
},
{
"id": 711,
"url": "https://shop.example.ua/storage/products/1045/711/g9-cold.jpg",
"preview": "https://shop.example.ua/storage/products/1045/711/conversions/g9-cold-preview.jpg",
"sku_id": 2108,
"locales": []
}
],
"features": [
{
"id": 605,
"code": "base-cap",
"name": "Тип цоколя",
"value": "G9",
"unit": null,
"values": [{ "id": 2405, "label": "G9", "color": null }]
},
{
"id": 606,
"code": "height",
"name": "Высота",
"value": "50 мм",
"unit": "мм",
"values": [{ "id": null, "label": "50 мм", "color": null }]
}
],
"updated_at": "2026-10-09T02:28:42Z",
"skus": [
{
"id": 2108,
"sku": "730601",
"barcode": "4820000730601",
"name": { "ru": "холодный белый", "uk": "холодне біле" },
"is_default": true,
"is_available": true,
"qty_min": "1.000",
"qty_step": "1.000",
"options": [{ "feature_id": 616, "value_id": 2428 }],
"features": [
{
"id": 616,
"code": "light",
"name": "Свет",
"value": "холодный белый",
"unit": null,
"values": [{ "id": 2428, "label": "холодный белый", "color": null }]
}
],
"image": "https://shop.example.ua/storage/products/1045/711/g9-cold.jpg",
"price": { "price": "208.32", "compare_price": "320.00", "discount_percent": 35, "currency": "UAH", "tiers": [] },
"stock": {
"available": "12.000",
"in_stock": true,
"preorder": false,
"warehouses": [{ "id": 3, "name": "Склад в Киеве", "available": "12.000" }]
}
},
{
"id": 2109,
"sku": "730602",
"barcode": null,
"name": { "ru": "нейтральный", "uk": "нейтральне" },
"is_default": false,
"is_available": true,
"qty_min": "1.000",
"qty_step": "1.000",
"options": [{ "feature_id": 616, "value_id": 2426 }],
"features": [
{
"id": 616,
"code": "light",
"name": "Свет",
"value": "нейтральный",
"unit": null,
"values": [{ "id": 2426, "label": "нейтральный", "color": null }]
}
],
"image": "https://shop.example.ua/storage/products/1045/710/g9.jpg",
"price": { "price": "208.32", "compare_price": "320.00", "discount_percent": 35, "currency": "UAH", "tiers": [] },
"stock": { "available": "0.000", "in_stock": false, "preorder": false, "warehouses": [] }
}
]
}
],
"meta": { "total": 37, "limit": 1, "after_id": 0 },
"links": {
"next": "https://shop.example.ua/api/v1/products?limit=1&after_id=1045&category_id=313",
"prev": null
}
}
Поля товара
| Поле | Тип | Что значит |
|---|---|---|
id |
целое | номер товара |
slug |
строка | адрес товара на сайте. Он один на все языки |
url |
строка или null |
полный адрес товара на витрине, на языке ответа. Если такого языка у витрины нет, на её основном языке |
type_id |
целое или null |
номер типа товара из /product_types |
main_category_id |
целое или null |
главная категория товара. null, если она не задана или не видна на витрине |
category_ids |
массив целых | все видимые на витрине категории, куда владелец добавил товар, вместе с главной. Категории «по условиям» сюда не входят |
brand |
объект или null |
бренд товара. null, если бренда нет или его страница скрыта на этой витрине |
brand.id |
целое | номер бренда из /brands |
brand.name |
строка | название бренда на языке ответа. Если на нём названия нет, приходит название на любом другом языке |
name |
объект или null |
название товара по языкам магазина |
summary |
объект или null |
краткое описание по языкам. Вид зависит от настройки ключа, как у description |
description |
объект или null |
описание по языкам: безопасной разметкой или простым текстом, по настройке ключа. Подробно в разделе «Описание товара» |
meta_title |
объект или null |
SEO-заголовок страницы товара по языкам |
meta_description |
объект или null |
SEO-описание страницы товара по языкам |
meta_keywords |
объект или null |
ключевые слова страницы товара по языкам |
unit |
строка | единица продажи: pcs, m, kg, g, l, m² или своя единица магазина. Если у товара она не задана, pcs |
qty_step |
строка | шаг количества в единицах unit, три знака после точки. Количество в заказе растёт от qty_min на этот шаг. При минимуме 0,5 и шаге 0,25 подойдут 0,5, 0,75 и 1. У товара, который продают только упаковками, шаг равен размеру упаковки: при упаковке 1,4 м² придёт "1.400" |
qty_min |
строка | наименьшее количество в заказе в единицах unit, три знака после точки. Если владелец минимум не задал, он равен шагу. У товара, который продают только упаковками, минимум округляется вверх до целого числа упаковок и не бывает меньше одной упаковки |
pack_only |
логическое | товар продаётся только упаковками, поштучно его купить нельзя |
images |
массив | фото товара в порядке галереи |
images[].id |
целое | номер фото |
images[].url |
строка или null |
полный адрес фото в исходном размере |
images[].preview |
строка или null |
полный адрес уменьшенной копии, до 800 пикселей по большей стороне |
images[].sku_id |
целое или null |
артикул, к которому привязано фото. null — общее фото товара |
images[].locales |
массив строк | языки, на которых фото показывается на витрине. Пустой массив — на всех. Так владелец отмечает, например, фото упаковки с надписью на одном языке |
features |
массив | общие характеристики товара, описание полей ниже |
updated_at |
дата или null |
когда товар или любой его артикул в последний раз изменился так, что это видно в ответе, в UTC. Это время сдвигают и новый курс, и акция, а правка рейтинга или запрета индексации не сдвигает. Движение остатка в это время не входит. Подробно в разделе «Изменения: updated_since» |
skus |
массив | артикулы товара в порядке, заданном владельцем. Описание полей ниже |
Фото приходят те, что показываются на этой витрине. Если владелец отметил для витрины только часть фото товара или варианта, приходят только они.
Поля qty_step и qty_min товара повторяют значения основного артикула. У
каждого артикула упаковка бывает своя, поэтому количество для заказа берите из
полей qty_min и qty_step самого артикула. Они описаны в разделе
«Поля артикула».
Поля характеристики
Характеристики приходят на языке ответа, так же, как их видит покупатель витрины. Значения одной характеристики сведены в одну строку.
| Поле | Тип | Что значит |
|---|---|---|
id |
целое | номер характеристики из /features |
code |
строка | код характеристики |
name |
строка | название характеристики на языке ответа |
value |
строка | все значения через запятую, готовые к показу: «G9», «50 мм», «красный, синий», «Да» |
unit |
строка или null |
подпись единицы на языке ответа, например «мм» или «Вт». У числа она уже стоит внутри value |
values |
массив | значения по одному |
values[].id |
целое или null |
номер значения из словаря характеристики. null у значения, которое введено вручную, например у числа, текста или «да или нет» |
values[].label |
строка | подпись значения |
values[].color |
строка или null |
цвет значения в виде #RRGGBB, если он задан в справочнике |
У товара в features приходят значения самого товара, а у артикула — только
его собственные значения, например вес или цвет этого варианта.
Поля артикула
| Поле | Тип | Что значит |
|---|---|---|
id |
целое | номер артикула. По нему спрашивают цены и остатки |
sku |
строка | код артикула, который владелец задал в магазине |
barcode |
строка или null |
штрихкод |
name |
объект или null |
подпись варианта по языкам, например «холодный белый» или «XL» |
is_default |
логическое | основной вариант, витрина показывает его первым |
is_available |
логическое | вариант продаётся. false — владелец снял его с продажи |
qty_min |
строка | наименьшее количество этого артикула в заказе, в единицах unit товара, три знака после точки. Правила те же, что у поля qty_min товара, но с упаковкой этого артикула |
qty_step |
строка | шаг количества этого артикула, в единицах unit товара, три знака после точки. У товара, который продают только упаковками, шаг равен размеру упаковки этого артикула |
options |
массив | опции покупки, по которым покупатель выбирает этот вариант |
options[].feature_id |
целое | номер характеристики из /features, у неё for_skus: true |
options[].value_id |
целое | номер значения из словаря этой характеристики |
features |
массив | собственные характеристики варианта, поля как у характеристик товара |
image |
строка или null |
полный адрес главного фото варианта в исходном размере. Если своего фото у варианта нет, приходит общее фото товара |
price |
объект | цена для вашего контакта. Есть только с правом prices:read. Поля описаны на странице «Цены», цены от количества (tiers) — в разделе «Ступени по количеству» |
stock |
объект | наличие. Есть только с правом inventory:read. Поля описаны на странице «Остатки» |
GET /api/v1/products/{id}
Один товар по номеру. Право: catalog:read. Ответ тот же, что у элемента
списка /products, только в поле data приходит объект, а не массив.
Принимает только общие параметры locale и storefront_id. Адрес отдаёт одну
запись и страниц не листает, поэтому limit, offset и after_id дают
ответ 422, как и любой другой параметр, в том числе фильтры списка:
{
"code": "validation_failed",
"errors": {
"limit": ["Такого параметра у этого адреса нет. Допустимые параметры: locale, storefront_id."]
}
}
curl "https://shop.example.ua/api/v1/products/1045?locale=uk" \
-H "Authorization: Bearer <ключ>"
{
"data": {
"id": 1045,
"slug": "lampa-svetodiodnaya-g9",
"url": "https://shop.example.ua/uk/electrics-and-lighting/lampochki/lampa-svetodiodnaya-g9/",
"...": "..."
}
}
Если товара нет, он не опубликован или номер записан не числом, приходит
ответ 404 с кодом not_found.
GET /api/v1/products/ids
Номера всех видимых товаров по возрастанию. Право: catalog:read. Адрес нужен
для сверки. Товар, которого больше нет в этом списке, сняли с продажи или
удалили, и его пора убрать у себя.
Страница здесь большая, без цен и остатков.
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
limit |
целое | 5000 | номеров на странице, от 1 до 10 000 |
offset |
целое | 0 | сколько номеров пропустить. Вместе с after_id не передаётся |
after_id |
целое | нет | номера больше указанного |
category_id, brand_id, type_id, sku, barcode, updated_since |
нет | те же фильтры, что у /products |
Ошибки те же, что у /products. На limit больше 10 000 приходит сообщение
«limit — целое число от 1 до 10000.».
curl "https://shop.example.ua/api/v1/products/ids?after_id=0&limit=10000" \
-H "Authorization: Bearer <ключ>"
{
"data": [1040, 1041, 1042, 1045, 1053],
"meta": { "total": 5, "limit": 10000, "after_id": 0 },
"links": { "next": null, "prev": null }
}
| Поле | Тип | Что значит |
|---|---|---|
data |
массив целых | номера товаров по возрастанию |
meta, links |
объекты | как у остальных списков. При after_id в meta вместо offset приходит after_id |
GET /api/v1/skus
Артикулы опубликованных товаров, без деления по товарам. Право:
catalog:read. Порядок: по номеру артикула, по возрастанию. Адрес нужен,
чтобы найти свой товар по коду или штрихкоду и забрать изменённые артикулы.
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
limit |
целое | 50 | артикулов на странице, от 1 до 200 |
offset |
целое | 0 | сколько артикулов пропустить. Вместе с after_id не передаётся |
after_id |
целое | нет | артикулы с номером больше указанного |
sku |
строка | нет | артикул с таким кодом, точное совпадение |
barcode |
строка | нет | артикул с таким штрихкодом, точное совпадение |
product_id |
целое | нет | артикулы одного товара |
updated_since |
дата и время ISO 8601 | нет | только артикулы, изменённые начиная с этого момента. Изменением считается правка самого артикула или его перевода, движение остатка, смена склада, на котором он лежит, новая цена из-за акции, курса, валюты витрины или правки в дополнении «Оптовые цены» и переключение настройки «Разрешить заказ, когда товара нет». Сюда же попадают артикулы товаров, которые изменились сами, например после правки характеристик или фото, потому что от товара зависят опции и фото артикула. Подробно в разделе «Изменения: updated_since» |
Ошибки те же, что у /products: неизвестный параметр, product_id не целое
положительное число, sku или barcode списком, неверный updated_since,
after_id или limit.
curl "https://shop.example.ua/api/v1/skus?barcode=4820000730601" \
-H "Authorization: Bearer <ключ>"
{
"data": [
{
"id": 2108,
"product_id": 1045,
"sku": "730601",
"barcode": "4820000730601",
"name": { "ru": "холодный белый", "uk": "холодне біле" },
"is_default": true,
"is_available": true,
"qty_min": "1.000",
"qty_step": "1.000",
"options": [{ "feature_id": 616, "value_id": 2428 }],
"features": [
{
"id": 616,
"code": "light",
"name": "Свет",
"value": "холодный белый",
"unit": null,
"values": [{ "id": 2428, "label": "холодный белый", "color": null }]
}
],
"image": "https://shop.example.ua/storage/products/1045/711/g9-cold.jpg",
"price": { "price": "208.32", "compare_price": "320.00", "discount_percent": 35, "currency": "UAH", "tiers": [] },
"stock": { "available": "12.000", "in_stock": true, "preorder": false }
}
],
"meta": { "total": 1, "limit": 50, "offset": 0 },
"links": { "next": null, "prev": null }
}
Поля те же, что у артикула в товаре, и ещё product_id —
номер товара, которому принадлежит артикул. Блоки price и stock приходят
по тем же правам. В примере остатки у ключа настроены «Одной суммой», поэтому
в stock нет разбивки по складам.
Описание товара
Описание пишут в редакторе магазина, а вы вставляете его в страницу своего сайта. Поэтому магазин отдаёт его в безопасном виде и вычищает всё, что может выполниться на вашей странице. Вид описания для ключа выбирает владелец магазина в настройке «Описание товара»: «С разметкой» или «Только текст». По умолчанию описание приходит с разметкой.
Одна и та же настройка действует на description и summary. Язык, на
котором после очистки ничего не осталось, в объект не попадает.
С разметкой
В описании остаются только эти теги:
| Что | Теги |
|---|---|
| абзацы и разделители | p, br, hr, div, span, blockquote, pre, code |
| оформление текста | b, strong, i, em, u, s, sup, sub |
| заголовки | h2, h3, h4, h5, h6 |
| списки | ul, ol, li, dl, dt, dd |
| таблицы | table, caption, thead, tbody, tfoot, tr, th, td |
| ссылки | a |
| картинки | img |
У тегов остаются только такие свойства:
styleу любого тега из списка, если в нём нетexpression(),url(),javascript:,vbscript:,behavior:,-moz-bindingи@import. Иначеstyleубирается целиком;hrefиtitleуa;src,alt,title,widthиheightуimg;colspanиrowspanуthиtd.
Остальные свойства, в том числе class, id, target и все обработчики
вида onclick, убираются.
Адреса. Ссылка может вести на http, https, mailto и tel, а
картинка грузиться только по http и https. Адрес магазина без домена
(/storage/…, /delivery/) достраивается до полного адреса витрины, адрес
вида //cdn.example.com/… получает https:, ссылка на якорь #… остаётся
как есть. Любой другой адрес (javascript:, data:, относительный
photo.jpg) убирается, а картинка без адреса удаляется совсем.
Что заменяется. Заголовок h1 становится h2, чтобы на вашей странице
остался один главный заголовок. Блоки section, article, header,
footer, main, aside, nav, figure, figcaption, address,
center, details и summary становятся div, чтобы текст из соседних
блоков не слипался.
Что удаляется вместе с содержимым. script, style, iframe, frame,
frameset, object, embed, applet, noscript, template, svg,
math, input, button, select, textarea, option, title, head,
link, meta, base, комментарии и вставки, которые понимает только витрина
магазина (блоки шаблона). Видео, встроенное через iframe, тоже пропадает.
Что раскрывается. Остальные теги, например font, form или label,
убираются, а текст внутри них остаётся.
Пусть в магазине записано такое описание:
<h1>Лампа G9</h1>
<p class="lead" style="color:#333">Светодиодная лампа <b>10 Вт</b> для люстр.</p>
<ul><li>Цоколь G9</li><li>Свет: тёплый</li></ul>
<table><tr><th>Мощность</th><td>10 Вт</td></tr><tr><th>Ресурс</th><td>25 000 ч</td></tr></table>
<p><img src="/storage/products/1045/710/g9.jpg" alt="Лампа" onerror="x()"> <a href="/delivery/" target="_blank">Доставка</a><br>Гарантия 2 года</p>
<iframe src="https://youtube.com/embed/x"></iframe>
<font color="red">Акция</font>
С разметкой оно придёт так (переносы строк добавлены для чтения):
<h2>Лампа G9</h2>
<p style="color:#333">Светодиодная лампа <b>10 Вт</b> для люстр.</p>
<ul><li>Цоколь G9</li><li>Свет: тёплый</li></ul>
<table><tr><th>Мощность</th><td>10 Вт</td></tr><tr><th>Ресурс</th><td>25 000 ч</td></tr></table>
<p><img src="https://shop.example.ua/storage/products/1045/710/g9.jpg" alt="Лампа"> <a href="https://shop.example.ua/delivery/">Доставка</a><br>Гарантия 2 года</p>
Акция
Только текст
Если ваш сайт разметку не принимает, владелец выбирает «Только текст». Тогда
описание приходит обычным текстом с переносами строк \n:
- абзацы, заголовки, списки и таблицы отделены друг от друга пустой строкой;
- каждый пункт списка начинается с новой строки и знака «• »;
- ячейки строки таблицы разделены « | »;
- перенос строки
brостаётся переносом, а внутриpreпереносы сохраняются как были; - термины и подписи (
dt,dd,caption,figcaption,summary) стоят каждый на своей строке; - спецсимволы раскодированы: вместо
&приходит&, вместо пробел; - лишние пробелы схлопнуты, пустых строк подряд не больше одной;
- картинки пропадают, от ссылки остаётся только её текст;
- скрипты, стили, встроенные окна и вставки шаблона вырезаются вместе с содержимым, как и в разметке.
То же описание в виде текста:
Лампа G9
Светодиодная лампа 10 Вт для люстр.
• Цоколь G9
• Свет: тёплый
Мощность | 10 Вт
Ресурс | 25 000 ч
Доставка
Гарантия 2 года
Акция
В JSON это одна строка: "Лампа G9\n\nСветодиодная лампа 10 Вт для люстр.\n\n• Цоколь G9\n• Свет: тёплый\n\n…".
Краткое описание
Краткое описание summary в магазине обычно пишут простым текстом. С
разметкой такой текст приходит экранированным: «Размер S<M & L» придёт как
Размер S<M & L, и его можно вставлять в страницу как есть. В виде
«Только текст» он придёт без изменений: Размер S<M & L. Если в кратком
описании всё-таки есть разметка (так бывает после переезда с другой
платформы), она очищается так же, как описание.