Markdown
Markdown — родной язык ИИ-агентов, на нем они пишут ответы в чатах. Поэтому страницу в OnPress агент получает и отправляет одним документом в Markdown, без HTML и верстки. Это позволяет агенту публиковать и изменять контент максимально быстро: одна правка текста — один запрос. В начале документа стоят свойства страницы с адресом, языком, фреймом и SEO, за ними идет текст.
Как создать, прочитать, изменить и удалить страницу, рассказано на странице Страницы, а все эндпоинты собраны в справочнике API.
Свойства страницы
Свойства страницы, или frontmatter, — строки ключ: значение между двумя строками --- в самом начале документа. Они задают все, кроме текста страницы, то есть заголовок, адрес, язык, фрейм, SEO и служебные поля. Например:
---
name: "Тарифы"
slug: "tarify"
url: "/company/tarify/"
lang: "ru"
status: "publish"
frame: "article"
excerpt: "Три тарифа и что в них входит."
seo_title: "Тарифы OnPress — цены и возможности"
seo_description: "Сколько стоит OnPress и что входит в каждый тариф."
focus_keyword: "тарифы onpress"
topic: "Цены"
---
Формат
API разбирает свойства по упрощенным правилам, а не как полный YAML.
- Одна строка задает одно поле в виде
ключ: значение. Списков и многострочных значений нет. Вложенные ключи есть только подdata:, о них рассказано в разделе Свои ключи. - Значением API считает все, что стоит после первого двоеточия, поэтому двоеточия внутри значения допустимы.
- Кавычки вокруг значения, двойные или одинарные, API снимает. Внутри кавычек допустимы любые символы, включая
#и:. - Строку, которая начинается с
#, API пропускает как комментарий. - Все значения API читает как строки. Флаг включают значения
true,1,yesиonв любом регистре, остальные его выключают. - Ключи чувствительны к регистру.
Slugдля API другой ключ, незнакомый, а неslug.
Ставьте свойства в самое начало документа. Без них API создаст страницу без названия, адреса, языка и фрейма.
Заголовок и адрес
| Поле | Что делает |
|---|---|
name | Заголовок страницы. Теги вырезаются. Из заголовка собирается слаг, если slug не указан |
slug | Слаг — последний сегмент адреса. Приводится к виду адреса: нижний регистр, транслитерация кириллицы, пробелы в дефисы. Уникален среди соседей одного языка: занятый получит суффикс -2, и ответ скажет об этом в slug_changed |
url | Полный путь страницы: /company/tarify/. Все сегменты кроме последнего — существующие страницы-родители. Родителей API не создает: если родителя нет, запись вернет 422 parent_not_found, поэтому опубликуйте сначала родителя. Последний сегмент — сама страница, но ее слаг берется из slug, а не отсюда. Языковой префикс (/ru/…) распознается и отбрасывается. Схема и домен — 422 absolute_url_in_path |
parent | Id родителя числом, если url не указан; 0 — верхний уровень. При url игнорируется |
id | Обновить именно эту страницу. Страница другого языка — 409 lang_mismatch |
Если не указаны ни url, ни parent, при создании страница встает на верхний уровень, а при обновлении остается там, где была.
Ключа redirect у страницы нет: редирект — правило сайта, а не поле страницы, см. Редиректы. Присланный ключ не записывается, ответ публикации несет предупреждение.
Сменили у опубликованной страницы slug или родителя в url (публикация с id) — старый адрес не пропадает: правило 301 на новый заводится само, для страницы и каждого ее опубликованного потомка, а ответ перечисляет их в redirects_created. Подробно и как это выключить — автоправила. Смена lang у существующей страницы через публикацию не делается (409 lang_mismatch).
Язык и переводы
| Поле | Что делает |
|---|---|
lang | Слаг языка сайта (ru, en). Не указан — язык сайта по умолчанию и предупреждение. Язык, которого на сайте нет, — 422 unknown_language со списком. На сайте без языков игнорируется с предупреждением |
translation_of | Оригинал, переводом которого является страница: id, слаг или путь (можно с языковым префиксом). Требует lang, отличный от языка оригинала. Страница вступает в группу переводов оригинала в той же транзакции, что и запись. Подробно — перевод страницы |
Вид
| Поле | Что делает |
|---|---|
frame | Фрейм страницы: слаг или id, ровно один. Пустое значение снимает фрейм. Список в любой форме (a, b, [a, b], header=…) — 400 frame_single. Фрейма нет на этом сайте — 404 frame_not_found. Поле frame в теле запроса перекрывает свойство frame |
Без фрейма страница на сайте v2 отвечает 404 — ставьте frame в каждой публикации.
Статус и даты
| Поле | Что делает |
|---|---|
status | publish (по умолчанию), draft, pending, private, future. Любое другое значение — 400 invalid_status. publish или future с датой впереди сохраняется как future — страница запланирована и выйдет сама; future с прошедшей датой — publish. Снять планирование — сохранить страницу со status: draft |
date | Дата публикации: местное время сайта 2026-10-05 09:00 (секунды и T вместо пробела допустимы) или точный момент — ISO 8601 с Z или смещением (2026-10-05T06:00:00Z, …+03:00), либо unix-секунды. Дата впереди откладывает публикацию, см. отложенная публикация. Без date новая страница получает текущее время, существующая сохраняет свою дату. Не дата — 400 invalid_date |
Текст вокруг страницы
| Поле | Куда пишется |
|---|---|
excerpt | Выдержка: лид под заголовком, описание в списках. Указана — пишется, "" — очищается, не указана — не трогается. Отдельно правится PATCH /pages/{ref} |
image | Превью страницы: номер вложения из медиатеки или адрес картинки, в том числе короткий /media/…. Своя картинка узнается по адресу без скачивания, чужая заливается в медиатеку, повтор того же адреса берет то же вложение. "" — снимает превью, нет ключа — не трогает. Превью становится og:image страницы, обложкой страницы во фрейме и картинкой в карточках дочерних страниц. Отдельно правится PATCH /pages/{ref} полем thumbnail. Отказы — 400 image_invalid, 404 image_not_found, 422 image_not_image |
SEO
| Поле | Куда пишется |
|---|---|
seo_title | Заголовок для поиска (<title>) — SEO-поле страницы. API записывает его, только если значение не пустое, поэтому пустое свойство заголовок не очищает |
seo_description | Мета-описание — SEO-поле страницы. То же правило пустого значения |
focus_keyword | Фокусный ключ страницы. |
noindex | true закрывает страницу от поисковиков, false открывает; поле не указано — не трогается. Другое значение — 400 invalid_noindex |
SEO-настройки уровня сайта — шаблоны заголовков, разделитель, карта сайта — на странице SEO.
Служебные поля
| Поле | Что делает |
|---|---|
topic | Тема страницы — термин таксономии topic. Одно значение: "SEO, контент" станет одним термином с запятой в имени, а не двумя |
target | Метаполе _onpress_page_target: страница, на которую эта должна ссылаться (для перелинковки). "" или "0" удаляют |
anchor | Метаполе _onpress_page_anchor: анкор этой ссылки. "" или "0" удаляют |
Свои ключи
Вы можете записать в свойства страницы любые свои ключи, например время чтения, рейтинг или цену, и потом выводить их в тексте страницы или во фрейме. API сохраняет такие ключи в данные страницы, а ответ на запись перечисляет их в поле data_keys.
---
name: "Статья"
slug: "statya"
reading_time: "7 минут"
---
{
"success": true,
"data_keys": ["reading_time"],
"data_keys_note": "Custom keys saved to page data as page.data.*: reading_time. They are not page properties. If you meant a page property, check its name."
}
Поле data_keys_note объясняет, что это пользовательские ключи, а не свойства страницы. Если вы хотели задать свойство, а написали seo_titel вместо seo_title, проверьте имя ключа по таблицам выше.
Тот же ключ можно записать как data.reading_time или вложить под data:, результат одинаковый. Выгрузка GET /pages/{ref}/markdown возвращает свои ключи в той форме и в том порядке, в каком их записали, поэтому круг «выгрузил, поправил, отправил» их не теряет. Пустое значение API не записывает.
Фрейм выводит это значение по имени page.data.reading_time. Как это устроено, рассказано на странице Бинды.
Например, готовые фреймы из каталога читают такие свои ключи:
| Ключ | Что делает |
|---|---|
nav_label | короткая подпись страницы в сайдбаре документации, если полное название не помещается в дерево |
cta | при cta: 1 фрейм site__cta выводит на странице общий призыв к действию из набора cta |
author | при author: 1 фрейм article выводит под заголовком подпись автора из набора author и добавляет автора в разметку страницы |
Ключи с подчеркиванием в начале API не записывает и перечисляет в warnings.
Текст страницы
API понимает основную разметку Markdown: заголовки, абзацы, списки, таблицы, ссылки, картинки и код. Все, что можно писать в тексте страницы, описано ниже.
Абзацы и переносы
Абзацы разделяйте пустой строкой. Перенос строки внутри абзаца API превращает в перенос <br>, а не в пробел, поэтому каждый абзац пишите одной строкой.
Первый абзац одной строкой.
Второй абзац.
Эта строка встанет на новую строку внутри второго абзаца.
Заголовки
Пишите # … ###### и пробел, уровень заголовка API не меняет. Платформа ставит каждому заголовку H2–H6 якорь из его текста: ## Как это работает получает #kak-eto-rabotaet, а повторы получают хвост -1, -2. Чтобы якорь не менялся при переименовании заголовка, задайте свой в конце строки: ## Как это работает {#kak}. Чтобы сослаться на заголовок из текста, укажите его якорь: [см. ниже](#kak).
Выделение, код и ссылки
Выделение, код и ссылки внутри абзаца пишите так:
| Пишете | Получаете |
|---|---|
**жирный** | жирный |
*курсив* | курсив |
| текст в обратных кавычках | код |
[ссылка](/docs/v2/ru/guides/) | ссылка |
Звездочка ищет пару до конца строки, поэтому pages.* и menu.* без обратных кавычек превратятся в курсив. Имена полей, пути и код заключайте в обратные кавычки, а одиночную звездочку в тексте пишите как \*. Адрес без квадратных и круглых скобок останется текстом и ссылкой не станет.
Списки
Пункт маркированного списка начинайте с - и пробела, пункт нумерованного списка — с цифры, точки и пробела.
- пункт
- еще пункт
1. первый
2. второй
API нумерует список с единицы, какие бы цифры вы ни написали. Вложенных списков нет: пункт с отступом станет отдельным абзацем и разорвет список. Абзац с числом и точкой в начале, например 2026. Год…, тоже станет нумерованным списком.
Цитаты
Каждую строку цитаты начинайте с > и пробела. Строки подряд API собирает в одну цитату и ставит каждую с новой строки.
> Первая строка цитаты
> вторая строка
Таблицы
Первая строка таблицы становится шапкой, а строка из дефисов под ней отделяет шапку от остальных строк.
| Город | Население |
|---|---|
| Москва | 13 млн |
| Казань | 1,3 млн |
Вертикальная черта делит ячейки даже внутри обратных кавычек. Чтобы показать черту в ячейке как текст, напишите \| вне обратных кавычек.
Чтобы задать ширину колонок, сделайте разделитель под шапкой разной длины: число дефисов задает долю ширины. Двоеточие слева от дефисов прижимает текст колонки к левому краю, справа — к правому, а с обеих сторон ставит его по центру. Например, в этой таблице колонка «Город» займет четверть ширины с текстом по левому краю, а «Население» — три четверти с текстом по правому:
| Город | Население |
|:---|---------:|
| Москва | 13 млн |
| Казань | 1,3 млн |
Когда в каждой колонке разделителя дефисов поровну, как в |---|---|, API ширину колонок не задает.
Код
Код поставьте между двумя строками из трех обратных кавычек, а сразу после первых кавычек напишите имя языка, например bash, json или html.
```bash
curl -s "$API/health"
```
Все между кавычками API выводит как текст, поэтому разметка внутри кода, в том числе вызов фрейма, на странице не срабатывает. Подсветку по имени языка делает фрейм, если она в нем есть.
Разделитель
Строка --- между абзацами дает горизонтальную линию.
Картинки
Картинку ставьте отдельной строкой. В квадратных скобках напишите описание картинки для alt, в круглых — адрес, а после него через пробел в кавычках подпись под картинкой, если она нужна.

Адрес берите из поля path в ответе загрузки медиа. Адрес вида /media/… работает на любом домене сайта. Картинку из медиатеки сайт выводит с размерами и копией в WebP, а картинку с чужого адреса выводит как есть. В подписи работают жирный, курсив и код, а ссылки не работают. Если после картинки на той же строке стоит текст, вместо картинки на странице окажется абзац со ссылкой.
Видео с YouTube
Ссылку на ролик поставьте отдельной строкой, и на ее месте на странице появится видео.
https://www.youtube.com/watch?v=VIDEO_ID
Подходят ссылки youtube.com/watch?v=…, youtu.be/… и youtube.com/shorts/…, время начала из ссылки (t=90) сохраняется. До нажатия на превью ролика страница не загружает плеер YouTube.
Фреймы в тексте
Вызов фрейма вставляет в текст страницы готовый элемент, например вопросы и ответы или врезку. Текст для фрейма поставьте между строками <!-- frame/имя --> и <!-- /frame -->. Например, фрейм faq берет вопросы из заголовков H3, а ответы из текста под ними:
<!-- frame/faq -->
### Сколько стоит?
Бесплатно на старте.
### Нужна ли карта?
Нет.
<!-- /frame -->
Фрейм callout--info выводит текст из вызова врезкой:
<!-- frame/callout--info -->
Перевыпуск токена **сразу** отключает старый.
<!-- /frame -->
Все фреймы и примеры их вызова — на странице Все фреймы.
HTML
В тексте страницы пишите обычный HTML, как в стандартном Markdown. Фрагментом HTML API считает текст от строки с HTML-тегом в начале до пустой строки и сохраняет его как есть.
<div class="promo"><a class="btn" href="/tarify/">Тарифы</a></div>
Вопросы и ответы, врезки и другие готовые элементы вставляйте фреймами.