Перейти к содержанию

Темы, ассеты и файлы

Темы, ассеты и типы виджетов можно читать и менять, если у приложения есть право на дизайн. Для файлов раздела «Контент — Файлы» нужно право на файлы. Для панелей блоков — право на блоки.

Если нужного права нет, ответ 403:

{"status":"error","message":"Недостаточно прав для операции"}

Новую тему через этот API создать нельзя: POST /admin/themes.json отвечает 404. Скачать тему архивом нельзя: GET /admin/themes/:id/export.json отвечает 404.

На витрине файл темы и файл раздела «Контент — Файлы» — разные адреса. Файл темы попадает в шаблон через фильтр asset_url, файл раздела — через file_url.

Список тем

GET /admin/themes.json отдаёт массив тем, которые можно открыть. В объект входят название, признак публикации, язык, версия ассетов и текст последней ошибки темы.

GET/admin/themes.json
GET /admin/themes.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 1,
    "title": "Пользовательская",
    "description": null,
    "is_published": true,
    "is_mobile": null,
    "language_id": 1,
    "assets_version": 1651223995,
    "errors_text": null,
    "created_at": "2026-10-19T21:43:37.000+03:00",
    "updated_at": "2026-10-21T22:17:41.000+03:00"
  }
]

is_published: true — тема включена на витрине. language_id — язык темы. assets_version входит в путь файлов темы. errors_text — текст последней ошибки темы. У темы без ошибки поле равно null.

GET /admin/themes/999999999.json отвечает 404. Тело при заголовке Accept: application/json остаётся HTML-страницей.

Одна тема читается тем же составом полей.

GET/admin/themes/1.json
Параметр Описание
id обязательный
число
id темы в пути.
GET /admin/themes/1.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{
  "id": 1,
  "title": "Пользовательская",
  "description": null,
  "is_published": true,
  "is_mobile": null,
  "language_id": 1,
  "assets_version": 1651223995,
  "errors_text": null,
  "created_at": "2026-10-19T21:43:37.000+03:00",
  "updated_at": "2026-10-21T22:17:41.000+03:00"
}

Название и описание

PUT /admin/themes/:id.json сохраняет title и description. Ответ — {"status":"ok"}, саму тему нужно прочитать отдельным GET. description: null очищает описание.

PUT/admin/themes/1.json
Параметр Описание
id обязательный
число
id темы в пути.
theme[title] необязательный
строка
Название темы.
theme[description] необязательный
строка
Описание. `null` очищает поле.
PUT /admin/themes/1.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "theme": {
    "title": "Пользовательская",
    "description": "docs probe"
  }
}

Ответ · 200

{"status":"ok"}

Настройки цветов, шрифтов и пресетов этим запросом не передаются. Они лежат в файле settings_data.json, см. ниже.

Публикация

PUT /admin/themes/:id/publish.json публикует тему. Повторный вызов для уже опубликованной темы тоже отвечает {"status":"ok"}.

PUT/admin/themes/1/publish.json
Параметр Описание
id обязательный
число
id темы в пути.
PUT /admin/themes/1/publish.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{}

Ответ · 200

{"status":"ok"}

Удаление

DELETE /admin/themes/:id.json у опубликованной основной темы отвечает {"status":"ok"}, и тема остаётся в списке.

DELETE/admin/themes/1.json
Параметр Описание
id обязательный
число
id темы в пути.
DELETE /admin/themes/1.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{"status":"ok"}

После такого ответа основную тему нужно перечитать: {"status":"ok"} здесь значит, что запрос принят, а не что запись исчезла.

Ассеты темы

Ассет — файл внутри темы: шаблон, сниппет, картинка, стиль, скрипт или JSON из каталога config. Адрес: /admin/themes/:theme_id/assets.json.

type при создании:

Тип Что это Имя в запросе
Asset::Template Шаблон страницы. К имени дописывается .liquid. product.docs_api становится product.docs_api.liquid
Asset::Snippet Сниппет. К имени дописывается .liquid. docs_api_note становится docs_api_note.liquid
Asset::Media Картинка, CSS, JS и прочие файлы в корне темы. Имя как есть, с расширением: docs-api.png
Asset::Configuration JSON настроек в config. docs-api.json, settings_data.json

Список отдаёт id, тип, имя, человекочитаемое имя, адрес и version (unix-время изменения). Содержимого в списке нет.

GET/admin/themes/1/assets.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
GET /admin/themes/1/assets.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 97,
    "human_readable_name": "Товар",
    "asset_url": "/assets/1/1/1/1651223995/templates/product.liquid",
    "inner_file_name": "product.liquid",
    "type": "Asset::Template",
    "version": 1792435418
  },
  {
    "id": 177,
    "human_readable_name": "theme.css",
    "asset_url": "/assets/1/1/1/1651223995/theme.css",
    "inner_file_name": "theme.css",
    "type": "Asset::Media",
    "version": 1792435421
  }
]

Список содержит все файлы темы, без текста. asset_url — путь файла на витрине. Хост к нему не добавляется. В пути стоит assets_version темы.

GET одного liquid-файла добавляет поле content. У CSS, JS, картинки и JSON в этом ответе content нет.

GET/admin/themes/1/assets/113.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета в пути.
GET /admin/themes/1/assets/113.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{
  "id": 113,
  "human_readable_name": "head.liquid",
  "asset_url": "/assets/1/1/1/1651223995/snippets/head.liquid",
  "inner_file_name": "head.liquid",
  "type": "Asset::Snippet",
  "version": 1792435418,
  "content": "<!-- meta -->\n<meta charset=\"UTF-8\" />\n"
}

У CSS, JS, картинки и JSON тот же GET возвращает метаданные без content.

Тело любого файла, включая JSON, CSS и картинку, читается отдельным адресом .../raw.json. В ответе само содержимое файла. У картинки это байты файла.

GET/admin/themes/1/assets/153/raw.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета в пути.
GET /admin/themes/1/assets/153/raw.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{
  "current": "custom",
  "generation": 4,
  "presets": {
    "custom": {
      "color-btn-bg": "#0073E6"
    }
  }
}

Так читается settings_data.json. Адрес .../raw без суффикса .json отвечает 404 с пустым телом.

Тот же ресурс в .xml у картинки добавляет поле attachment — файл в Base64. В JSON-ответе картинки этого поля нет, байты берутся через raw.json.

Создание ассета

POST /admin/themes/:theme_id/assets.json. Без Content-Type: application/json ответ 422 и {"message":"incorrect Content-Type, should be application/json"}.

Сниппет создаётся текстом в content. Расширение .liquid дописывается само.

POST/admin/themes/1/assets.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
asset[type] обязательный
строка
`Asset::Snippet`.
asset[name] обязательный
строка
Имя без `.liquid`.
asset[content] обязательный
строка
Текст сниппета.
POST /admin/themes/1/assets.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "type": "Asset::Snippet",
    "name": "docs_api_note",
    "content": "<p>docs-api</p>"
  }
}

Ответ · 201

{
  "id": 1241,
  "human_readable_name": "docs_api_note.liquid",
  "asset_url": "/assets/1/1/1/1651223995/snippets/docs_api_note.liquid?1792609806",
  "inner_file_name": "docs_api_note.liquid",
  "type": "Asset::Snippet",
  "version": 1792609806
}

Повтор с тем же именем — 422:

{"inner_file_name":["Файл с именем docs_api_note.liquid уже существует"]}

Невалидный Liquid отвечает 422:

{"inner":["Ошибка синтаксиса: Liquid syntax error (line 1): [:end_of_string] is not a valid expression in \"\""]}

Неизвестный type — 422, в теле одновременно «Не заполнены обязательные поля» у inner и «имеет неверное значение» у type.

Свой шаблон товара называется product.ИМЯ. В ответе human_readable_name — «Товар: ИМЯ». Так же создаются page.ИМЯ («Страница: ИМЯ») и collection.ИМЯ («Категория: ИМЯ»).

POST/admin/themes/1/assets.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
asset[type] обязательный
строка
`Asset::Template`.
asset[name] обязательный
строка
Тип страницы, точка и имя шаблона.
asset[content] обязательный
строка
Liquid-текст шаблона.
POST /admin/themes/1/assets.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "type": "Asset::Template",
    "name": "product.docs_api",
    "content": "<h1>{{ product.title }}</h1>"
  }
}

Ответ · 201

{
  "id": 1249,
  "human_readable_name": "Товар: docs_api",
  "asset_url": "/assets/1/1/1/1651223995/templates/product.docs_api.liquid?1792609807",
  "inner_file_name": "product.docs_api.liquid",
  "type": "Asset::Template",
  "version": 1792609807
}

Картинка и прочий бинарный файл передаются полем attachment: содержимое в Base64. Рядом нужно filename, оно же попадает в name.

POST/admin/themes/1/assets.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
asset[type] обязательный
строка
`Asset::Media`.
asset[name] обязательный
строка
Имя файла с расширением.
asset[filename] обязательный
строка
То же имя: по нему определяется тип Base64.
asset[attachment] обязательный
строка
Файл в Base64.
POST /admin/themes/1/assets.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "type": "Asset::Media",
    "name": "docs-api.png",
    "filename": "docs-api.png",
    "attachment": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
  }
}

Ответ · 201

{
  "id": 1257,
  "human_readable_name": "docs-api.png",
  "asset_url": "/assets/1/1/1/1651223995/docs-api.png?1792609808",
  "inner_file_name": "docs-api.png",
  "type": "Asset::Media",
  "version": 1792609808
}

Вместо Base64 можно передать публичный src — http или https. Адрес внутренней сети отвечает 422: у src сообщение «Недопустимый URL», у inner — «Не заполнены обязательные поля».

CSS и JSON создаются тем же полем content. Для CSS тип — Asset::Media, для JSON — Asset::Configuration. raw.json возвращает текст файла как есть.

Изменение и переименование

PUT записывает новое content. В JSON-ответе по-прежнему нет текста: его читают через GET для liquid или через raw.json для остальных.

PUT/admin/themes/1/assets/1241.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета в пути.
asset[content] обязательный
строка
Новый текст файла.
PUT /admin/themes/1/assets/1241.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "content": "<p>docs-api updated</p>"
  }
}

Ответ · 200

{
  "id": 1241,
  "human_readable_name": "docs_api_note.liquid",
  "asset_url": "/assets/1/1/1/1651223995/snippets/docs_api_note.liquid",
  "inner_file_name": "docs_api_note.liquid",
  "type": "Asset::Snippet",
  "version": 1792609807
}

Переименование — отдельный путь .../rename.json, поле new_name.

PUT/admin/themes/1/assets/1241/rename.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета в пути.
asset[new_name] обязательный
строка
Новое имя файла.
PUT /admin/themes/1/assets/1241/rename.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "new_name": "docs_api_note_renamed.liquid"
  }
}

Ответ · 200

{
  "id": 1241,
  "human_readable_name": "docs_api_note_renamed.liquid",
  "asset_url": "/assets/1/1/1/1651223995/snippets/docs_api_note_renamed.liquid?1792609807",
  "inner_file_name": "docs_api_note_renamed.liquid",
  "type": "Asset::Snippet",
  "version": 1792609807
}

Стандартный шаблон, например product.liquid, так не переименовывается. Ответ 422:

{"inner_file_name":["Нельзя переименовать стандартный шаблон"]}

Удаление ассета

DELETE отвечает 200 и пустым телом и для удалённого файла, и для файла, который удалить нельзя. Разница видна только следующим GET.

Сниппет, свой шаблон, картинка и CSS после такого ответа читаются как 404. Стандартный product.liquid остаётся на месте. Файл типа Asset::Configuration, в том числе свой JSON-файл настроек и settings_data.json, тоже остаётся: GET после DELETE по-прежнему 200.

DELETE/admin/themes/1/assets/1241.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета в пути.
DELETE /admin/themes/1/assets/1241.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

Тело пустое.

Настройки темы

Цвета, шрифты и текущий пресет лежат в ассете settings_data.json (Asset::Configuration). GET метаданных content не отдаёт. Текст читается через .../raw.json. Запись идёт через PUT: в content передаётся весь JSON файла. Ответ — метаданные ассета. Новый текст снова читается через raw.json.

PUT/admin/themes/1/assets/153.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
id обязательный
число
id ассета `settings_data.json`.
asset[content] обязательный
строка
Полный JSON файла настроек.
PUT /admin/themes/1/assets/153.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "asset": {
    "content": "<текст из GET /admin/themes/1/assets/153/raw.json>"
  }
}

Ответ · 200

{
  "id": 153,
  "human_readable_name": "settings_data.json",
  "asset_url": "/assets/1/1/1/1651223995/config/settings_data.json",
  "inner_file_name": "settings_data.json",
  "type": "Asset::Configuration",
  "version": 1792609881
}

В content кладётся весь JSON из raw.json, с изменёнными ключами. Запись части файла стирает остальные настройки пресета. После записи текст снова читается через raw.json.

settings_data.json сохраняет и невалидный JSON: ответ 200, после этого файл не разбирается. settings.json и другие JSON-ассеты на такое тело отвечают 422, файл остаётся прежним:

{"content":["Невалидный json"]}

Рядом в теме лежат:

  • settings.json — описание полей редактора. Невалидный JSON отклоняется.
  • messages.json — тексты по языкам. Обновляется тем же PUT с полным JSON.
  • setup.json — состав блоков темы, в том числе block_lists. Читается через raw.json. Метода для панелей виджетов страницы в этом API нет, см. ниже.

Файлы аккаунта

/admin/files.json — это раздел «Контент — Файлы», не файлы темы. В ответе три поля: id, created_at, absolute_url. Имени отдельным полем нет, оно стоит в конце absolute_url.

GET/admin/files.json
GET /admin/files.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 249,
    "created_at": "2026-10-21T22:13:06.867+03:00",
    "absolute_url": "https://static-ru.insales.ru/files/1/249/249/original/docs-api.png"
  },
  {
    "id": 257,
    "created_at": "2026-10-21T22:13:06.992+03:00",
    "absolute_url": "https://static-ru.insales.ru/files/1/257/257/original/docs-api.txt"
  }
]

absolute_url — полный адрес файла на CDN. Хост у магазина свой, путь имеет вид /files/…/original/имя. Хост из адреса убирать нельзя. В шаблоне тот же файл подключают фильтром file_url по имени.

При создании в absolute_url есть query с unix-временем изменения. В списке и в GET /admin/files/:id.json этого query нет.

name ищет подстроку в имени. Без per_page на странице 10 файлов. page начинается с 1. page=0 отвечает 422:

{"message":"page должен иметь значение, большее 0"}
GET/admin/files.json?name=docs-api&per_page=1&page=1
Параметр Описание
name необязательный
строка
Часть имени файла.
per_page необязательный
число
Размер страницы. Без параметра — 10.
page необязательный
число
Номер страницы, начиная с 1.
GET /admin/files.json?name=docs-api&per_page=1&page=1
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 249,
    "created_at": "2026-10-21T22:13:06.867+03:00",
    "absolute_url": "https://static-ru.insales.ru/files/1/249/249/original/docs-api.png"
  }
]

Загрузка — Base64 в attachment и filename. Отдельного метода изменения нет: PUT /admin/files/:id.json отвечает 404. Чтобы заменить файл, его удаляют и создают снова. Повтор того же имени — 422, {"inner_file_name":["уже существует"]}.

POST/admin/files.json
Параметр Описание
file[filename] обязательный
строка
Имя файла с расширением.
file[attachment] обязательный
строка
Файл в Base64. Вместо него можно передать `file[src]`.
POST /admin/files.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "file": {
    "filename": "docs-api.png",
    "attachment": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
  }
}

Ответ · 201

{
  "id": 249,
  "created_at": "2026-10-21T22:13:06.867+03:00",
  "absolute_url": "https://static-ru.insales.ru/files/1/249/249/original/docs-api.png?1792609986"
}

src на http://127.0.0.1/... ответил 422: «Недопустимый URL». Имя robots.txt тоже 422:

{"inner_file_name":["Вы можете отредактировать robots.txt в разделе Настройки → Robots.txt"]}

Удаление возвращает {"status":"ok"}. Следующий GET этого id — HTML 404.

DELETE/admin/files/249.json
Параметр Описание
id обязательный
число
id файла в пути.
DELETE /admin/files/249.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{"status":"ok"}

Свой шаблон страницы

Файл product.docs_api.liquid сам по себе ничего не подключает. У товара, страницы и категории есть поле custom_template. В него пишется часть имени после точки: для файла product.docs_api.liquid это docs_api. Метод сохраняет значение и тогда, когда такого файла в теме нет.

Товар:

PUT/admin/products/681.json
Параметр Описание
id обязательный
число
id товара в пути.
product[custom_template] необязательный
строка
Имя шаблона без префикса `product.` и без `.liquid`.
PUT /admin/products/681.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "product": {
    "custom_template": "docs_api"
  }
}

Ответ · 200

{
  "id": 681,
  "title": "docs-api-theme",
  "custom_template": "docs_api"
}

Создание товара — в разделе про товары.

Страница принимает то же поле, но без текста страницы ответ 422: «Добавьте какой-нибудь текст на страницу, даже если она будет скрыта.» С текстом custom_template сохраняется.

POST/admin/pages.json
Параметр Описание
page[title] обязательный
строка
Название. Из него строится permalink.
page[content] обязательный
строка
Текст страницы.
page[custom_template] необязательный
строка
Имя шаблона для файла `page.ИМЯ.liquid`.
POST /admin/pages.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "page": {
    "title": "docs-api page",
    "content": "Текст страницы",
    "custom_template": "docs_api"
  }
}

Ответ · 201

{
  "id": 59,
  "title": "docs-api page",
  "permalink": "docs-api-page-710e05",
  "content": "Текст страницы",
  "custom_template": "docs_api",
  "is_hidden": false,
  "kind": "only_page"
}

Категория создаётся с parent_id существующей категории и тем же custom_template. Без родителя ответ 422: «Не заполнены обязательные поля» у parent_id. Файл шаблона категории — collection.docs_api.liquid.

У блога в GET /admin/blogs.json есть поле custom_template.

Виджеты темы

Публичное API работает с типами виджетов темы: /admin/themes/:theme_id/widget_types.json. Список содержит только свои типы этой темы. Системных виджетов в нём нет. Поставить виджет на страницу, прочитать список виджетов страницы или панели header / content / footer этим API нельзя: GET /admin/themes/1/widgets.json, GET /admin/widget_lists.json и GET /admin/widgets.json отвечают 404.

Виджет в карточке заказа или товара бэк-офиса — другой ресурс, виджеты приложения.

Поля создания лежат в корне JSON. Объект внутри ключа widget_type отвечает 422: ключ назван неизвестным, обязательные поля — пропущенными.

page_kinds — массив из all, index, collection, product, cart, page, search, blog, article, compare, favorite, shared_cart. Чужое значение даёт 422: {"page_kinds":{"0":["is not valid"]}}.

widget_list_kinds — массив из header, before_content, content, sidebar, after_content, footer, outside, top_panel, bottom_panel. Чужое значение: {"widget_list_kinds":{"0":["is not valid"]}}.

widget_category_handle — handle существующей категории, например benefits. Неизвестная категория: 422, widget_category_id — «Не заполнены обязательные поля».

POST/admin/themes/1/widget_types.json
Параметр Описание
theme_id обязательный
число
id темы в пути.
type обязательный
строка
`SimpleWidgetType` или `BlockListWidgetType`.
name обязательный
объект
Название по языкам, ключ `ru` и другие.
handle обязательный
строка
Код виджета в теме. Не начинается с `system_`.
snippet_content обязательный
строка
Liquid-разметка.
generation обязательный
число
Поколение виджета. Для темы поколения 4 — `4`.
page_kinds обязательный
массив
Типы страниц, где виджет можно поставить.
widget_list_kinds обязательный
массив
Панели, куда виджет можно поставить.
widget_category_handle необязательный
строка
Категория в списке виджетов. Без известной категории запись не создаётся.
snippet_js необязательный
строка
JavaScript виджета.
snippet_scss необязательный
строка
Стили виджета.
messages необязательный
строка
JSON текстов. В теле запроса это строка.
description необязательный
объект
Описание по языкам.
setup необязательный
строка
JSON состава строкой.
settings_form необязательный
строка
JSON формы настроек строкой.
settings_data необязательный
строка
JSON значений строкой.
block_template_handle необязательный
строка
Шаблон блока. Нужен для `BlockListWidgetType`.
POST /admin/themes/1/widget_types.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "type": "SimpleWidgetType",
  "name": {"ru": "docs-api виджет"},
  "handle": "docs-api-widget",
  "snippet_content": "<div class=\"docs-api\">{{ widget_settings.title }}</div>",
  "generation": 4,
  "page_kinds": ["index", "all"],
  "widget_list_kinds": ["content"],
  "widget_category_handle": "benefits",
  "snippet_js": "console.log('docs-api');",
  "snippet_scss": ".docs-api{display:block}",
  "messages": "{\"ru\":{\"title\":\"Заголовок\"}}",
  "description": {"ru": "Пример виджета"},
  "setup": "{}",
  "settings_form": "{\"content\":[],\"design\":[]}",
  "settings_data": "{}"
}

Ответ · 201

{
  "id": 12381652,
  "type": "SimpleWidgetType",
  "name": "docs-api виджет",
  "handle": "docs-api-widget",
  "snippet_content": "<div class=\"docs-api\">{{ widget_settings.title }}</div>",
  "snippet_scss": ".docs-api{display:block}",
  "snippet_js": "console.log('docs-api');",
  "settings_form": "{\"content\":[],\"design\":[]}",
  "settings_data": "{}",
  "setup": "{}",
  "messages": "{\"ru\":{\"title\":\"Заголовок\"}}",
  "description": "Пример виджета",
  "page_kinds": ["index", "all"],
  "widget_list_kinds": ["content"],
  "generation": 4,
  "preview_url": null,
  "widget_category_handle": "benefits",
  "libraries": []
}

В ответе name и description — строки текущего языка. В запросе name передаётся объектом по языкам. handle после создания не обновляется: PUT с полем handle отвечает 422, {"handle":["unknown attribute"]}.

Пустой JSON {} на создание отвечает 422 и перечисляет пропущенные поля: type, name, handle, snippet_content, generation, page_kinds, widget_list_kinds. Неизвестный type — {"type":["is not valid"]}.

PUT меняет переданные поля и возвращает тип целиком. GET /admin/themes/:theme_id/widget_types.json возвращает массив таких объектов. GET одного id — один объект. DELETE отвечает 200 и пустым телом, следующий GET — HTML 404.

Виджет со списком блоков создаётся типом BlockListWidgetType. В block_template_handle передаётся handle системного шаблона блока, например system-benefit. В ответе это поле возвращается вместе с остальными полями простого виджета.

POST/admin/themes/1/widget_types.json
Параметр Описание
type обязательный
строка
`BlockListWidgetType`.
block_template_handle обязательный
строка
Handle системного шаблона блока, например `system-benefit`.
name обязательный
объект
Название по языкам.
handle обязательный
строка
Код виджета.
snippet_content обязательный
строка
Liquid-разметка.
generation обязательный
число
Поколение виджета. Для темы поколения 4 — `4`.
page_kinds обязательный
массив
Типы страниц.
widget_list_kinds обязательный
массив
Панели размещения.
widget_category_handle обязательный
строка
Категория виджета.
POST /admin/themes/1/widget_types.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "type": "BlockListWidgetType",
  "name": {"ru": "docs-api блоки"},
  "handle": "docs-api-blocks",
  "snippet_content": "<div class=\"docs-api\">{{ widget_settings.title }}</div>",
  "generation": 4,
  "page_kinds": ["index", "all"],
  "widget_list_kinds": ["content"],
  "widget_category_handle": "benefits",
  "block_template_handle": "system-benefit"
}

Ответ · 201

{
  "id": 12381653,
  "type": "BlockListWidgetType",
  "name": "docs-api блоки",
  "handle": "docs-api-blocks",
  "block_template_handle": "system-benefit",
  "generation": 4,
  "page_kinds": ["index", "all"],
  "widget_list_kinds": ["content"],
  "widget_category_handle": "benefits"
}

Ответ содержит те же snippet_content, settings_form, messages и libraries, что и простой виджет, и поле block_template_handle.

Панели блоков

/admin/block_lists.json читает панели блоков магазина. Это записи с именем, liquid_name и block_template_id. Состав панели — /admin/block_lists/:id/block_list_items.json, у элемента есть block_id и position.

GET/admin/block_lists.json
GET /admin/block_lists.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 1,
    "name": "Цвет стикеров",
    "liquid_name": "block-list-e213b73920beb6a2-pffc9bb5ea465fefbd",
    "block_template_id": 2851286,
    "invisible": true
  }
]

В ответе также есть account_id и даты. GET /admin/block_lists/1.json возвращает одну такую запись.

GET/admin/block_lists/1/block_list_items.json
Параметр Описание
block_list_id обязательный
число
id панели в пути.
GET /admin/block_lists/1/block_list_items.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 1,
    "block_list_id": 1,
    "block_id": 1,
    "position": 1
  },
  {
    "id": 9,
    "block_list_id": 1,
    "block_id": 9,
    "position": 2
  }
]

POST /admin/block_lists.json с name и liquid_name отвечает 404. Страница содержит «Couldn't find BlockList without an ID». PUT панели в JSON отвечает 406. Панель через JSON этим методом не меняется.

Списка блоков нет: GET /admin/blocks.json отвечает 404. POST /admin/blocks.json с названием и текстом отвечает 200 и {"status":"error","errors":{}}. Тот же запрос в XML отвечает 422 с пустым <errors/>. Отдельного чтения одного блока нет.

Состав блоков поколения 4, который виден в редакторе темы, в эту пару методов не входит. Его читают как файл setup.json темы через raw.json. Разместить виджет на панели публичным API нельзя.