Headless-управление контентом

Контент необязательно вести руками. Страницы, блоки и меню создаются и правятся обычными HTTP-запросами к API платформы — тем же контуром, которым работает её интерфейс. Отдельного «CMS API» в Gigma нет: интерфейс платформы и ваш скрипт вызывают одни и те же методы.

Витрина при этом ничего не знает про этот контур: она по-прежнему читает готовый контент по App Token — см. обзор раздела.

Когда это нужно

  • Перенос со старого сайта. Страницы и баннеры заливаются скриптом, а не переносятся вручную.
  • Контент приходит из внешней системы. Каталог статей, прайс-лист в баннере, расписание — синхронизируются по расписанию.
  • Свой редактор. Если редакции удобнее работать в вашем интерфейсе, он ходит в API платформы, а платформа остаётся хранилищем.
  • Массовые правки. Заменить телефон на сорока страницах или пересобрать меню — цикл по методам, а не сорок открытых вкладок.
  • MCP-агент. Технически агент вызывает те же методы, но контентная поверхность пока не входит в рекомендованные профили: перед выдачей таких инструментов агенту прочитайте P4 «Приложения и контент».

Доступ

Authorization: Bearer <access_token>

Токен сотрудника получают обычным входом — доступ сотрудников. Для автоматизации заведите отдельную техническую учётную запись или агента, чтобы не делить токен живого человека.

Этот токен — серверный секрет. Он не должен попадать во фронтенд: ни в витрину, ни в админку, которая работает в браузере. Правка контента из браузера идёт через ваш backend.

Порядок работы

1. Application id ──> 2. справочники ──> 3. файлы ──> 4. объект ──> 5. проверка
   что наполняем       page_types,        POST         POST         GET по App
                       block_types        /api/files   /api/pages   Token
  1. Определите приложение. Весь контент привязан к Applicationсписок приложений.
  2. Возьмите справочники. page_types, block_types, page_tags, file_types — их id нужны в теле запроса. Не фиксируйте id по примерам из документации, читайте справочник.
  3. Загрузите файлы заранее. Картинки и документы сначала попадают в файлы, в контент подставляется полученный id.
  4. Создайте объект — страницу, блок или пункт меню.
  5. Проверьте чтением витринного контура — тем же запросом, который делает сайт.

Карта методов

Страницы и публикации

ДействиеМетодКонтракт
СписокGET /api/tables/pagesсписок страниц
КарточкаGET /api/pages/{id}страница
СоздатьPOST /api/pagesсоздание
ИзменитьPUT /api/pages/{id}обновление
УдалитьDELETE /api/pages/{id}удаление
История правокGET /api/pages/{id}/historyистория
ТегиGET /api/page_tagsтеги

Контентные блоки

Блоки живут внутри приложения, поэтому его id стоит в пути.

ДействиеМетодКонтракт
СписокGET /api/applications/{application}/blocksсписок блоков
КарточкаGET /api/applications/{application}/blocks/{block}блок
СоздатьPOST /api/applications/{application}/blocksсоздание
ИзменитьPUT /api/applications/{application}/blocks/{block}обновление
УдалитьDELETE /api/applications/{application}/blocks/{block}удаление
История правокGET /api/applications/{application}/blocks/{block}/historyистория

Меню витрины

ДействиеМетодКонтракт
Список пунктовGET /api/applications/{application}/menu_itemsпункты меню
СоздатьPOST /api/applications/{application}/menu_itemsсоздание
ИзменитьPUT /api/applications/{application}/menu_items/{menu_item}обновление
УдалитьDELETE /api/applications/{application}/menu_items/{menu_item}удаление
Поднять в порядкеPOST /api/applications/{application}/menu_items/{menu_item}/upвыше
Опустить в порядкеPOST /api/applications/{application}/menu_items/{menu_item}/downниже

Файлы

ДействиеМетодКонтракт
ЗагрузитьPOST /api/filesзагрузка
Типы файловGET /api/file_typesсправочник
УдалитьDELETE /api/files/{id}удаление

Поля, от которых зависит витрина

Страница. Обязательны application_id, page_type_id, is_page, slug, title, content. is_page — флаг платформы «страница или не страница»; на выдачу витрине он не влияет: список pages отдаёт всё, что заведено приложению. Витрина запрашивает страницу по slug, поэтому он и есть публичный адрес. description, meta_title, meta_description, preview_id и tags — для карточек и выдачи. content хранится как есть и приходит на сайт HTML-строкой: экранирование и санитизация — на вашей стороне.

Блок. Обязательны name и block_type_id, остальное зависит от типа: текст и длинный текст требуют text, изображение — file_id, видео и ссылка — link. parent_id собирает блоки в дерево: витрина, запрашивая родителя, получает children целиком — так делается секция из нескольких карточек.

Витрина забирает блок по code или по identifier. code проставляет сама база: при создании он всегда перезаписывается на следующий номер в пределах проекта, поэтому переданное значение не сохранится, а сам номер зависит от порядка создания и на разных стендах различается. Если фронтенд должен обращаться к блоку по понятному ключу, задавайте identifier при создании и читайте блок методом blocks/id/{identifier}.

Пункт меню. Обязателен name. У slug две роли: у корневого пункта это имя меню, по которому витрина запрашивает всё дерево (GET /api/counterparty/menus/{slug}, по умолчанию navpanel), у вложенных — адрес ссылки, он приходит на витрину полем url. parent_id задаёт вложенность, order — порядок внутри уровня: если его не передать, пункт встаёт последним, а up и down двигают пункт на одну позицию и пересчитывают соседей.

Проверка результата

Проверять правку нужно тем же запросом, которым её увидит сайт, и с App Token — а не тем методом, которым правили:

GET /api/counterparty/pages/legal-offer HTTP/1.1
Host: api.gigma.ru
Token: <application_token>
Accept: application/json

Ответ платформы на POST подтверждает запись, но не то, что контент попал в нужное приложение: application_id мог указывать на другое.

При неизвестном slug метод витрины может вернуть резервную страницу вместо 404. Сравнивайте page.slug в ответе с запрошенным значением, иначе успешной публикацией будет выглядеть промах.

Ограничения

  • slug страницы уникален по всей базе, а не в рамках приложения. Двум сайтам одного проекта не удастся завести /about обоим — давайте slug различимые имена.
  • Черновиков и отложенной публикации нет. Сохранённое сразу доступно витрине; переключатель «показывать или нет» держите на своей стороне.
  • Слайдер только читается. Метод GET /api/counterparty/slides есть, методов управления слайдами в API нет — они заводятся в интерфейсе платформы. См. рекламные слайды.
  • Вебхуков на изменение контента нет. Приложению доступно единственное событие order.paidwebhooks. Если кэшируете контент у себя, сбрасывайте кэш сами: после правки или по расписанию.
  • Удаление немедленное. Корзины нет; остаётся только история правок объекта.
  • Разграничение доступа к контенту не проверяется на уровне маршрута. У страниц, блоков и пунктов меню нет ни policy, ни can:-middleware: объект находится по переданному id, а принадлежность его вашему проекту backend не подтверждает. Считайте, что ошибочный id в скрипте синхронизации может уехать не туда, проверяйте принадлежность на своей стороне, выдавайте токен только доверенному серверному коду и не смешивайте его с учётной записью для других задач. Тот же разрыв — причина, по которой контентные методы не входят в рекомендованные профили агентов: P4 «Приложения и контент».

© 2026 Gigma