Diil Docs
  1. Документація
  2. Довідник API

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

Оновлено:

Іноді вам не потрібна ні сторінка, ні навіть секція — потрібна рівно одна річ. Телефон у шапці. Промобанер над магазином. Ціна, яку маркетинг змінює щоп’ятниці. Цей endpoint віддає один блок за його маркером — і більше нічого.

Типові кандидати:

  • Телефон чи email у шапці — блок text, що живе на службовій сторінці common і показується всюди.
  • Промобанер — блок object із заголовком, зображенням і посиланням, який ви вставляєте в макет, що вже рендериться з коду.
  • Ціна — блок number, який ваш checkout чи лендинг читає, не завантажуючи всю сторінку з тарифами.

Отримати один блок

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 був би порожньою коробкою. До цього endpoint параметр просто не застосовується.

Приклад запиту

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": "Phone in header",
  "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": "Promo banner",
  "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": "Base plan price",
  "type": "number",
  "multilang": false,
  "updatedAt": "2026-09-26T16:20:00.000Z",
  "content": 149
}

Числа, кольори, дати, діапазони дат і булеві значення повертаються як сире збережене значення (або null, якщо порожньо) — без карти мов, тож ?lang їх не зачіпає. Усі форми перелічено на сторінці Типи блоків.

Поля відповіді

idnumber
Внутрішній id блоку. Стабільний, але в коді краще спиратися на маркери — id відрізняються між середовищами.
markerstring
Маркер блоку — той самий, що ви підставили в URL.
namestring
Людська назва з CRM («Phone in header»). Призначена для редакторів — не виводьте її на сторінці.
typestring
Одне з text, html, image, video, link, number, color, date, date_range, boolean, object, array. Перевіряйте його, перш ніж читати content, якщо той самий компонент рендерить різні блоки.
multilangboolean
Для зображень і відео: true, якщо в кожної мови свій файл, і тоді content — це карта URL за мовами замість одного 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"

# Точно: title секції 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;

Endpoint для одного блоку сяє, коли вам справді потрібне одне значення в місці, яке більше ніяк не пов’язане з тією сторінкою, — телефон у глобальній шапці, банер у макеті, ціна у віджеті оформлення замовлення.

Помилки

СтатусТілоЩо сталося
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"