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

Витрина

Через API бэк-офиса приложение может управлять содержимым витрины: блогами, статьями, страницами, меню, JS-тегами и редиректами.

Если объекта с указанным идентификатором нет, API возвращает 404 с HTML-страницей, даже при запросе JSON. Это относится к блогам, статьям, страницам, меню, пунктам меню, JS-тегам и редиректам.

Для изменения записи используйте PUT. У блогов и страниц также поддерживается PATCH: он выполняет то же изменение и возвращает тот же статус. Редиректы нельзя изменить: для них PUT и PATCH возвращают 404.

Если page меньше 1 или больше либо равен 1000000, API возвращает 422:

{"message": "page должен иметь значение, большее 0"}

Если метод ожидает корневой объект, а тело пустое, API возвращает 422 с сообщением param is missing or the value is empty or invalid. В сообщении указывается нужный ключ: blog, menu, js_tag или redirect.

Для создания записи используйте POST к соответствующему ресурсу, для удаления — DELETE.

Язык

Параметр lang выбирает язык для чтения и записи текстовых полей блога и статьи. Язык должен быть включён в магазине. При чтении без lang возвращается текст на языке магазина по умолчанию.

Чтобы добавить перевод существующей записи, отправьте PUT на её идентификатор с нужным lang. Поля title, content и author сохранятся на указанном языке, а permalink останется прежним. Для чтения перевода передайте тот же lang в GET-запросе.

Каждый POST создаёт отдельную запись. Если повторить его с другим lang, появится вторая запись, а не перевод первой.

Если язык из lang не включён в магазине, текст сохраняется на языке по умолчанию, заменяя его текущее значение.

PUT/admin/blogs/9/articles/121.json?lang=en
Параметр Описание
blog_id обязательный
число
id блога в пути.
id обязательный
число
id статьи в пути.
lang обязательный
строка
Код языка, включённого в магазине.
article[title] необязательный
строка
Название на этом языке.
article[content] необязательный
строка
Текст на этом языке.
article[author] необязательный
строка
Автор на этом языке.
PUT /admin/blogs/9/articles/121.json?lang=en
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api english",
    "content": "<p>english</p>",
    "author": "Author"
  }
}

Ответ · 200

{
  "id": 121,
  "title": "docs-api english",
  "content": "<p>english</p>",
  "author": "Author",
  "permalink": "docs-api-russkaya"
}

В примере изменяются только переводимые поля. Остальные поля статьи описаны в разделе «Создание статьи».

Блоги

GET /admin/blogs.json возвращает все блоги одним массивом, без постраничного деления. Адрес блога, который не является главным, имеет вид /blogs/{handle}. В JSON используется поле handle; отдельного поля permalink у блога нет.

commentable на витрине использует no, yes и moderable. Другое значение тоже сохраняется и возвращается.

Поле category принимает одно из значений: Авто, Военторг, Дизайн, Дом, Еда, Здоровье, Знаменитости, Игры, Кино, Культура, Литература, Мода, Музыка, Наука, Общество, Политика, Природа, Происшествия, Психология, Путешествия, Спорт, Технологии, Фотографии, Хобби, Экономика, Юмор. Другие значения отклоняются со статусом 422.

Поля category, check_spam_enabled и custom_layout принимаются в запросе, но не возвращаются в JSON блога, в том числе при повторном чтении. Поле custom_template возвращается. О назначении файла шаблона читайте в разделе «Темы, ассеты и файлы».

Список блогов

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

Ответ · 200

[
  {
    "id": 9,
    "commentable": "no",
    "notify_about_comment": true,
    "captcha_enabled": false,
    "disallow_links_in_comments": false,
    "custom_template": null,
    "handle": "docs-api-blog",
    "title": "docs-api блог",
    "html_title": null,
    "meta_keywords": null,
    "meta_description": null,
    "tags": []
  }
]

tags — массив объектов с title.

Создание блога

Для создания блога обязателен title. Значение handle формируется из названия транслитерацией. Если оно уже занято, InSales добавляет суффикс -2 и создаёт блог со статусом 201. Значение длиной больше 16 символов также сохраняется.

POST/admin/blogs.json
Параметр Описание
blog[title] обязательный
строка
Название. Из него строится handle, если handle не передан.
blog[handle] необязательный
строка
Сегмент адреса `/blogs/{handle}`.
POST /admin/blogs.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "blog": {
    "title": "docs-api блог"
  }
}

Ответ · 201

{
  "id": 9,
  "commentable": "no",
  "notify_about_comment": true,
  "captcha_enabled": false,
  "disallow_links_in_comments": false,
  "custom_template": null,
  "handle": "docs-api-blog",
  "title": "docs-api блог",
  "html_title": null,
  "meta_keywords": null,
  "meta_description": null,
  "tags": []
}

Повтор с тем же handle создаёт второй блог.

POST/admin/blogs.json
Параметр Описание
blog[title] обязательный
строка
Название второго блога.
blog[handle] необязательный
строка
Занятое значение. В ответе к нему добавлен суффикс.
POST /admin/blogs.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "blog": {
    "title": "docs-api другой",
    "handle": "docs-api-blog"
  }
}

Ответ · 201

{
  "id": 17,
  "commentable": "no",
  "notify_about_comment": true,
  "captcha_enabled": false,
  "disallow_links_in_comments": false,
  "custom_template": null,
  "handle": "docs-api-blog-2",
  "title": "docs-api другой",
  "html_title": null,
  "meta_keywords": null,
  "meta_description": null,
  "tags": []
}

Изменение блога

PUT/admin/blogs/9.json
Параметр Описание
id обязательный
число
id блога в пути.
blog[title] необязательный
строка
Название.
blog[handle] необязательный
строка
Сегмент адреса.
blog[html_title] необязательный
строка
Заголовок окна.
blog[meta_keywords] необязательный
строка
Ключевые слова.
blog[meta_description] необязательный
строка
Описание.
blog[commentable] необязательный
строка
`no`, `yes` или `moderable`.
blog[notify_about_comment] необязательный
логический
Письмо о комментарии.
blog[captcha_enabled] необязательный
логический
Капча в комментариях.
blog[disallow_links_in_comments] необязательный
логический
Запрет ссылок в комментариях.
blog[custom_template] необязательный
строка
Имя шаблона. Возвращается в JSON.
blog[category] необязательный
строка
Категория из списка выше. В JSON блога поля нет.
PUT /admin/blogs/9.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "blog": {
    "title": "docs-api блог полный",
    "handle": "docs-api-blog",
    "html_title": "HTML блога",
    "meta_keywords": "ключи",
    "meta_description": "описание",
    "commentable": "yes",
    "notify_about_comment": false,
    "captcha_enabled": true,
    "disallow_links_in_comments": true,
    "category": "Технологии",
    "custom_template": "blog.custom"
  }
}

Ответ · 200

{
  "id": 9,
  "commentable": "yes",
  "notify_about_comment": false,
  "captcha_enabled": true,
  "disallow_links_in_comments": true,
  "custom_template": "blog.custom",
  "handle": "docs-api-blog",
  "title": "docs-api блог полный",
  "html_title": "HTML блога",
  "meta_keywords": "ключи",
  "meta_description": "описание",
  "tags": []
}

Чужая категория отклоняется. Ключ ошибки — category.

PUT/admin/blogs/9.json
Параметр Описание
id обязательный
число
id блога в пути.
blog[category] обязательный
строка
Значение вне списка категорий.
PUT /admin/blogs/9.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "blog": {
    "category": "Несуществующая"
  }
}

Ответ · 422

{"category": ["имеет непредусмотренное значение"]}

Удаление блога

При удалении блога его статьи переносятся в архив. После этого чтение блога и его статей возвращает 404.

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

Ответ · 200

{"status": "ok"}

Статьи

Чтобы создать статью, отправьте POST /admin/blogs/:blog_id/articles.json в нужный блог.

GET /admin/blogs/:blog_id/articles.json возвращает статьи одного блога. Сначала идёт закреплённая статья, затем остальные по убыванию published_at и id.

По умолчанию на странице 10 статей. Параметры per_page и limit ограничены диапазоном от 10 до 250: значения за его пределами заменяются ближайшей границей. Параметр updated_since не фильтрует список статей.

Для создания статьи обязательны title, content, author и published_at. Пустые значения отклоняются со статусом 422. Ошибка текста возвращается под ключом content_with_urls, а не content.

Если дата публикации передана без времени, InSales использует полночь в часовом поясе магазина. Например, 2024-05-02 в магазине с поясом +03:00 сохраняется как 2024-05-02T00:00:00.000+03:00.

permalink можно задать. Если его нет, он строится из названия транслитом.

Опубликованная статья доступна на витрине по адресу /blogs/{handle}/{permalink} со статусом 200. Если published_at находится в будущем, статья уже доступна в API, но её обычный адрес возвращает 404. Предпросмотр /blogs/{handle}/{permalink}/preview возвращает 200. Адрес /blog/{permalink} для статьи неглавного блога возвращает 404.

Комментариев статьи в этом API нет. GET /admin/comments.json и GET /admin/blogs/:blog_id/articles/:id/comments.json отвечают 404.

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

Поле all_tags заменяет список тегов целиком. Можно назначить не более 30 тегов. При передаче 31 тега API возвращает 422: «Невозможно задать больше 30 тегов к статье.»

Чтобы привязать товары к статье, передайте related_products_attributes с product_id. Массив идентификаторов в related_products не привязывает товары: статья создаётся с пустым списком. Несуществующий идентификатор отклоняется со статусом 422: «Товары 999999999 не найдены». Для удаления привязки передайте элемент того же массива с _destroy: true.

related_products — товары статьи.

Одновременно может быть закреплена одна статья. Если сохранить другую статью с pinned: true, у ранее закреплённой статьи pinned станет false.

HTML в content сохраняется как передан, включая meta и script.

POST/admin/blogs/9/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[title] обязательный
строка
Название.
article[content] обязательный
строка
Текст. В ошибке ключ называется `content_with_urls`.
article[author] обязательный
строка
Автор.
article[published_at] обязательный
строка
Дата публикации.
article[notice] необязательный
строка
Анонс.
article[permalink] необязательный
строка
Сегмент адреса статьи.
article[html_title] необязательный
строка
Заголовок окна.
article[meta_keywords] необязательный
строка
Ключевые слова.
article[meta_description] необязательный
строка
Описание.
article[all_tags] необязательный
массив
Теги. Новый список заменяет прежний. Максимум 30.
article[pinned] необязательный
логический
Закрепить. Предыдущая закреплённая снимается.
article[custom_template] необязательный
строка
Имя шаблона.
article[related_products_attributes] необязательный
массив
Товары статьи. Элемент содержит `product_id`.
POST /admin/blogs/9/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api статья",
    "content": "<p>Текст статьи</p>",
    "notice": "<p>Анонс</p>",
    "author": "Документация",
    "permalink": "docs-api-article",
    "html_title": "HTML статьи",
    "meta_keywords": "статья",
    "meta_description": "описание статьи",
    "published_at": "2024-05-01T10:00:00+03:00",
    "all_tags": ["docs-api", "витрина"],
    "pinned": true,
    "custom_template": "article.custom",
    "related_products_attributes": [
      {"product_id": 601}
    ]
  }
}

Ответ · 201

{
  "id": 9,
  "created_at": "2026-10-21T22:15:45.000+03:00",
  "updated_at": "2026-10-21T22:15:45.000+03:00",
  "published_at": "2024-05-01T10:00:00.000+03:00",
  "pinned": true,
  "custom_template": "article.custom",
  "title": "docs-api статья",
  "author": "Документация",
  "permalink": "docs-api-article",
  "html_title": "HTML статьи",
  "meta_keywords": "статья",
  "meta_description": "описание статьи",
  "tags": [
    {"title": "docs-api"},
    {"title": "витрина"}
  ],
  "related_products": [
    {
      "id": 601,
      "title": "Футболка с принтом"
    }
  ],
  "notice": "<p>Анонс</p>",
  "content": "<p>Текст статьи</p>"
}

Массив id в related_products статью создаёт, товары не привязывает.

POST/admin/blogs/9/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[title] обязательный
строка
Название.
article[content] обязательный
строка
Текст.
article[author] обязательный
строка
Автор.
article[published_at] обязательный
строка
Дата публикации.
article[related_products] необязательный
массив
Список id. Привязки товаров не создаёт.
POST /admin/blogs/9/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api товары массивом",
    "content": "<p>x</p>",
    "author": "Документация",
    "published_at": "2024-05-02",
    "related_products": [601]
  }
}

Ответ · 201

{
  "id": 17,
  "published_at": "2024-05-02T00:00:00.000+03:00",
  "pinned": false,
  "title": "docs-api товары массивом",
  "author": "Документация",
  "permalink": "docs-api-tovary-massivom",
  "tags": [],
  "related_products": [],
  "notice": null,
  "content": "<p>x</p>"
}

Неизвестный товар отклоняет всю статью.

POST/admin/blogs/9/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[related_products_attributes] обязательный
массив
Элемент с id, которого нет в магазине.
POST /admin/blogs/9/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api чужой товар",
    "content": "<p>x</p>",
    "author": "Документация",
    "published_at": "2024-05-03",
    "related_products_attributes": [
      {"product_id": 999999999}
    ]
  }
}

Ответ · 422

{"related_products_attributes": ["Товары 999999999 не найдены"]}

Без текста, автора и даты статья не создаётся. Если название передано, ключа title в ошибке нет.

POST/admin/blogs/9/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[title] обязательный
строка
Название. Остальные обязательные поля в запросе пустые.
POST /admin/blogs/9/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "только название"
  }
}

Ответ · 422

{
  "published_at": ["Не заполнены обязательные поля"],
  "author": ["Не заполнены обязательные поля"],
  "content_with_urls": ["Не заполнены обязательные поля"]
}

Картинка статьи

Изображение статьи передаётся при создании или изменении статьи, в том же POST или PUT. Отдельного метода загрузки нет. Используйте один из способов: содержимое файла в Base64 в attachment вместе с filename или публичный адрес в src. Пока InSales обрабатывает файл, original_url может указывать на /images/loading.gif.

Внутренний адрес в src отвечает 422, ключ ошибки — image.src, текст «Недопустимый URL».

POST/admin/blogs/9/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[image_attributes][filename] обязательный
строка
Имя файла.
article[image_attributes][attachment] обязательный
строка
Содержимое файла, base64.
POST /admin/blogs/9/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api с картинкой",
    "content": "<p>картинка</p>",
    "author": "Документация",
    "published_at": "2024-06-01",
    "image_attributes": {
      "filename": "dot.png",
      "attachment": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
    }
  }
}

Ответ · 201

{
  "id": 41,
  "published_at": "2024-06-01T00:00:00.000+03:00",
  "pinned": false,
  "title": "docs-api с картинкой",
  "author": "Документация",
  "permalink": "docs-api-s-kartinkoy",
  "image": {
    "id": 1,
    "created_at": "2026-10-21T22:15:46.000+03:00",
    "original_url": "/images/loading.gif"
  },
  "tags": [],
  "notice": null,
  "content": "<p>картинка</p>"
}

Публичный адрес тоже создаёт картинку. В ответе снова временный original_url.

POST/admin/blogs/33/articles.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
article[image_attributes][src] обязательный
строка
Публичный URL файла.
POST /admin/blogs/33/articles.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "title": "docs-api картинка по ссылке",
    "content": "<p>картинка</p>",
    "author": "Документация",
    "published_at": "2024-07-02",
    "image_attributes": {
      "src": "https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png"
    }
  }
}

Ответ · 201

{
  "title": "docs-api картинка по ссылке",
  "image": {
    "id": 9,
    "created_at": "2026-10-21T22:27:13.000+03:00",
    "original_url": "/images/loading.gif"
  }
}

Список статей блога

GET/admin/blogs/9/articles.json?per_page=10&page=2
Параметр Описание
blog_id обязательный
число
id блога в пути.
per_page необязательный
число
Размер страницы. Меньше 10 становится 10, больше 250 становится 250.
limit необязательный
число
То же, что `per_page`.
page необязательный
число
Номер страницы. `0` отвечает 422.
GET /admin/blogs/9/articles.json?per_page=10&page=2
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 81,
    "created_at": "2026-10-21T22:15:48.000+03:00",
    "updated_at": "2026-10-21T22:15:48.000+03:00",
    "published_at": "2020-01-04T00:00:00.000+03:00",
    "pinned": false,
    "custom_template": null,
    "title": "docs-api пачка 3",
    "author": "Документация",
    "permalink": "docs-api-pachka-3",
    "html_title": null,
    "meta_keywords": null,
    "meta_description": null,
    "tags": [],
    "related_products": [],
    "notice": null,
    "content": "<p>пачка</p>"
  }
]

Если per_page меньше 10, API использует размер страницы 10.

page=0 отклоняется.

GET/admin/blogs/9/articles.json?page=0
Параметр Описание
blog_id обязательный
число
id блога в пути.
page обязательный
число
Номер страницы меньше 1.
GET /admin/blogs/9/articles.json?page=0
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 422

{"message": "page должен иметь значение, большее 0"}

Замена тегов и товаров

Чтобы заменить все теги статьи, передайте полный список в all_tags запросом PUT. Для удаления привязки товара передайте _destroy в related_products_attributes.

PUT/admin/blogs/9/articles/9.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
id обязательный
число
id статьи в пути.
article[all_tags] обязательный
массив
Новый полный список тегов.
PUT /admin/blogs/9/articles/9.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "all_tags": ["только-этот"]
  }
}

Ответ · 200

{
  "id": 9,
  "title": "docs-api статья",
  "permalink": "docs-api-article",
  "tags": [
    {"title": "только-этот"}
  ]
}
PUT/admin/blogs/9/articles/9.json
Параметр Описание
blog_id обязательный
число
id блога в пути.
id обязательный
число
id статьи в пути.
article[related_products_attributes] обязательный
массив
Элемент с `product_id` и `_destroy: true` снимает товар.
PUT /admin/blogs/9/articles/9.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "article": {
    "related_products_attributes": [
      {"product_id": 601, "_destroy": true}
    ]
  }
}

Ответ · 200

{
  "id": 9,
  "title": "docs-api статья",
  "related_products": []
}

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

Удаление архивирует статью. Следующий GET отвечает 404, в списке её нет.

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

Ответ · 200

{"status": "ok"}

Страницы

Адрес страницы — /page/{permalink}. GET /admin/pages.json возвращает страницы без фиксированного порядка.

По умолчанию на странице до 25 записей. Если per_page меньше 25, API использует 25; если больше 1000 — 1000.

content обязателен. permalink можно задать. Занятый permalink сохраняется с суффиксом -2. Занятое название отвечает 422: «уже существует». created_at можно передать, значение сохраняется. custom_template сохраняется и возвращается. Файл шаблона — в темах.

is_hidden и kind из запроса не применяются. В ответе is_hidden равен false, kind — only_page.

Если в магазине уже есть меню, новая страница автоматически добавляется в первое из них. Параметр menu_id не позволяет выбрать другое меню. Пункт получает название страницы и адрес /page/{permalink}.

Создание страницы

POST/admin/pages.json
Параметр Описание
page[title] обязательный
строка
Название. Повтор того же названия отвечает 422.
page[content] обязательный
строка
Текст. Пустой текст отвечает 422.
page[permalink] необязательный
строка
Сегмент адреса `/page/{permalink}`. Занятый получает суффикс.
page[html_title] необязательный
строка
Заголовок окна.
page[meta_keywords] необязательный
строка
Ключевые слова.
page[meta_description] необязательный
строка
Описание.
page[custom_template] необязательный
строка
Имя шаблона. Сохраняется как передано.
page[created_at] необязательный
строка
Дата создания. Сохраняется из запроса.
page[is_hidden] необязательный
логический
В объект не записывается.
page[kind] необязательный
строка
В объект не записывается. В ответе остаётся `only_page`.
page[menu_id] необязательный
число
Меню не выбирает. Пункт создаётся в первом меню.
POST /admin/pages.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "page": {
    "title": "docs-api страница",
    "content": "<p>Текст страницы</p>",
    "permalink": "docs-api-page",
    "html_title": "HTML страницы",
    "meta_keywords": "страница",
    "meta_description": "описание страницы",
    "custom_template": "page.custom",
    "created_at": "2014-09-09T00:00:00+04:00",
    "is_hidden": true,
    "kind": "privacy_policy"
  }
}

Ответ · 201

{
  "id": 31,
  "meta_keywords": "страница",
  "meta_description": "описание страницы",
  "is_hidden": false,
  "kind": "only_page",
  "permalink": "docs-api-page",
  "custom_template": "page.custom",
  "created_at": "2014-09-09T00:00:00.000+04:00",
  "updated_at": "2026-10-21T22:15:51.000+03:00",
  "is_main": false,
  "title": "docs-api страница",
  "html_title": "HTML страницы",
  "content": "<p>Текст страницы</p>"
}

Пустой текст отклоняется. В ключе ошибки — content_with_urls.

POST/admin/pages.json
Параметр Описание
page[title] обязательный
строка
Название. Текст в запросе пустой.
POST /admin/pages.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "page": {
    "title": "docs-api без текста"
  }
}

Ответ · 422

{"content_with_urls": ["Добавьте какой-нибудь текст на страницу, даже если она будет скрыта."]}

Занятый permalink создаёт страницу с суффиксом.

POST/admin/pages.json
Параметр Описание
page[title] обязательный
строка
Другое название.
page[content] обязательный
строка
Текст.
page[permalink] обязательный
строка
Permalink, который уже есть у другой страницы.
POST /admin/pages.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "page": {
    "title": "docs-api другая страница",
    "content": "<p>ещё</p>",
    "permalink": "docs-api-page"
  }
}

Ответ · 201

{
  "id": 32,
  "is_hidden": false,
  "kind": "only_page",
  "permalink": "docs-api-page-2",
  "is_main": false,
  "title": "docs-api другая страница",
  "content": "<p>ещё</p>"
}

Изменение страницы

При изменении страницы PUT и PATCH возвращают {"status":"ok"}. Чтобы получить обновлённый объект страницы, выполните отдельный GET-запрос.

PUT/admin/pages/31.json
Параметр Описание
id обязательный
число
id страницы в пути.
page[title] необязательный
строка
Название.
page[content] необязательный
строка
Текст.
PUT /admin/pages/31.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "page": {
    "title": "docs-api страница обновлена",
    "content": "<p>Новый текст</p>"
  }
}

Ответ · 200

{"status": "ok"}
GET/admin/pages/31.json
Параметр Описание
id обязательный
число
id страницы в пути.
GET /admin/pages/31.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{
  "id": 31,
  "meta_keywords": "страница",
  "meta_description": "описание страницы",
  "is_hidden": false,
  "kind": "only_page",
  "permalink": "docs-api-page",
  "custom_template": "page.custom",
  "created_at": "2014-09-09T00:00:00.000+04:00",
  "updated_at": "2026-10-21T22:15:51.000+03:00",
  "is_main": false,
  "title": "docs-api страница обновлена",
  "html_title": "HTML страницы",
  "content": "<p>Новый текст</p>"
}

Удаление страницы

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

Ответ · 200

{"status": "ok"}

Меню

GET /admin/menus.json возвращает все меню без постраничного деления. Пункты не включаются в объект меню; запрашивайте их отдельно.

Поле handle задаёт имя меню латиницей. Допустимы строчные буквы, цифры, дефис и точка. Ошибки этого поля возвращаются под ключом liquid_name.

POST /admin/menus/order.json отвечает 404. Порядок пунктов задаётся полем position.

Создание меню

POST/admin/menus.json
Параметр Описание
menu[name] обязательный
строка
Название.
menu[handle] необязательный
строка
Латинское имя. В ошибке ключ называется `liquid_name`.
menu[used_in_theme] необязательный
логический
Меню используется в теме. По умолчанию `false`.
POST /admin/menus.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu": {
    "name": "docs-api меню",
    "handle": "docs-api-menu"
  }
}

Ответ · 201

{
  "id": 1,
  "name": "docs-api меню",
  "handle": "docs-api-menu",
  "used_in_theme": false
}

Кириллица и пробел в handle отклоняются.

PUT/admin/menus/1.json
Параметр Описание
id обязательный
число
id меню в пути.
menu[handle] обязательный
строка
Имя с символами вне латиницы, цифр, дефиса и точки.
PUT /admin/menus/1.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu": {
    "handle": "Плохой Хэндл"
  }
}

Ответ · 422

{"liquid_name": ["имеет неверное значение"]}

Занятый handle тоже отвечает 422, ключ тот же: «уже существует».

Удаление меню

Тело ответа пустое.

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

Ответ · 200


Пункты меню

GET /admin/menus/:menu_id/items.json возвращает плоский список пунктов меню. Поля родителя нет, поэтому задать вложенность через этот ресурс нельзя. При создании пункты получают последовательные позиции, начиная с 1.

Поле related_object_id связывает пункт меню с объектом магазина. Для страницы, коллекции и блога InSales формирует url автоматически:

related_object_id url в ответе
Page_31 /page/docs-api-page
Collection_53486010 /collection/all
Blog_9 /blogs/docs-api-blog
Page_0 адрес из url
Page_-2 /cart_items
Page_-3 /client_account/login
Page_-5 /compares
Page_-6 /favorites
Page_-7 якорь из url, сохраняется #delivery

Внешняя ссылка без related_object_id сохраняется как Page_0. Произвольный путь тоже: Page_0 и url /page/docs-api-page.

Название уникально внутри меню. Пустое название и неверный адрес отвечают 422, ошибки возвращаются в объекте errors. У блога и страницы объект errors в таком ответе не используется.

Свободное значение position, например 50, сохраняется. Если позиция занята, PUT возвращает 200 и переданное число в теле ответа, но фактическая позиция остаётся прежней. Проверяйте её отдельным GET-запросом.

Удаление пункта отвечает 200 с пустым телом.

Пункт на страницу

POST/admin/menus/1/items.json
Параметр Описание
menu_id обязательный
число
id меню в пути.
menu_item[title] обязательный
строка
Название пункта.
menu_item[related_object_id] обязательный
строка
`Page_` и id страницы. Адрес собирается из permalink.
POST /admin/menus/1/items.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu_item": {
    "title": "docs-api пункт страница",
    "related_object_id": "Page_31"
  }
}

Ответ · 201

{
  "id": 1,
  "position": 1,
  "title": "docs-api пункт страница",
  "url": "/page/docs-api-page",
  "related_object_id": "Page_31"
}

Внешняя ссылка и корзина

POST/admin/menus/1/items.json
Параметр Описание
menu_id обязательный
число
id меню в пути.
menu_item[title] обязательный
строка
Название пункта.
menu_item[url] обязательный
строка
Абсолютный адрес. Пункт сохраняется как `Page_0`.
POST /admin/menus/1/items.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu_item": {
    "title": "docs-api внешняя",
    "url": "https://example.com/docs"
  }
}

Ответ · 201

{
  "id": 25,
  "position": 4,
  "title": "docs-api внешняя",
  "url": "https://example.com/docs",
  "related_object_id": "Page_0"
}
POST/admin/menus/1/items.json
Параметр Описание
menu_id обязательный
число
id меню в пути.
menu_item[title] обязательный
строка
Название пункта.
menu_item[related_object_id] обязательный
строка
`Page_-2` — корзина. Адрес в ответе `/cart_items`.
POST /admin/menus/1/items.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu_item": {
    "title": "docs-api корзина",
    "related_object_id": "Page_-2"
  }
}

Ответ · 201

{
  "id": 33,
  "position": 5,
  "title": "docs-api корзина",
  "url": "/cart_items",
  "related_object_id": "Page_-2"
}

Адрес not a url отвечает 422.

POST/admin/menus/1/items.json
Параметр Описание
menu_id обязательный
число
id меню в пути.
menu_item[title] обязательный
строка
Название пункта.
menu_item[url] обязательный
строка
Строка, которая не является адресом.
POST /admin/menus/1/items.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "menu_item": {
    "title": "docs-api плохой url",
    "url": "not a url"
  }
}

Ответ · 422

{"errors": {"url": ["имеет неверное значение"]}}

JS-теги

JS-тег позволяет добавить код на витрину. GET /admin/js_tags.json возвращает только теги приложения, указанного в авторизации HTTP Basic. Другой ключ получает пустой массив. Попытка прочитать или удалить чужой тег возвращает 404.

В текст JS-тега передавайте JavaScript. Конструкции Liquid остаются текстом и не выполняются. Код подключается на витрине, если у тега enabled: true. Поле enabled принимается и сохраняется, но в JSON-ответ не включается.

Для скрипта в карточке заказа или товара бэк-офиса есть виджеты приложения.

JS-тег может иметь тип JsTag::TextTag или JsTag::FileTag. Тип можно изменить через PUT.

Для TextTag передавайте сам JavaScript без тега script. Если добавить тег, API вернёт 422: «В теле не должно быть тега <script>». Для FileTag передавайте URL файла в content. Если значение не является адресом, ошибка 422 возвращается под ключом url, а не content. Неизвестный тип отклоняется со статусом 422 с ошибками по content, account_id и type; поля не сохраняются.

Текст и файл

POST/admin/js_tags.json
Параметр Описание
js_tag[type] обязательный
строка
`JsTag::TextTag` или `JsTag::FileTag`.
js_tag[content] обязательный
строка
Код без тега `script` либо URL файла.
js_tag[name] необязательный
строка
Название тега.
js_tag[enabled] необязательный
логический
Вывод на витрину. В ответе поля нет.
POST /admin/js_tags.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "js_tag": {
    "type": "JsTag::TextTag",
    "content": "console.log('docs-api')",
    "name": "docs-api text",
    "enabled": false
  }
}

Ответ · 201

{
  "content": "console.log('docs-api')",
  "id": 1,
  "name": "docs-api text",
  "created_at": "2026-10-21T22:15:58.000+03:00",
  "updated_at": "2026-10-21T22:15:58.000+03:00",
  "type": "JsTag::TextTag"
}
POST/admin/js_tags.json
Параметр Описание
js_tag[type] обязательный
строка
`JsTag::FileTag`.
js_tag[content] обязательный
строка
URL скрипта.
js_tag[name] необязательный
строка
Название тега.
POST /admin/js_tags.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "js_tag": {
    "type": "JsTag::FileTag",
    "content": "https://example.com/docs-api.js",
    "name": "docs-api file"
  }
}

Ответ · 201

{
  "content": "https://example.com/docs-api.js",
  "id": 9,
  "name": "docs-api file",
  "created_at": "2026-10-21T22:15:58.000+03:00",
  "updated_at": "2026-10-21T22:15:58.000+03:00",
  "type": "JsTag::FileTag"
}

Тег script в тексте отклоняется. Если для файла передать некорректный URL, ошибка возвращается под ключом url.

POST/admin/js_tags.json
Параметр Описание
js_tag[type] обязательный
строка
`JsTag::TextTag`.
js_tag[content] обязательный
строка
Текст, внутри которого есть тег `script`.
POST /admin/js_tags.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "js_tag": {
    "type": "JsTag::TextTag",
    "content": "<script>alert(1)</script>",
    "name": "docs-api script"
  }
}

Ответ · 422

{"content": ["В теле не должно быть тега <script>"]}

Строка, которая не является адресом, у JsTag::FileTag отвечает 422. Ключ ошибки — url.

POST/admin/js_tags.json
Параметр Описание
js_tag[type] обязательный
строка
`JsTag::FileTag`.
js_tag[content] обязательный
строка
Текст, который не разбирается как URL.
js_tag[name] необязательный
строка
Название тега.
POST /admin/js_tags.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "js_tag": {
    "type": "JsTag::FileTag",
    "content": "не адрес",
    "name": "docs-api bad"
  }
}

Ответ · 422

{"url": ["Невалидный URL-адрес."]}

Неизвестный тип отвечает так, как будто поля не заданы.

POST/admin/js_tags.json
Параметр Описание
js_tag[type] обязательный
строка
Тип вне `JsTag::TextTag` и `JsTag::FileTag`.
js_tag[content] необязательный
строка
Код. При неизвестном типе до проверки содержания не доходит.
POST /admin/js_tags.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "js_tag": {
    "type": "JsTag::Other",
    "content": "alert(1)",
    "name": "x"
  }
}

Ответ · 422

{
  "content": ["Не заполнены обязательные поля"],
  "account_id": ["Не заполнены обязательные поля"],
  "type": ["Unknown type"]
}

Удаление JS-тега

DELETE/admin/js_tags/9.json
Параметр Описание
id обязательный
число
id тега этого приложения.
DELETE /admin/js_tags/9.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

{"status": "ok"}

Редиректы

Для создания редиректа используйте POST /admin/redirects.json. Изменение не поддерживается: PUT и PATCH возвращают 404. Удаляйте редиректы по одному через DELETE; успешный ответ содержит {"status":"ok"}. Метода массового удаления нет.

Витрина отвечает 301 на адрес, который находится по правилам ниже. Редирект действует на запрос страницы. Адрес с суффиксом .json витрина по этим правилам не перенаправляет.

По умолчанию список содержит до 100 записей. У per_page нет нижней границы. Порядок записей не задан, поэтому одна запись может попасть на несколько страниц. При сборе списка увеличьте per_page или исключайте повторы по id.

q[q] ищет подстроку в старом и новом адресе. q[c_from] и q[c_to] ограничивают created_at по часовому поясу магазина.

Создание

При сохранении старого адреса InSales удаляет схему и хост, оставляя путь. Например, https://example.com/from-outside сохраняется как /from-outside. Завершающий / также удаляется. При этом запрос витрины с завершающим / не совпадёт с сохранённым правилом.

Новый адрес на домене магазина также сохраняется как путь без завершающего /: https://abc.myinsales.ru/catalog/ станет /catalog. Адрес другого сайта сохраняется целиком: https://example.com/catalog.

Одинаковые старый и новый адреса отвечают 422, ключ new_url: «имеет неверное значение».

Нельзя создать редирект с корня / или с адреса, первый сегмент которого входит в список ниже. Для /delivery возвращается ошибка «Недопустимый URL. Путь '/delivery/' не может быть использован в качестве первой составной части старого URL.». Для корня в таком же сообщении указан путь ///.

Запрещённый первый сегмент: orders, cart_items, payments, auth, address, delivery, payment, fast_checkout, new_order, compares, cities, bank_receipts, yandex_market, yandex_snippets, torg_mail, sitemap, robots, juridical_person_receipts, yandex_market_fast_checkout, counter_settings, codes_settings.

POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Старый адрес. Абсолютный сохраняется путём.
redirect[new_url] обязательный
строка
Новый адрес.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "/docs-api-old",
    "new_url": "/page/docs-api-page"
  }
}

Ответ · 201

{
  "id": 1,
  "old_url": "/docs-api-old",
  "new_url": "/page/docs-api-page",
  "created_at": "2026-10-21T22:16:05.251+03:00"
}

Абсолютные адреса своего домена myinsales становятся путями.

POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Абсолютный адрес. В ответе остаётся путь.
redirect[new_url] обязательный
строка
Адрес на поддомен.myinsales. В ответе возвращается путь без завершающего /.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "https://example.com/from-outside",
    "new_url": "https://abc.myinsales.ru/catalog/"
  }
}

Ответ · 201

{
  "id": 11,
  "old_url": "/from-outside",
  "new_url": "/catalog",
  "created_at": "2026-10-21T22:26:54.750+03:00"
}

Чужой новый адрес остаётся абсолютным.

POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Старый путь.
redirect[new_url] обязательный
строка
Адрес другого сайта.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "/docs-api-out",
    "new_url": "https://example.com/catalog"
  }
}

Ответ · 201

{
  "id": 3,
  "old_url": "/docs-api-out",
  "new_url": "https://example.com/catalog",
  "created_at": "2026-10-21T22:16:05.613+03:00"
}

/delivery отклоняется.

POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Путь с запрещённым первым сегментом.
redirect[new_url] обязательный
строка
Новый адрес.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "/delivery",
    "new_url": "/page/docs-api-page"
  }
}

Ответ · 422

{"old_url": ["Недопустимый URL. Путь '/delivery/' не может быть использован в качестве первой составной части старого URL."]}

Цепочки

При создании редиректа InSales проверяет, не образуется ли цепочка. Старый адрес новой записи не должен совпадать с новым адресом существующей, а новый адрес — со старым адресом другой записи. При совпадении API возвращает 422.

«Уже существует редирект на адрес ...» — ключ old_url. «Уже существует редирект с адреса ...» — ключ new_url.

Чтобы объединить цепочку, передайте remove_redirect_chains: 1. InSales создаст новую запись и изменит конечный адрес существующих редиректов, которые вели на её старый адрес. Идентификаторы существующих записей сохранятся.

POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Адрес, который уже стоит новым у другого редиректа.
redirect[new_url] обязательный
строка
Новый адрес.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "/page/docs-api-page",
    "new_url": "/docs-api-next"
  }
}

Ответ · 422

{"old_url": ["Нельзя создавать цепочки редиректов. Уже существует редирект на адрес /page/docs-api-page"]}
POST/admin/redirects.json
Параметр Описание
redirect[old_url] обязательный
строка
Старый адрес новой записи.
redirect[new_url] обязательный
строка
Адрес, на который перепишутся прежние редиректы.
redirect[remove_redirect_chains] обязательный
число
`1` разрешает цепочку и переписывает прежние новые адреса.
POST /admin/redirects.json
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json
Content-Type: application/json

{
  "redirect": {
    "old_url": "/page/docs-api-page",
    "new_url": "/docs-api-final",
    "remove_redirect_chains": 1
  }
}

Ответ · 201

{
  "id": 7,
  "old_url": "/page/docs-api-page",
  "new_url": "/docs-api-final",
  "created_at": "2026-10-21T22:16:06.001+03:00"
}

Повтор того же старого адреса отвечает 422: «Для указанного URL редирект уже настроен». Регистр различается: /Docs-Api-Case не совпадает с правилом /docs-api-case.

Список и фильтр

GET/admin/redirects.json?q[q]=docs-api-old
Параметр Описание
per_page необязательный
число
Размер страницы. По умолчанию 100. Нижней границы нет.
page необязательный
число
Номер страницы. Порядок записей не фиксирован.
q[q] необязательный
строка
Подстрока старого или нового адреса.
q[c_from] необязательный
строка
Начало интервала `created_at`.
q[c_to] необязательный
строка
Конец интервала `created_at`.
GET /admin/redirects.json?q[q]=docs-api-old
Authorization: Basic API_KEY:API_PASSWORD
Accept: application/json

Ответ · 200

[
  {
    "id": 1,
    "old_url": "/docs-api-old",
    "new_url": "/docs-api-final",
    "created_at": "2026-10-21T22:16:05.251+03:00"
  }
]

Новый адрес в ответе уже переписан правилом remove_redirect_chains.

Как витрина выбирает адрес

Пока среди редиректов нет старых адресов с ?, InSales сравнивает только путь запроса и переносит параметры URL на новый адрес. Правило со знаком ? в старом адресе в этом режиме не применяется.

При добавлении первого правила с ? запрос POST может вернуть 500 без сохранения записи. При этом магазин переключается на точное сравнение адресов. Повторный такой же POST возвращает 201.

В режиме точного сравнения должны совпасть и путь, и параметры URL. Параметры domain и locale отбрасываются. Параметры _ga, tagtag_uid, erid, gsaid, advcake_params, utm_source, utm_medium, utm_campaign, yclid, ysclid, utm_referrer, utm_content и utm_term не влияют на совпадение и переносятся на новый адрес.

Параметр page влияет на сравнение: адрес с page не совпадёт с правилом без параметров URL.

Знак * в конце старого адреса позволяет сопоставить этот путь как с параметрами URL, так и без них. Более длинные пути с правилом не совпадают. Регулярные выражения не поддерживаются.

Повторяющиеся слэши в пути заменяются одним, даже если для адреса нет отдельного редиректа. Например, /foo//bar перенаправляется на /foo/bar.

В таблице цель цепочки — /docs-api-final. В колонке «точный режим» среди редиректов есть старый адрес с ?. В колонке «только путь» таких редиректов нет.

Запрос Точный режим Только путь
/docs-api-old /docs-api-final /docs-api-final
/docs-api-old?utm_source=ads /docs-api-final?utm_source=ads /docs-api-final?utm_source=ads
/docs-api-old?page=2 совпадения нет /docs-api-final?page=2
/docs-api-q?color=red /docs-api-final правило с ? не используется
/docs-api-q?color=blue совпадения нет правило с ? не используется
/docs-api-q?utm_source=ads совпадения нет правило с ? не используется
/docs-api-wild и /docs-api-wild?x=1 /docs-api-final /docs-api-final, query дописывается
/docs-api-wild/extra совпадения нет совпадения нет
/page/docs-api-page?utm_source=ads&page=2 совпадения нет /docs-api-final?utm_source=ads&page=2

Удаление редиректа

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

Ответ · 200

{"status": "ok"}