Товары
Через API можно создавать товары, управлять их вариантами, ценами и остатками, добавлять изображения и дополнительные поля. В этой статье также описаны привязка товаров к коллекциям, опции покупки и комплекты.
Список
GET /admin/products.json возвращает массив товаров. Чтобы узнать количество товаров с теми же фильтрами, используйте GET /admin/products/count.json.
Параметр per_page задаёт количество товаров на странице. Если передать значение меньше 10, API использует 10. Номер страницы задаётся параметром page.
| Параметр | Описание |
|---|---|
per_page необязательныйчисло |
Количество товаров на странице. При значении меньше 10 API использует 10. |
page необязательныйчисло |
Номер страницы списка товаров. |
filter[title] необязательныйстрока |
Фильтрация товаров по названию. |
deleted необязательныйстрока |
true — только архивные товары. |
with_deleted необязательныйстрока |
true — текущие и архивные товары. |
GET /admin/products/count.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
{"count": 37}
Для поиска по названию передайте filter[title]. В примере запрашивается первый товар, соответствующий фильтру.
| Параметр | Описание |
|---|---|
per_page необязательныйчисло |
Количество товаров на странице. При значении меньше 10 API использует 10. |
page необязательныйчисло |
Номер страницы. |
filter[title] необязательныйстрока |
Часть названия. |
GET /admin/products.json?per_page=10&filter[title]=iPhone
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
[
{
"id": 673,
"title": "Apple iPhone 16 Pro Max 1 ТБ",
"permalink": "apple-iphone-16-pro-max-1-tb"
}
]
Чтобы получить несколько товаров по идентификаторам, передайте их в product_ids. Один запрос принимает не более 100 идентификаторов.
| Параметр | Описание |
|---|---|
product_ids обязательныйстрока |
id товаров через запятую, не больше 100. |
GET /admin/products/by_ids.json?product_ids=561,569
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
[
{"id": 561, "title": "товар 1"},
{"id": 569, "title": "товар 2"}
]
GET /admin/products/999999999.json отвечает 404. Тело при заголовке Accept: application/json остаётся HTML-страницей.
Скрытые товары (is_hidden: true) входят в список. Архивные товары по умолчанию не возвращаются. Для их получения используйте deleted или with_deleted, как описано в разделе «Удаление и архив».
Создание
Для создания товара достаточно передать название и один вариант с ценой. InSales формирует адрес товара (permalink) из названия. Описание сохраняется в виде переданного HTML.
| Параметр | Описание |
|---|---|
product[title] обязательныйстрока |
Название. Из него строится permalink. |
product[description] необязательныйстрока |
Описание, сохраняется как переданный HTML. |
product[short_description] необязательныйстрока |
Короткое описание. |
product[variants_attributes][][price] обязательныйчисло |
Цена первого варианта. |
product[variants_attributes][][sku] необязательныйстрока |
Артикул варианта. |
product[variants_attributes][][barcode] необязательныйстрока |
Штрихкод варианта. |
product[variants_attributes][][quantity] необязательныйчисло |
Остаток варианта. |
POST /admin/products.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"title": "docs-api-простой",
"description": "<p>Короткое описание для примера</p>",
"short_description": "Коротко",
"variants_attributes": [
{
"price": 1500,
"sku": "DOCS-SIMPLE",
"barcode": "4600000000017",
"quantity": 3
}
]
}
}
Ответ · 201
{
"id": 913,
"title": "docs-api-простой",
"permalink": "docs-api-prostoy",
"is_hidden": false,
"archived": false,
"category_id": 1,
"collections_ids": [],
"description": "<p>Короткое описание для примера</p>",
"short_description": "Коротко",
"variants": [
{
"id": 2176487279,
"sku": "DOCS-SIMPLE",
"barcode": "4600000000017",
"price": "1500.0",
"quantity": 3,
"quantity_at_warehouse0": "3.0"
}
]
}
Поле category_id задаёт категорию учёта. Если его не передать, магазин выберет категорию автоматически. Идентификатор коллекции витрины для этого поля не подходит: API вернёт 422 и {"category_id":["Категория удалена или отсутствует."]}. Чтобы добавить товар в коллекцию, используйте отдельный запрос из следующего раздела.
Если отправить запрос на запись без Content-Type: application/json, API вернёт 422:
{"message": "incorrect Content-Type, should be application/json"}
Коллекция
Чтобы добавить товар в коллекцию, отправьте POST /admin/collects.json. Если коллекция дочерняя, в collections_ids карточки товара появятся и её идентификатор, и идентификатор родительской коллекции.
Поле position у привязки задаёт положение товара при ручной сортировке в коллекции.
| Параметр | Описание |
|---|---|
collect[product_id] обязательныйчисло |
id товара. |
collect[collection_id] обязательныйчисло |
id коллекции. |
collect[position] необязательныйчисло |
Порядок товара в коллекции. |
POST /admin/collects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"collect": {
"product_id": 913,
"collection_id": 53486014,
"position": 1
}
}
Ответ · 201
{
"id": 11029225261,
"collection_id": 53486014,
"product_id": 913,
"position": 1
}
| Параметр | Описание |
|---|---|
collect[position] обязательныйчисло |
Новый порядок товара в коллекции. |
PUT /admin/collects/11029225261.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"collect": {
"position": 5
}
}
Ответ · 200
{
"id": 11029225261,
"collection_id": 53486014,
"product_id": 913,
"position": 5
}
Скрытие
is_hidden: true убирает товар с витрины и оставляет его в GET /admin/products.json.
| Параметр | Описание |
|---|---|
product[is_hidden] обязательныйлогический |
true скрывает товар с витрины, сохраняя его в списке API. false возвращает товар на витрину. |
PUT /admin/products/913.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"is_hidden": true
}
}
Ответ · 200
{
"id": 913,
"title": "docs-api-простой",
"is_hidden": true,
"archived": false
}
Чтобы снова показать товар на витрине, отправьте тот же запрос с "is_hidden": false.
Удаление и архив
DELETE /admin/products/:id.json переносит товар в архив и возвращает {"status":"ok"}. После этого чтение карточки без архивных флагов возвращает 404 с HTML-страницей.
Если товара с указанным идентификатором нет, DELETE также возвращает 200 и {"status":"ok"}. По ответу на удаление нельзя определить, существовал ли товар.
По умолчанию список не содержит архивных товаров. С deleted=true API возвращает только архивные товары с archived: true. С with_deleted=true возвращаются и текущие, и архивные товары. Ниже показана одна запись из списка с deleted=true.
| Параметр | Описание |
|---|---|
deleted необязательныйстрока |
true возвращает только архивные товары с archived: true. |
with_deleted необязательныйстрока |
true возвращает текущие и архивные товары. |
per_page необязательныйчисло |
Размер страницы. |
GET /admin/products.json?deleted=true&per_page=250
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
[
{
"id": 977,
"title": "docs-api-архив",
"archived": true
}
]
Дополнительное поле товара
Пустой массив product_field_values означает, что у товара нет значений дополнительных полей. Сначала создайте само поле; для текстового поля передайте type: ProductField::TextField.
Затем запишите значение в товар через product_field_values_attributes. Оно будет возвращаться при чтении карточки товара.
| Параметр | Описание |
|---|---|
product_field[title] обязательныйстрока |
Название поля. |
product_field[handle] необязательныйстрока |
Системное имя. |
product_field[type] обязательныйстрока |
Тип поля. Для текста — ProductField::TextField. |
POST /admin/product_fields.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product_field": {
"title": "docs-api Комментарий",
"handle": "docs_api_comment",
"type": "ProductField::TextField"
}
}
Ответ · 201
{
"id": 4586434,
"handle": "docs_api_comment",
"type": "ProductField::TextField",
"title": "docs-api Комментарий"
}
| Параметр | Описание |
|---|---|
product[product_field_values_attributes][][product_field_id] обязательныйчисло |
id дополнительного поля. |
product[product_field_values_attributes][][value] обязательныйстрока |
Значение дополнительного поля. Если значений нет, в карточке возвращается пустой product_field_values. |
PUT /admin/products/985.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"product_field_values_attributes": [
{
"product_field_id": 4586434,
"value": "пример"
}
]
}
}
Ответ · 200
{
"id": 985,
"product_field_values": [
{"id": 895989818, "product_field_id": 4586434, "value": "пример"}
]
}
Параметры
Параметр описывает товар целиком, например его материал, состав или длину. В API параметр представлен свойством property и его значением characteristic. При создании или обновлении товара передайте название свойства и его значение в properties_attributes.
Размер и цвет, от которых зависят варианты товара, задаются свойствами вариантов. Гравировка или подарочная упаковка могут быть опциями покупки: у каждого значения такой опции есть своя цена.
Чтобы прочитать параметры товара, запросите GET /admin/products/:id.json. Массив properties содержит свойства, а characteristics — их значения. Поле property_id у значения указывает на id свойства. Название значения хранится в title.
Запись по названиям
Если свойства или значения с переданным названием ещё нет в магазине, API создаёт его. Несколько элементов properties_attributes с одинаковым title задают несколько значений одного свойства. В ответе будет одно свойство и несколько значений с одинаковым property_id.
| Параметр | Описание |
|---|---|
product[title] обязательныйстрока |
Название товара. |
product[variants_attributes][][price] обязательныйчисло |
Цена варианта. |
product[properties_attributes][][title] обязательныйстрока |
Название параметра. Повтор названия добавляет ещё одно значение. |
product[properties_attributes][][value] обязательныйстрока |
Значение параметра. |
POST /admin/products.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"title": "docs-api-параметры",
"variants_attributes": [
{
"price": 500,
"sku": "DOCS-PROP"
}
],
"properties_attributes": [
{
"title": "docs-api Материал",
"value": "Хлопок"
},
{
"title": "docs-api Состав",
"value": "90% хлопок"
},
{
"title": "docs-api Состав",
"value": "10% эластан"
}
]
}
}
Ответ · 201
{
"id": 929,
"title": "docs-api-параметры",
"properties": [
{"id": 61541236, "title": "docs-api Материал", "permalink": "docs-api-material"},
{"id": 61541237, "title": "docs-api Состав", "permalink": "docs-api-sostav"}
],
"characteristics": [
{"id": 785, "property_id": 61541236, "title": "Хлопок", "permalink": "hlopok"},
{"id": 793, "property_id": 61541237, "title": "90% хлопок", "permalink": "90-hlopok"},
{"id": 801, "property_id": 61541237, "title": "10% эластан", "permalink": "10-elastan"}
]
}
Полный список при обновлении
При обновлении properties_attributes заменяет весь набор параметров товара. Связи со значениями, которые не вошли в запрос, удаляются.
Чтобы добавить параметр и сохранить существующие, передайте в properties_attributes как прежние пары «свойство — значение», так и новую.
| Параметр | Описание |
|---|---|
product[properties_attributes][][title] обязательныйстрока |
Название параметра. Передавайте полный набор пар «свойство — значение», который должен остаться у товара. |
product[properties_attributes][][value] обязательныйстрока |
Значение параметра. |
PUT /admin/products/929.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"properties_attributes": [
{
"title": "docs-api Материал",
"value": "Лён"
}
]
}
}
Ответ · 200
{
"id": 929,
"properties": [
{"id": 61541236, "title": "docs-api Материал"}
],
"characteristics": [
{"id": 809, "property_id": 61541236, "title": "Лён", "permalink": "lyon"}
]
}
Если не передать properties_attributes, набор параметров товара не изменится.
Одна пара по id
Чтобы добавить одну пару по идентификаторам и сохранить существующие, используйте product_characteristics_attributes. Передайте property_id и characteristic_id.
| Параметр | Описание |
|---|---|
product[product_characteristics_attributes][][property_id] обязательныйчисло |
id параметра. |
product[product_characteristics_attributes][][characteristic_id] обязательныйчисло |
id значения. |
PUT /admin/products/929.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"product_characteristics_attributes": [
{
"property_id": 61541238,
"characteristic_id": 817
}
]
}
}
Ответ · 200
{
"characteristics": [
{"id": 785, "property_id": 61541236, "title": "Хлопок"},
{"id": 793, "property_id": 61541237, "title": "90% хлопок"},
{"id": 817, "property_id": 61541238, "title": "12.5"}
]
}
В characteristics поле id содержит идентификатор значения, а не связи с товаром. Чтобы убрать пару из товара, передайте полный properties_attributes без этой пары.
Числовой параметр
Для числового параметра создайте свойство отдельным запросом с "is_numeric": true. Поле is_numeric не возвращается ни при создании, ни в GET /admin/properties/:id.json; числовой режим можно определить по обработке значений.
Обработка числового значения зависит от способа записи. При сохранении товара через properties_attributes InSales извлекает число из строки: 12.5 см сохраняется как 12.5. При отдельном создании значения через POST /admin/properties/:id/characteristics.json передавайте число без единицы измерения: строка 40 см отклоняется со статусом 422 и телом {"title":["Указано не число"]}, а 40 принимается.
| Параметр | Описание |
|---|---|
property[title] обязательныйстрока |
Название параметра. |
property[is_numeric] необязательныйлогический |
true делает параметр числовым. |
POST /admin/properties.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"property": {
"title": "docs-api Ширина",
"is_numeric": true
}
}
Ответ · 201
{
"id": 61541239,
"title": "docs-api Ширина",
"permalink": "docs-api-shirina",
"position": 34,
"is_hidden": false,
"is_navigational": true
}
| Параметр | Описание |
|---|---|
characteristic[title] обязательныйстрока |
Название значения. |
POST /admin/properties/61541239/characteristics.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"characteristic": {
"title": "40 см"
}
}
Ответ · 422
{"title": ["Указано не число"]}
Список значений — GET /admin/properties/:id/characteristics.json. У значения есть id, property_id, title, permalink, position.
Свойства вариантов
Свойство варианта — справочник значений, например размеров или цветов. Чтобы назначить свойство товару, передайте title и value в product.options, как описано в разделе «Варианты». Поле option_name_id внутри variants_attributes в этом запросе не принимается.
GET /admin/option_names.json возвращает свойства без вложенных значений. Поле api_permalink состоит из префикса o- и значения permalink. Параметр sorting_type принимает manual или auto, но в ответе не возвращается.
POST /admin/option_names.json создаёт свойство и возвращает его объект со статусом 201. Вложенные option_values_attributes позволяют сразу создать значения, но в ответ они не включаются. Получите их отдельным GET-запросом.
| Параметр | Описание |
|---|---|
option_name[title] обязательныйстрока |
Название свойства. |
option_name[permalink] необязательныйстрока |
Адрес свойства. Пустое значение строится из названия. |
option_name[navigational] необязательныйлогический |
Навигационное свойство. |
option_name[position] необязательныйчисло |
Позиция свойства. |
option_name[sorting_type] необязательныйстрока |
manual или auto. Поле не возвращается в ответе. |
option_name[option_values_attributes] необязательныймассив |
Значения: title, position, id, _destroy. |
POST /admin/option_names.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"option_name": {
"title": "docs-api Посадка",
"navigational": false,
"sorting_type": "manual",
"option_values_attributes": [
{
"title": "свободная",
"position": 1
},
{
"title": "приталенная",
"position": 2
}
]
}
}
Ответ · 201
{
"id": 2517842,
"position": 4,
"navigational": false,
"permalink": "docs-api-posadka",
"title": "docs-api Посадка",
"api_permalink": "o-docs-api-posadka"
}
PUT /admin/option_names/:id.json изменяет название и navigational, затем возвращает объект свойства со статусом 200. При удалении DELETE /admin/option_names/:id.json возвращает {"status":"ok"}. Сразу после удаления свойство ещё может возвращаться при чтении.
Наличие товара с одним вариантом не блокирует удаление свойства: API возвращает {"status":"ok"}.
Значения
GET /admin/option_names/:option_name_id/option_values.json возвращает значения одного свойства. GET /admin/option_values.json возвращает значения магазина; чтобы ограничить их одним свойством, добавьте параметр URL option_name_id.
from_id оставляет значения с идентификатором больше переданного. Параметр limit ограничивает количество записей: при значении меньше 25 API использует 25, при значении больше 1000 — 1000. Если limit не передан, ограничение по этому параметру не применяется.
| Параметр | Описание |
|---|---|
option_name_id обязательныйчисло |
id свойства в пути. |
GET /admin/option_names/2517842/option_values.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
[
{
"id": 21063155,
"option_name_id": 2517842,
"position": 1,
"title": "свободная",
"image_url": null,
"permalink": "svobodnaya"
},
{
"id": 21063156,
"option_name_id": 2517842,
"position": 2,
"title": "приталенная",
"image_url": null,
"permalink": "pritalennaya"
}
]
POST /admin/option_names/:option_name_id/option_values.json создаёт значение со статусом 201. Чтобы добавить изображение, отправьте PUT с полем option_value.image.src. Поле image_url в ответе содержит адрес миниатюры.
| Параметр | Описание |
|---|---|
option_name_id обязательныйчисло |
id свойства. |
id обязательныйчисло |
id значения. |
option_value[image][src] обязательныйстрока |
Публичный адрес файла. |
PUT /admin/option_names/2517842/option_values/21063155.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"option_value": {
"image": {
"src": "https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png"
}
}
}
Ответ · 200
{
"id": 21063155,
"option_name_id": 2517842,
"position": 1,
"title": "свободная",
"image_url": "http://…/images/option_values/1/1523/21063155/thumb/1x1.png",
"permalink": "svobodnaya"
}
image_url — адрес миниатюры.
Удаление значения выполняется асинхронно. DELETE /admin/option_names/:option_name_id/option_values/:id.json сразу возвращает идентификатор и номер задачи. Для проверки состояния используйте GET /admin/option_names/:option_name_id/option_values/:id/destroy_status.json?jid=. Пока значение удаляется, ответ содержит {"status":"wait"}, после удаления — {"status":"ok"}.
| Параметр | Описание |
|---|---|
option_name_id обязательныйчисло |
id свойства. |
id обязательныйчисло |
id значения. |
DELETE /admin/option_names/2517842/option_values/21063157.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
{
"id": 21063157,
"jid": 88
}
Варианты
Вариант — это сочетание значений свойств вроде размера и цвета, со своей ценой, остатком, артикулом и штрихкодом. Справочник свойств (option_name) — в свойствах вариантов. Параметр карточки (property) из раздела «Параметры» — другой справочник. Цена и остаток меняются у варианта, отдельного поля цены у товара в этих запросах нет.
У товара всегда остаётся хотя бы один вариант.
Товар с одним свойством
При создании options задаёт свойство и значение первого варианта. У варианта в ответе появляется option_values.
| Параметр | Описание |
|---|---|
product[title] обязательныйстрока |
Название товара. |
product[options][][title] обязательныйстрока |
Название свойства, например размера. |
product[options][][value] обязательныйстрока |
Значение свойства первого варианта. |
product[variants_attributes][][price] обязательныйчисло |
Цена варианта. |
product[variants_attributes][][sku] необязательныйстрока |
Артикул. |
product[variants_attributes][][barcode] необязательныйстрока |
Штрихкод. |
POST /admin/products.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"title": "docs-api-размер",
"options": [
{
"title": "docs-api Размер",
"value": "M"
}
],
"variants_attributes": [
{
"sku": "DOCS-M",
"price": 1000,
"barcode": "4600000000109"
}
]
}
}
Ответ · 201
{
"id": 945,
"title": "docs-api-размер",
"option_names": [
{"id": 2517858, "title": "docs-api Размер", "permalink": "docs-api-razmer"}
],
"variants": [
{
"id": 2176487283,
"title": "M",
"sku": "DOCS-M",
"barcode": "4600000000109",
"price": "1000.0",
"option_values": [
{"id": 21063206, "option_name_id": 2517858, "title": "M"}
]
}
]
}
Чтобы добавить вариант с другим значением того же свойства, создайте отдельный вариант. Возьмите option_name_id из массива option_names товара.
| Параметр | Описание |
|---|---|
variant[price] обязательныйчисло |
Цена нового варианта. |
variant[sku] необязательныйстрока |
Артикул. |
variant[barcode] необязательныйстрока |
Штрихкод. |
variant[options][][option_name_id] обязательныйчисло |
id уже существующего свойства. |
variant[options][][value] обязательныйстрока |
Новое значение этого свойства. |
POST /admin/products/945/variants.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"sku": "DOCS-L",
"price": 1200,
"barcode": "4600000000116",
"options": [
{
"option_name_id": 2517858,
"title": "docs-api Размер",
"value": "L"
}
]
}
}
Ответ · 201
{
"id": 2176487284,
"title": "L",
"sku": "DOCS-L",
"price": "1200.0",
"option_values": [
{"id": 21063207, "option_name_id": 2517858, "title": "L"}
]
}
Повтор того же значения отвечает 422. У создания варианта ошибки обёрнуты в status и errors:
{"status": "error", "errors": {"options": ["Вариант с такими значениями свойств уже существует"]}}
Новое свойство
Вариант не создаётся, если в options передано свойство, которого у товара ещё нет. Ответ 422: список свойств изменился.
| Параметр | Описание |
|---|---|
variant[price] обязательныйчисло |
Цена варианта. |
variant[sku] необязательныйстрока |
Артикул. |
variant[options][][title] обязательныйстрока |
Название свойства, которого у товара ещё нет. |
variant[options][][value] обязательныйстрока |
Значение этого свойства. |
POST /admin/products/945/variants.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"sku": "DOCS-COLOR",
"price": 1100,
"options": [
{
"title": "docs-api Цвет",
"value": "Чёрный"
}
]
}
}
Ответ · 422
{
"status": "error",
"errors": {
"options": ["Список свойств у товара изменился, перезагрузите страницу"]
}
}
Сначала добавьте свойство запросом на обновление товара. Для существующего свойства передайте option_name_id, для нового — title и value. Значение value будет назначено всем текущим вариантам товара. Если вместо него передать список values без значения по умолчанию в value, API вернёт 422.
| Параметр | Описание |
|---|---|
product[options][][option_name_id] необязательныйчисло |
id уже существующего свойства, которое нужно оставить. |
product[options][][title] необязательныйстрока |
Название добавляемого свойства. |
product[options][][value] необязательныйстрока |
Значение добавляемого свойства. Оно проставляется текущим вариантам. |
PUT /admin/products/985.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"options": [
{
"option_name_id": 2517859
},
{
"title": "docs-api Цвет",
"value": "Чёрный"
}
]
}
}
Ответ · 200
{
"id": 985,
"option_names": [
{"id": 2517859, "title": "docs-api Размер"},
{"id": 2517860, "title": "docs-api Цвет"}
],
"variants": [
{
"id": 2176487289,
"title": "Чёрный / M",
"sku": "DOCS-M2",
"option_values": [
{"option_name_id": 2517860, "title": "Чёрный"},
{"option_name_id": 2517859, "title": "M"}
]
}
]
}
При создании следующего варианта передайте значения всех свойств товара. Если указать только одно из двух свойств, API вернёт ту же ошибку об изменении списка свойств. При обновлении варианта ошибки возвращаются без обёртки status: {"options":["Список свойств у товара изменился, перезагрузите страницу"]}.
| Параметр | Описание |
|---|---|
variant[price] обязательныйчисло |
Цена варианта. |
variant[sku] необязательныйстрока |
Артикул. |
variant[options][][option_name_id] обязательныйчисло |
id свойства. |
variant[options][][value] обязательныйстрока |
Значение этого свойства. |
POST /admin/products/985/variants.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"sku": "DOCS-WHITE",
"price": 1300,
"options": [
{
"option_name_id": 2517859,
"value": "M"
},
{
"option_name_id": 2517860,
"value": "Белый"
}
]
}
}
Ответ · 201
{
"id": 2176487290,
"title": "M / Белый",
"sku": "DOCS-WHITE",
"price": "1300.0",
"option_values": [
{"option_name_id": 2517859, "title": "M"},
{"option_name_id": 2517860, "title": "Белый"}
]
}
Цена, артикул, вес, габариты
PUT /admin/products/:product_id/variants/:id.json меняет цену, старую цену, артикул, штрихкод, вес и габариты одного варианта. Свойства варианта в этом запросе передавать не нужно. Дополнительные цены — в типах цен.
Чтобы установить одинаковую цену для всех вариантов, отправьте этот запрос для каждого идентификатора из variants.
| Параметр | Описание |
|---|---|
variant[price] необязательныйчисло |
Цена. |
variant[old_price] необязательныйчисло |
Старая цена. |
variant[sku] необязательныйстрока |
Артикул. |
variant[barcode] необязательныйстрока |
Штрихкод. |
variant[weight] необязательныйчисло |
Вес. |
variant[dimensions] необязательныйстрока |
Габариты. |
PUT /admin/products/913/variants/2176487279.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"price": 1800,
"old_price": 2100,
"sku": "DOCS-SIMPLE-2",
"barcode": "4600000000018",
"weight": 0.35,
"dimensions": "10х20х5"
}
}
Ответ · 200
{
"id": 2176487279,
"sku": "DOCS-SIMPLE-2",
"barcode": "4600000000018",
"price": "1800.0",
"old_price": "2100.0",
"weight": "0.35",
"dimensions": "10x20x5",
"quantity": 3,
"quantity_at_warehouse0": "3.0"
}
Вес в ответе — строка, например "0.35". Русская буква «х» в габаритах сохраняется как латинская x: 10х20х5 становится 10x20x5.
Внешний идентификатор
external_id — идентификатор варианта во внешней системе. Его пишут в уже созданный вариант запросом PUT /admin/products/:product_id/variants/:id.json.
При создании товара данные вариантов передаются в variants_attributes: цена, артикул, остаток, вес и габариты. Поле external_id в этом вложенном объекте не поддерживается. Если передать его при создании товара, API вернёт 422 и укажет недопустимый ключ:
{"variants_attributes": ["undefined keys [\"external_id\"]"]}
Обновление варианта с "external_id": "1c-200" возвращает 200. Значение сохраняется у варианта, но не включается в его JSON-ответ.
Остаток
quantity — остаток варианта. Остаток на складе передаётся полем quantity_at_warehouseN. Число N — это array_index склада из GET /admin/warehouses.json. У единственного склада индекс 0, поле называется quantity_at_warehouse0.
Если в магазине один склад, quantity и quantity_at_warehouse0 описывают один остаток: изменение любого из этих полей меняет оба. Остаток склада возвращается строкой, например "7.0". Работа с несколькими складами и суммарным остатком описана в разделе «Склады».
Групповое обновление
PUT /admin/products/variants_group_update.json меняет цены и остатки сразу у нескольких вариантов. В теле — массив variants, у каждого элемента обязателен id:
{"variants": [{"id": 2176487279, "price": 1900}]}
API сразу возвращает 200 с пустым массивом []. Изменения применяются не сразу. Чтобы проверить новые цены и остатки, повторно запросите варианты после завершения обновления.
Удаление варианта
Последний вариант удалить нельзя.
| Параметр | Описание |
|---|---|
id обязательныйчисло |
id варианта в пути. Последний вариант товара удалить нельзя. |
DELETE /admin/products/953/variants/2176487285.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 422
{"base": ["Нельзя удалить последний вариант"]}
Если вариантов больше одного, DELETE /admin/products/945/variants/2176487284.json отвечает 200 и {"status":"ok"}.
Дополнительное поле варианта
Создайте поле с типом VariantField::TextField, затем запишите его значение в вариант. При чтении варианта значение возвращается в variant_field_values.
| Параметр | Описание |
|---|---|
variant_field[title] обязательныйстрока |
Название поля. |
variant_field[handle] необязательныйстрока |
Системное имя. |
variant_field[type] обязательныйстрока |
Тип поля. VariantField::TextField — текст. |
POST /admin/variant_fields.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant_field": {
"title": "docs-api Примечание",
"handle": "docs_api_note",
"type": "VariantField::TextField"
}
}
Ответ · 201
{
"id": 1,
"handle": "docs_api_note",
"type": "VariantField::TextField",
"title": "docs-api Примечание"
}
| Параметр | Описание |
|---|---|
variant[variant_field_values_attributes][][variant_field_id] обязательныйчисло |
id дополнительного поля варианта. |
variant[variant_field_values_attributes][][value] обязательныйстрока |
Значение поля. |
PUT /admin/products/945/variants/2176487283.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"variant_field_values_attributes": [
{
"variant_field_id": 1,
"value": "метка"
}
]
}
}
Ответ · 200
{
"id": 2176487283,
"variant_field_values": [
{"id": 1, "variant_field_id": 1, "value": "метка"}
]
}
Типы цен
Тип цены позволяет хранить у варианта дополнительную цену. Методы доступны, если эта возможность входит в тариф магазина. На обычном тарифе можно создать не более 20 типов цен.
POST /admin/price_kinds.json отвечает 201. price_index начинается с 1. variant_price_method_name для первого типа — price2: в варианте это поле price2. Следующий тип получает следующий индекс и поле price3. Повтор названия отвечает 422:
{"title":["уже существует"]}
PUT /admin/price_kinds/:id.json меняет title и show_in_lists.
| Параметр | Описание |
|---|---|
price_kind[title] обязательныйстрока |
Название типа цены. Уникально в магазине. |
price_kind[show_in_lists] необязательныйлогический |
Показывать цену в списках. |
POST /admin/price_kinds.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"price_kind": {
"title": "docs-api Опт",
"show_in_lists": false
}
}
Ответ · 201
{
"id": 1,
"price_index": 1,
"title": "docs-api Опт",
"show_in_lists": false,
"variant_price_method_name": "price2"
}
Для записи дополнительной цены передайте в вариант поле, указанное в variant_price_method_name. Базовая цена price возвращается строкой, дополнительная — числом. Массив prices содержит дополнительные цены в порядке типов.
| Параметр | Описание |
|---|---|
product_id обязательныйчисло |
id товара. |
id обязательныйчисло |
id варианта. |
variant[price2] обязательныйчисло |
Цена типа с variant_price_method_name price2. |
PUT /admin/products/673/variants/2176487181.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"price2": 77.5
}
}
Ответ · 200
{
"id": 2176487181,
"product_id": 673,
"price": "10.0",
"price2": 77.5,
"prices": [77.5]
}
DELETE /admin/price_kinds/:id.json возвращает {"status":"ok"}. После удаления первого типа цены в ответе варианта отсутствует ключ price2, а соответствующий элемент массива prices равен null.
Единицы измерения
Список можно прочитать, если у приложения есть право на настройки магазина.
GET /admin/units.json без lang отвечает 422. Тело — строка, не JSON-объект: Отсутствует параметр lang, либо данный язык недоступен на платформе. Заголовок при этом Content-Type: application/json. То же тело у lang=xx.
lang=ru и lang=en отвечают 200. Ключ — код единицы, значение — короткая подпись. Этот код приходит в строке заказа как unit, например pce. Создать свою единицу этим ресурсом нельзя: у него есть только список.
| Параметр | Описание |
|---|---|
lang обязательныйстрока |
Язык подписей. ru или en. |
GET /admin/units.json?lang=ru
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
{
"mmt": "мм",
"cmt": "см",
"dmt": "дм",
"mtr": "м",
"kmt": "км",
"inh": "дюйм",
"fot": "фут",
"yrd": "ярд",
"mtk": "м2",
"dmk": "дм2",
"mlt": "мл",
"cmq": "см3",
"ltr": "л",
"dmq": "дм3",
"mtq": "м3",
"mgm": "мг",
"grm": "г",
"kgm": "кг",
"tne": "т",
"hur": "ч",
"nbb": "боб",
"lef": "л.",
"set": "набор",
"npr": "пар",
"npl": "рул",
"nmp": "упак",
"dzp": "дюжина упак",
"cnp": "100 упак",
"pce": "шт",
"cen": "100 шт",
"mil": "тыс. шт",
"box": "ящ",
"sct": "секц",
"btl": "флак",
"lmt": "пог. м",
"com": "компл",
"pct": "кор",
"day": "сут",
"mth": "мес"
}
Изображения
Чтобы добавить изображение к товару, используйте POST /admin/products/:product_id/images.json. Пока InSales обрабатывает файл, image_processing равен true, а URL изображений указывают на /images/loading.gif. Имя файла в ответе уже соответствует загруженному файлу.
Адрес изображения
src — публичный адрес файла. Магазин скачивает изображение по этому адресу, поэтому адрес должен открываться из интернета. Если файл по адресу скачать нельзя, ответ 422:
{"image": ["Не заполнены обязательные поля"], "src": ["Недопустимый URL"]}
| Параметр | Описание |
|---|---|
image[src] обязательныйстрока |
Адрес изображения в интернете. |
POST /admin/products/985/images.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"image": {
"src": "https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png"
}
}
Ответ · 201
{
"id": 377,
"product_id": 985,
"position": 1,
"image_processing": true,
"filename": "1x1.png",
"url": "/images/loading.gif",
"original_url": "/images/loading.gif"
}
Файл в теле
Для загрузки файла передайте его содержимое в Base64 в поле attachment, а имя — в filename. Используйте тот же POST /admin/products/:product_id/images.json. Пока файл обрабатывается, image_processing равен true, а URL изображений указывают на /images/loading.gif.
| Параметр | Описание |
|---|---|
image[filename] обязательныйстрока |
Имя файла. |
image[attachment] обязательныйстрока |
Содержимое файла в кодировке base64. |
POST /admin/products/913/images.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"image": {
"filename": "docs-api.png",
"attachment": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
}
}
Ответ · 201
{
"id": 369,
"product_id": 913,
"position": 1,
"image_processing": true,
"filename": "docs-api.png",
"original_url": "/images/loading.gif"
}
Привязка к варианту и порядок
Чтобы связать изображение с вариантом, передайте image_id при обновлении варианта. В ответе изображение будет указано и в image_id, и в image_ids. Подпись и положение изображения меняются отдельным запросом к изображению.
| Параметр | Описание |
|---|---|
variant[image_id] обязательныйчисло |
id изображения, которую нужно привязать к варианту. |
PUT /admin/products/913/variants/2176487279.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"variant": {
"image_id": 369
}
}
Ответ · 200
{
"id": 2176487279,
"image_id": 369,
"image_ids": [369]
}
| Параметр | Описание |
|---|---|
image[position] необязательныйчисло |
Порядок изображения. |
image[title] необязательныйстрока |
Подпись. |
PUT /admin/products/913/images/369.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"image": {
"position": 1,
"title": "docs-api"
}
}
Ответ · 200
{
"id": 369,
"product_id": 913,
"position": 1,
"title": "docs-api",
"filename": "docs-api.png",
"image_processing": true
}
Аналоги
Чтобы назначить аналоги, передайте массив идентификаторов других товаров. При сохранении API возвращает {"status":"ok"}. При чтении списка возвращаются идентификаторы назначенных товаров.
| Параметр | Описание |
|---|---|
similar_ids обязательныймассив |
id аналогичных товаров. |
POST /admin/products/913/similars.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"similar_ids": [
961
]
}
Ответ · 200
{"status": "ok"}
GET /admin/products/913/similars.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Ответ · 200
[{"id": 961}]
Сопутствующие
Чтобы назначить сопутствующие товары, отправьте запрос на /admin/products/:id/supplementaries.json с массивом supplementary_ids. При сохранении API возвращает {"status":"ok"}. Список сопутствующих товаров возвращается массивом объектов с полем id.
Опция покупки
Опция покупки (аксессуар) — отдельный объект магазина, например гравировка или подарочная упаковка. У неё есть набор значений, каждое со своей ценой; покупатель выбирает значение при покупке. Опция связывается с товаром через product_accessory_link.
Размер и другие свойства вариантов описаны в разделе «Варианты». Характеристики товара целиком описаны в разделе «Параметры».
| Параметр | Описание |
|---|---|
accessory[name] обязательныйстрока |
Название опции покупки. |
accessory[permalink] необязательныйстрока |
Адрес опции. |
accessory[min_count] необязательныйчисло |
Минимум выбранных значений. |
accessory[max_count] необязательныйчисло |
Максимум выбранных значений. |
POST /admin/accessories.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"accessory": {
"name": "docs-api Гравировка",
"permalink": "docs-api-gravirovka",
"min_count": 0,
"max_count": 1
}
}
Ответ · 201
{
"id": 2,
"name": "docs-api Гравировка",
"permalink": "docs-api-gravirovka",
"min_count": 0,
"max_count": 1
}
| Параметр | Описание |
|---|---|
accessory_value[name] обязательныйстрока |
Название значения. |
accessory_value[price] необязательныйчисло |
Добавка к цене. |
POST /admin/accessories/2/values.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"accessory_value": {
"name": "Имя",
"price": 300
}
}
Ответ · 201
{
"id": 3,
"accessory_id": 2,
"name": "Имя",
"price": "300.0"
}
| Параметр | Описание |
|---|---|
product_accessory_link[accessory_id] обязательныйчисло |
id опции, которую нужно привязать к товару. |
POST /admin/products/913/product_accessory_links.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product_accessory_link": {
"accessory_id": 2
}
}
Ответ · 201
{
"id": 2,
"accessory_id": 2,
"product_id": 913
}
В карточке товара ссылка приходит так: "product_accessory_links": [{"id": 2, "accessory_id": 2}].
Комплект
Чтобы создать комплект, передайте при создании товара "bundle": true и состав в product_bundle_components_attributes. Для каждой составляющей укажите variant_id другого товара и количество. Цену комплекта задайте в его собственном варианте через variants_attributes.
| Параметр | Описание |
|---|---|
product[title] обязательныйстрока |
Название комплекта. |
product[bundle] обязательныйлогический |
true помечает товар как комплект. |
product[variants_attributes][][price] обязательныйчисло |
Цена комплекта. |
product[product_bundle_components_attributes][][variant_id] обязательныйчисло |
id варианта в составе. |
product[product_bundle_components_attributes][][quantity] обязательныйчисло |
Сколько штук этого варианта входит в комплект. |
POST /admin/products.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"product": {
"title": "docs-api-комплект",
"bundle": true,
"variants_attributes": [
{
"price": 40
}
],
"product_bundle_components_attributes": [
{
"variant_id": 2176487279,
"quantity": 1
},
{
"variant_id": 2176487286,
"quantity": 1
}
]
}
}
Ответ · 201
{
"id": 969,
"title": "docs-api-комплект",
"bundle": true,
"product_bundle_components": [
{"id": 2, "variant_id": 2176487279, "quantity": "1.0", "product_id": 913, "free": false},
{"id": 3, "variant_id": 2176487286, "quantity": "1.0", "product_id": 961, "free": false}
],
"variants": [
{"id": 2176487287, "price": "40.0"}
]
}
Признак bundle можно задать только при создании товара. Если обновить обычный товар, передав "bundle": true и состав комплекта, API вернёт 200, но товар не станет комплектом. В ответе bundle будет равен null, а product_bundle_components — пустому массиву.