Выгрузки товаров
Выгрузки можно читать и менять, если у приложения есть право на маркетплейсы.
Если этого права нет, ответ 403:
{"status":"error","message":"Недостаточно прав для операции"}
Выгрузки товаров
/admin/marketplaces — файл товаров для внешней площадки. Каталог приложений к этому адресу не относится. id в пути — число. GET /admin/marketplaces/abc.json — страница 404 витрины.
Поле url — адрес файла без Basic. Content-Type XML-файла — application/xml; charset=utf-8. Ссылки внутри файла используют хост, с которого файл запрошен. Если запрошенный язык в магазине не включён, ?lang= возвращает тот же файл. ?download=1 при сборке файла на лету заголовок скачивания не ставит.
GET /admin/marketplaces.json отдаёт массив. Набор полей зависит от type. collection_ids в ответе 201 может быть [], хотя идентификаторы сохранены: следующий GET их показывает.
В файл попадают товары выбранных коллекций. Пустой список коллекций и пустая коллекция дают файл без товаров. Архивный товар из файла пропадает. Товар вне выбранных коллекций в файл не входит.
Смена type у существующей записи запросом PATCH отвечает HTML 404, и тип в записи уже другой. Новую площадку создают отдельным POST.
DELETE /admin/marketplaces/ID.json отвечает 200, тело {"status":"ok"}.
Какие типы создаются одним названием
Тело с name и type. Неизвестная строка типа отвечает 422, тело {"type":["Тип является обязательным полем"]}. Тело только с name, без type, отвечает 500 и HTML-страницей. Повтор name в магазине отвечает 422, тело {"name":["Выгрузка с таким названием уже существует"]}. Пустое название отвечает 422, тело {"name":["Не указано название выгрузки"]}.
| type | Ответ на name и type |
|---|---|
Marketplace::GoogleMerchant |
201, файл .xml |
Marketplace::ExcelPrices |
201, url заканчивается на .xls |
Marketplace::LiquidYandexMarket |
201, в ответе шаблон offer_liquid по умолчанию |
Marketplace::ModelYandexMarket |
422: пустые shop_name, shop_company, vendor_id |
Marketplace::YandexMarket |
422: пустые shop_name, shop_company |
Marketplace::Sbermegamarket |
422: пустые shop_name, shop_company |
Marketplace::CartsLiquidYandexMarket |
422: touched_carts_days_ago должен быть от 0 до 30 |
Marketplace::Avito |
422: пустые address и category_id, плюс непринятые listing_fee, ad_status, condition_type |
Google Merchant
Достаточно названия и типа. description_type принимает 1 и 2. adult, utm_label, local_delivery_cost и collection_ids сохраняются и возвращаются. Отрицательная стоимость доставки отвечает 422, тело {"local_delivery_cost":["Стоимость доставки должна быть неотрицательным числом, например 300"]}.
brand принимается и влияет на файл, в JSON записи его нет. not_load_not_available, show_hidden и layout_template в JSON тоже не возвращаются.
| Параметр | Описание |
|---|---|
name обязательныйстрока |
Название выгрузки, уникальное в магазине. |
type обязательныйстрока |
Marketplace::GoogleMerchant. |
POST /admin/marketplaces.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"marketplace": {
"name": "docs-min-GoogleMerchant",
"type": "Marketplace::GoogleMerchant"
}
}
Ответ · 201
{
"id": 1,
"name": "docs-min-GoogleMerchant",
"type": "Marketplace::GoogleMerchant",
"created_at": "2026-10-21T22:22:44.698+03:00",
"updated_at": "2026-10-21T22:22:44.698+03:00",
"url": "http://abc.insales.io/marketplace/1.xml",
"collection_ids": [],
"description_type": 1,
"local_delivery_cost": null,
"utm_label": null,
"adult": false,
"delivery_new_style": false,
"use_stock_currency": false,
"use_variants": false
}
После PATCH с коллекцией, utm_label, description_type 2, adult и local_delivery_cost публичный файл содержит товар этой коллекции. Метка дописывается к ссылке товара. Стоимость доставки попадает в g:shipping.
| Параметр | Описание |
|---|---|
id обязательныйчисло |
Идентификатор выгрузки в пути. Авторизация не нужна. |
GET /marketplace/1.xml
Accept: application/xml
Ответ · 200
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>docs-min-GoogleMerchant</title>
<link>http://abc.insales.io</link>
<item>
<g:title>docs-api catalog product</g:title>
<g:link>http://abc.insales.io/product/docs-api-catalog-product?utm_source=docs</g:link>
<g:description></g:description>
<g:id>673</g:id>
<g:condition>new</g:condition>
<g:availability>in stock</g:availability>
<g:price>10.0 RUB</g:price>
<g:adult>TRUE</g:adult>
<g:mpn>DOCS-CAT</g:mpn>
<g:shipping>
<g:country>RU</g:country>
<g:price>300 RUB</g:price>
</g:shipping>
</item>
</channel>
</rss>
Шапка RSS идёт одной строкой. У товара могут быть пустые g:product_type и g:image_link. Состав полей товара тот же.
Яндекс.Маркет, модель
shop_name короче 21 символа. Длиннее отвечает 422, тело {"shop_name":["Название магазина не может быть длиннее 20 символов."]}. vendor_id — id параметра товара. Чужой id отвечает 422, тело {"vendor_id":["Такого параметра для указания производителя не существует"]}.
Успешное создание возвращает collection_ids: []. Категории уже есть в файле, а следующий PUT без повторной передачи коллекций возвращает их список. Дата в файле модели — время магазина со смещением.
| Параметр | Описание |
|---|---|
name обязательныйстрока |
Название выгрузки. |
type обязательныйстрока |
Marketplace::ModelYandexMarket. |
shop_name обязательныйстрока |
Название магазина в файле, до 20 символов. |
shop_company обязательныйстрока |
Название компании в файле. |
vendor_id обязательныйчисло |
Идентификатор параметра, из которого берётся производитель. |
collection_ids необязательныймассив |
Коллекции товаров. В ответе 201 массив может быть пустым. |
local_delivery_cost необязательныйчисло |
Стоимость доставки в файле. |
sales_notes необязательныйстрока |
Примечание к условиям продажи. |
page_encoding необязательныйстрока |
utf-8. |
POST /admin/marketplaces.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"marketplace": {
"name": "docs-ym",
"type": "Marketplace::ModelYandexMarket",
"shop_name": "Docs Shop",
"shop_company": "Docs Co",
"vendor_id": 61541199,
"collection_ids": [53486011, 53486012],
"local_delivery_cost": 250,
"sales_notes": "самовывоз",
"page_encoding": "utf-8"
}
}
Ответ · 201
{
"id": 41,
"name": "docs-ym",
"type": "Marketplace::ModelYandexMarket",
"url": "http://abc.insales.io/marketplace/41.xml",
"collection_ids": [],
"description_type": 1,
"local_delivery_cost": 250,
"sales_notes": "самовывоз",
"vendor_id": 61541199,
"page_encoding": "utf-8",
"shop_company": "Docs Co",
"shop_name": "Docs Shop",
"adult": false,
"delivery": true,
"delivery_new_style": false,
"pickup": false,
"store": false,
"use_sku_as_vendor_code": false,
"use_stock_currency": false,
"use_variants": false
}
Произвольный шаблон
Marketplace::LiquidYandexMarket без offer_liquid отвечает 201 и записывает шаблон оффера по умолчанию. В нём есть product.id, product.price, product.title, product.properties.vendor, account.url, collection.id. Ошибочный Liquid отвечает 422, например {"offer_liquid":["Offer liquid содержит ошибку: Liquid syntax error (line 1): 'if' tag was never closed"]}.
В шаблоне оффера доступны product, account и collection: product.id, product.title, product.price, product.cost_price, product.sku, product.currency_id, product.available, product.variants.first.id, product.variants.first.cost_price, account.url, collection.id, collection.title. Закупочная цена печатается и как product.cost_price, и как product.variants.first.cost_price, когда она заполнена у варианта.
Параметр товара печатается по permalink и по названию: product.properties.brand и product.properties['Бренд']. Имя vendor остаётся пустым, пока нет параметра с таким permalink или названием. Параметр попадает в шаблон после выбора в выгрузке. Выбор передаётся объектом с числовыми ключами.
| Параметр | Описание |
|---|---|
offer_liquid необязательныйстрока |
Шаблон одного оффера. Ошибка синтаксиса отвечает 422. |
marketplace_properties_attributes необязательныйобъект |
Ключи 0, 1, … и property_id выбранных параметров. |
use_variants необязательныйлогический |
Включает данные вариантов в шаблоне. |
collection_ids необязательныймассив |
Коллекции, чьи товары попадают в файл. |
PATCH /admin/marketplaces/49.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"marketplace": {
"use_variants": true,
"collection_ids": [53486010],
"marketplace_properties_attributes": {
"0": {
"property_id": 61541199
}
},
"offer_liquid": "<offer id=\"{{ product.id }}\">\n <name>{{ product.title }}</name>\n <price>{{ product.price }}</price>\n <cost>{{ product.cost_price }}</cost>\n <sku>{{ product.sku }}</sku>\n <brand>{{ product.properties.brand }}</brand>\n</offer>"
}
}
Ответ · 200
{
"id": 49,
"name": "docs-lym",
"type": "Marketplace::LiquidYandexMarket",
"use_variants": true,
"collection_ids": [53486010],
"offer_liquid": "<offer id=\"{{ product.id }}\">…</offer>",
"shop_name": "Docs Liquid",
"shop_company": "Docs Co",
"url": "http://abc.insales.io/marketplace/49.xml"
}
offer_liquid в JSON сокращён. Выбранного параметра в JSON нет, он виден в файле.
| Параметр | Описание |
|---|---|
id обязательныйчисло |
Идентификатор выгрузки в пути. |
GET /marketplace/49.xml
Accept: application/xml
Ответ · 200
<offer id="673">
<name>docs-api catalog product</name>
<price>10.0</price>
<cost>4.5</cost>
<sku>DOCS-CAT</sku>
<brand>DocsBrand</brand>
</offer>
Вокруг оффера стандартная обёртка yml_catalog: категории, валюта RUB, пустой блок акций.
product.fields.HANDLE — строка выбранного доп. поля, без .value. Пока поле не выбрано, подстановка пустая. Запрос с marketplace_product_fields_attributes отвечает 422:
{
"marketplace_product_fields.account_id": ["Не заполнены обязательные поля"],
"marketplace_product_fields.product_field": ["Не заполнены обязательные поля"]
}
{% for product in products %} в шаблоне оффера товаров не перебирает. Общая обёртка файла задаётся layout_template. В ней есть content_for_layout — уже собранные офферы, marketplace.shop_name, marketplace.company, account.url, currency. Переменной products в обёртке нет. layout_template в JSON записи не возвращается, файл при этом собирается по нему. Фильтр {{ 'now' | date: '%Y-%m-%d %H:%M' }} печатает время UTC: при магазине +03:00 в файле было 2026-10-21 19:36. Дата стандартной обёртки модели Яндекса при этом остаётся во времени магазина.
| Параметр | Описание |
|---|---|
layout_template обязательныйстрока |
Обёртка файла. Офферы подставляются в content_for_layout. |
PATCH /admin/marketplaces/49.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json
{
"marketplace": {
"layout_template": "<yml_catalog date=\"{{ 'now' | date: '%Y-%m-%d %H:%M' }}\">\n<shop>\n<name>{{ marketplace.shop_name }}</name>\n<company>{{ marketplace.company }}</company>\n<url>{{ account.url }}</url>\n<currency>{{ currency }}</currency>\n<offers>{{ content_for_layout }}</offers>\n<has_products>{% if products %}yes{% else %}no{% endif %}</has_products>\n</shop>\n</yml_catalog>"
}
}
Ответ · 200
{
"id": 49,
"type": "Marketplace::LiquidYandexMarket",
"shop_name": "Docs Liquid",
"shop_company": "Docs Co",
"url": "http://abc.insales.io/marketplace/49.xml"
}
В JSON нет layout_template. Файл собирается по сохранённой обёртке. currency в ней равен RUR.
| Параметр | Описание |
|---|---|
id обязательныйчисло |
Идентификатор выгрузки в пути. |
GET /marketplace/49.xml
Accept: application/xml
Ответ · 200
<yml_catalog date="2026-10-21 19:36">
<shop>
<name>Docs Liquid</name>
<company>Docs Co</company>
<url>http://abc.insales.io</url>
<currency>RUR</currency>
<offers>
<offer id="673">
<name>docs-api catalog product</name>
<price>10.0</price>
</offer>
</offers>
<has_products>no</has_products>
</shop>
</yml_catalog>
Дата в файле — UTC. Оффер в файле равен текущему offer_liquid.