Diil Docs
  1. Документация
  2. Справочник API

GET /v1/blocks/:marker — один блок

Обновлено:

Иногда не нужна ни страница, ни даже секция — нужна ровно одна вещь. Телефон в шапке. Промо-баннер над каталогом. Цена, которую маркетинг меняет каждую пятницу. Этот запрос отдаёт один блок по маркеру — и больше ничего.

Типичные кандидаты:

  • Телефон или почта в шапке — блок text на служебной странице common, который виден на всех страницах.
  • Промо-баннер — блок object с заголовком, картинкой и ссылкой, который встраивается в вёрстку, собранную в коде.
  • Цена — блок number, который корзина или посадочная страница читает, не загружая всю страницу тарифов.

Получить один блок

GET/v1/blocks/:marker

https://back.sitecog.com/content/v1/blocks/:marker

Один блок со значением в content. Устроен так же, как блок внутри ответа страницы или секции, — только без обёртки.

Параметры

markerpathstringобязательно
Маркер блока из CRM, например phone или promo_banner. Латиница, цифры и подчёркивание, от 2 до 40 символов, регистр важен.
sectionquerystringнеобязательноПо умолчанию: любая секция
Маркер секции, в которой лежит блок, например ?section=header. Маркеры блоков уникальны только внутри секции, и так вы говорите, какой именно title имеете в виду. Без него побеждает первое совпадение — самый старый блок с таким маркером. Подробнее — ниже.
langquerystringнеобязательноПо умолчанию: все активные языки
Оставить переводы только на этих языках: ?lang=en, ?lang=en,de или ?lang=en&lang=de. Каждый код должен быть активным языком сайта, иначе придёт 400 unknown_lang. На значения без переводов — числа, цвета — не влияет.
x-crm-keyheaderstringобязательно
Ключ сайта. Если заголовок передать нельзя, подойдёт ?key=. Подробнее — в разделе Ключ сайта.

?empty здесь нет: блок без content — это пустая коробка. К этому запросу параметр просто не относится.

Пример запроса

curl "https://back.sitecog.com/content/v1/blocks/phone?section=header&lang=en" \
  -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

Примеры ответов

Обёртка всегда одна и та же, от типа блока меняется только content.

Текстовый блок

200 OK — GET /v1/blocks/phone?section=headerjson
{
  "id": 88,
  "marker": "phone",
  "name": "Телефон в шапке",
  "type": "text",
  "multilang": true,
  "updatedAt": "2026-09-12T07:45:10.000Z",
  "content": { "en": "+66 2 123 4567", "de": "+66 2 123 4567" }
}

Текст — это карта переводов: по ключу на язык, в порядке CRM. Языка, для которого значение ни разу не сохраняли, в карте просто нет; если значение есть, но пустое, придёт "". Запасного языка на стороне сервера нет — выбирайте его сами, помощник есть в разделе Советы.

Блок-объект

200 OK — GET /v1/blocks/promo_banner?section=promojson
{
  "id": 131,
  "marker": "promo_banner",
  "name": "Промо-баннер",
  "type": "object",
  "multilang": false,
  "updatedAt": "2026-09-28T10:05:00.000Z",
  "content": {
    "title": { "en": "Autumn sale: 20% off", "de": "Herbst-Sale: 20 % Rabatt" },
    "image": { "file": "https://cdn.example.com/storage/your-site/autumn.jpg" },
    "link": {
      "url": "https://example.com/sale",
      "target": "_self",
      "title": { "en": "Shop now", "de": "Jetzt kaufen" }
    },
    "ends": "2026-10-15",
    "active": true
  }
}

Объект — это набор полей, ключ — маркер поля, и каждое поле подчиняется тем же правилам, что и отдельный блок: текстовые поля — карты переводов, ссылка — { url, target, title }, картинка — { file } (или карта файлов по языкам), числа, даты и флаги — как сохранены. Приходят только значения, описание полей остаётся в CRM.

И цена

200 OK — GET /v1/blocks/price?section=pricingjson
{
  "id": 140,
  "marker": "price",
  "name": "Цена базового тарифа",
  "type": "number",
  "multilang": false,
  "updatedAt": "2026-09-26T16:20:00.000Z",
  "content": 149
}

Числа, цвета, даты, периоды и флаги приходят как есть — сохранённым значением (или null, если пусто). Карты переводов у них нет, так что ?lang их не трогает. Все варианты — на странице Типы блоков.

Поля ответа

idnumber
Внутренний id блока. Не меняется, но в коде лучше опираться на маркеры — id на разных средах разные.
markerstring
Маркер блока — тот же, что вы указали в адресе.
namestring
Название из CRM («Телефон в шапке»). Оно для редакторов — на страницу его не выводите.
typestring
Один из типов: text, html, image, video, link, number, color, date, date_range, boolean, object, array. Если один компонент выводит разные блоки, проверяйте тип, прежде чем читать content.
multilangboolean
Для картинок и видео: true, если у каждого языка свой файл, — тогда в content не один file, а адреса по языкам.
updatedAtstring (ISO 8601)
Когда блок правили последний раз. Пригодится для подписи «цены обновлены…» и для ключей кэша.
contentзависит от type | null
Само значение: карта переводов у text и html, { file } у одиночной картинки или видео, { url, target, title } у ссылки, объект полей у object, массив таких объектов у array, сырое значение (или null) у чисел, цветов, дат и флагов. Подробности — на странице Типы блоков.

Маркеры уникальны внутри секции — уточняйте ?section

Маркер блока обязан быть уникальным только в своей секции. Поэтому редакторы могут давать блокам нормальные имена: в секции hero есть title, в секции faq тоже есть title, и никому не приходится выдумывать title_2_final.

Обратная сторона: просто /v1/blocks/title — это неоднозначно. Без ?section API вернёт первое совпадение — самый старый блок с таким маркером. Не факт, что тот, который вы имели в виду, и он может смениться, если кто-то пересоздаст блок. Добавьте секцию — и ответ станет точным:

# Неоднозначно: какой "title" создали раньше, тот и придёт
curl "https://back.sitecog.com/content/v1/blocks/title" -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

# Точно: заголовок секции FAQ
curl "https://back.sitecog.com/content/v1/blocks/title?section=faq" -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

Не собирайте блоки по одному

Не надо: водопад мелких запросовjs
const title = await getBlock('title', 'promo');
const text = await getBlock('text', 'promo');
const image = await getBlock('image', 'promo');
Надо: один запрос, те же данныеjs
const promo = await fetch('https://back.sitecog.com/content/v1/sections/promo?lang=en', {
  headers: { 'x-crm-key': 'pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40' },
}).then((r) => r.json());
const { title, text, image } = promo.content;

Запрос одного блока хорош, когда вам действительно нужно одно значение там, где остальная страница ни при чём: телефон в общей шапке, баннер в макете, цена в виджете оформления заказа.

Ошибки

СтатусТело ответаЧто случилось
400{"message":"invalid_marker"}В маркере есть символы кроме A–Z a–z 0–9 _ или не та длина.
400{"message":"invalid_lang", …}Код в lang записан неправильно.
400{"message":"unknown_lang", …}Язык из lang не активен на сайте. В теле ответа — список доступных.
401{"message":"invalid_key"}Ключа нет, он неправильного вида или отозван.
404{"message":"block_not_found"}Блока с таким маркером нет — или его нет в секции, указанной в ?section.
429{"message":"rate_limit_exceeded"}Слишком много запросов за эту минуту. См. Лимиты.

Полный список с подсказками, что делать, — на странице Ошибки.

Советы из практики

// нужный язык → язык по умолчанию → первое непустое значение
export function t(map: Record<string, string> | undefined, lang: string, fallback = 'en') {
  if (!map) return '';
  return map[lang] || map[fallback] || Object.values(map).find(Boolean) || '';
}

t(phone.content, 'de'); // "+66 2 123 4567"