• Как устроено
  • Быстрый старт
  • Доступ и токен
    • Страницы
      • Frontmatter
      • Синтаксис markdown
      • Переводы страниц
    • Фреймы
      • Вставки onpress/
      • Бинды data-op-bind
      • Сборка и копии
      • Фреймы в markdown
      • Фреймы с данными
    • Готовые фреймы
      • assistant
      • outline
      • faq
      • article
      • docs
      • site__header
      • site__footer
      • article__faq
      • landing
      • assistant__chat
      • site__404
      • news
      • news__category
      • news__post
      • news__more
      • news__share
      • author__page
      • author__byline
      • author__card
      • author__avatar
      • author__socials
      • author__head
      • home
      • pricing
      • page-feed
    • Данные
      • Повторитель onpress/repeat
  • Стили
  • Меню
  • Сайдбар документации
  • Языки сайта
  • Настройки и кэш
  • SEO
  • Медиа
  • Сайты и домены
  • Пользователи и профиль
  • Дашборд и вход
    • Рецепты
      • Сайт с нуля
      • Раздел документации
      • Лендинг
      • FAQ
      • Свой фрейм из готового
      • Многоязычный сайт
      • Поменять меню
      • Перенести страницу
      • Картинки в статье
      • Список из данных
      • Сменить оформление
  • Кейсы
    • Справочник API
      • Страницы
      • Переводы
      • Фреймы
      • Данные
      • Меню
      • Сайдбар документации
      • Стили
      • Настройки, главная, кэш
      • Языки
      • SEO
      • Медиа
      • Сайты
      • Пользователи и профиль
      • Вход и служебное
      • Кредиты и автоматизация
      • Входящие
      • Редиректы
      • Суперадмин
      • Кросспостинг
    • Ошибки и проблемы
      • Коды ошибок
OnPress OnPress
  • Документация
  • Контакты
Войти
  • Как устроено
  • Быстрый старт
  • Доступ и токен
    • Страницы
      • Frontmatter
      • Синтаксис markdown
      • Переводы страниц
    • Фреймы
      • Вставки onpress/
      • Бинды data-op-bind
      • Сборка и копии
      • Фреймы в markdown
      • Фреймы с данными
    • Готовые фреймы
      • assistant
      • outline
      • faq
      • article
      • docs
      • site__header
      • site__footer
      • article__faq
      • landing
      • assistant__chat
      • site__404
      • news
      • news__category
      • news__post
      • news__more
      • news__share
      • author__page
      • author__byline
      • author__card
      • author__avatar
      • author__socials
      • author__head
      • home
      • pricing
      • page-feed
    • Данные
      • Повторитель onpress/repeat
  • Стили
  • Меню
  • Сайдбар документации
  • Языки сайта
  • Настройки и кэш
  • SEO
  • Медиа
  • Сайты и домены
  • Пользователи и профиль
  • Дашборд и вход
    • Рецепты
      • Сайт с нуля
      • Раздел документации
      • Лендинг
      • FAQ
      • Свой фрейм из готового
      • Многоязычный сайт
      • Поменять меню
      • Перенести страницу
      • Картинки в статье
      • Список из данных
      • Сменить оформление
  • Кейсы
    • Справочник API
      • Страницы
      • Переводы
      • Фреймы
      • Данные
      • Меню
      • Сайдбар документации
      • Стили
      • Настройки, главная, кэш
      • Языки
      • SEO
      • Медиа
      • Сайты
      • Пользователи и профиль
      • Вход и служебное
      • Кредиты и автоматизация
      • Входящие
      • Редиректы
      • Суперадмин
      • Кросспостинг
    • Ошибки и проблемы
      • Коды ошибок
Справочник API
Markdown
Открыть в ИИ
  • Открыть в ChatGPT
  • Открыть в Claude
  • Открыть в Gemini
  • Открыть в Perplexity
  • Открыть в Grok
  • Открыть в DeepSeek

Справочник: фреймы

Все ручки фреймов: фреймы сайта, их файлы стилей и скриптов, библиотека системных фреймов. В примерах $API — https://onpress.pro/api/v2, $SITE — id сайта (SITE_ID), $OP_TOKEN — токен вида op_XXXX. Ручки сайта живут под $API/site/$SITE/frames…, ручки библиотеки — под $API/frames/system…, без сайта в адресе. {ref} — id фрейма (16 шестнадцатеричных символов) или слаг. Что такое фрейм и как он устроен — фреймы. Фреймы, которые вызываются в markdown страницы и обрамляют текст (шаги, FAQ, врезки), — фреймы в markdown, готовые фреймы с параметрами и списками — фреймы с данными.

Общее для всех записей фрейма:

  • type во входе игнорируется (warnings: ["type_ignored"]), default/is_default — тоже (default_ignored), name — тоже (name_ignored);
  • url во входе — 400 frame_url_not_supported: у фрейма нет адреса;
  • bake: false — не просить сборку на стороне сайта (по умолчанию просится);
  • dry_run: true — проверить и показать результат без записи; то же значит ?dry_run=1 в строке запроса. Ручка без пробного прогона (поставить на страницу, пересобрать вручную) на dry_run отвечает 400 dry_run_not_supported и ничего не пишет;
  • ответ записи несёт bake (сборка этого фрейма) и rebaked (пересборка фреймов, вкладывающих его).

Фреймы сайта

ПунктРучкаТело
СписокGET /site/{siteId}/frames?block=article&q=head&include_html=1
ЗагрузитьPOST /site/{siteId}/frames{"slug": "site__header", "html": "…"}
ПрочитатьGET /site/{siteId}/frames/{ref}—
Заменить разметкуPUT /site/{siteId}/frames/{ref}{"html": "…"}
ПереименоватьPATCH /site/{siteId}/frames/{ref}{"slug": "article__faq"}
УдалитьDELETE /site/{siteId}/frames/{ref}{}, {"bake": false} или ?dry_run=1
Поставить на страницуPOST /site/{siteId}/frames/{ref}/assign{"page": "/tarify/"}
Пересобрать вручнуюPOST /site/{siteId}/frames/rebake{"datasets": ["faq"]}

Без комментариев

Разметка фрейма и его файлы уходят в браузер как есть, поэтому комментариев в них быть не должно: ни <!-- … --> в разметке, ни // и /* … */ во встроенных и подключаемых скриптах, ни /* … */ в стилях, ни кириллицы в коде вне строк. Загрузка, замена разметки (в том числе системной версии) и запись файла с комментарием отклоняются целиком с 422 comments_not_allowed — ничего не записывается. Пояснения держите вне фрейма.

Пропускается то, что комментарием только выглядит и до страницы не доходит или обязано остаться:

ЧтоПример
вставки и их закрытие<!-- onpress/frame {"ref":"site__header"} /-->, <!-- onpress/repeat {"source":"faq"} --> … <!-- /onpress/repeat -->
разделители блоков<!-- wp:paragraph --> … <!-- /wp:paragraph -->
лицензионные заголовки/*! MIT License … */
условные комментарии IE<!--[if lt IE 9]>
адреса и строки"https://example.com", '// не комментарий'
{
  "success": false,
  "error": "comments_not_allowed",
  "message": "frame markup has 1 comment(s) at line(s) 2: code that goes to the browser carries no comments …",
  "kind": "html",
  "count": 1,
  "found": [{ "kind": "html", "line": 2, "text": "<!-- note -->" }]
}

kind — что проверялось: html (разметка), css или js (файл). found — до 20 находок: kind (html, line — //, block — /* */, cyrillic), номер строки и сама находка. Проверка идёт и при dry_run.

Список

ПараметрСмысл
blockтолько фреймы блока: ?block=article — article, article__faq, article__faq--simple
qподстрока слага, без учёта регистра
include_html1 — с разметкой каждого фрейма
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/frames?q=site__"
{
  "success": true,
  "site_id": "SITE_ID",
  "home_url": "https://example.com",
  "total": 2,
  "frames": [
    {
      "id": "10bc8f3cd3f65cd0",
      "slug": "site__header",
      "block": "site",
      "element": "header",
      "modifier": null,
      "bytes": 2117,
      "sha256": "…",
      "inserts": { "op/repeat": 3, "op/lang-switcher": 1 },
      "sources": ["header", "menu.header", "item.children"],
      "frame_refs": [],
      "binds": 9,
      "files": { "style.css": { "sha256": "…", "bytes": 1840, "type": "css" } },
      "created_at_gmt": "2026-10-01 16:53:49",
      "updated_at_gmt": "2026-10-01 16:53:49",
      "updated_by": 1,
      "option": "onpress_frame_10bc8f3cd3f65cd0",
      "origin": "system",
      "system_version": 7,
      "system_updated_at_gmt": "2026-10-02 08:40:12",
      "system_update_available": false,
      "resettable": false,
      "preview_page": { "id": 7036, "url": "/home/", "link": "https://example.com/home/" }
    }
  ],
  "registry_option": "onpress_frames",
  "page_meta": "_onpress_frame",
  "slug_pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:__[a-z0-9]+(?:-[a-z0-9]+)*)?(?:--[a-z0-9]+(?:-[a-z0-9]+)*)?$",
  "realm": "prod",
  "instance_realm": "prod",
  "writable": true,
  "is_base": false
}

Фреймы отсортированы по слагу. Поля фрейма:

ПолеСмысл
pagesid страниц, у которых это их фрейм; нет страниц — поля нет
preview_pageпервая опубликованная страница, где фрейм реально выводится: своя страница, страница фрейма, который его вкладывает (по цепочке), или страница, вставившая его в тело; {id, url, link}. Есть и у вложенных фреймов (site__header, author__byline), у которых своих страниц нет. Фрейм нигде не выводится — поля нет
filesопись файлов фрейма: {имя: {sha256, bytes, type}}; без файлов поля нет
renders_on_requesttrue — фрейм зависит от страницы и собирается на каждом запросе
origin, system_version, resettable и др.происхождение, см. системные и свои фреймы

Поля сайта рядом со списком:

ПолеСмысл
realmконтур сайта: prod — боевой, stage — стенд
instance_realmконтур сервиса, который ответил
writableзапись в этот сайт отсюда пройдёт; false — сайт другого контура, читать можно, запись получит 409 wrong_realm
is_baseсайт — эталон: правка его фреймов выпускает новую системную версию

?type= игнорируется с предупреждением type_ignored.

Загрузить

ПолеТипСмысл
slugstringобязательно; блок__элемент--модификатор, приводится к нижнему регистру
htmlstringобязательно; синонимы markup, content. Хранится байт в байт
dry_runboolпроверить и вернуть отчёт без записи
bakeboolпросить сборку (по умолчанию true)
curl -s -X POST "$API/site/$SITE/frames" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d "$(jq -n --arg html '<section class="proba-card"><h2 data-op-bind='"'"'{"text":"site.name"}'"'"'></h2><!-- onpress/menu {"place":"header","class":"proba-card__menu"} /--></section>' '{slug: "docs-proba__kartochka", html: $html}')"
{
  "success": true,
  "applied": true,
  "updated": false,
  "site_id": "SITE_ID",
  "frame": {
    "id": "20a39aa2b124c145",
    "slug": "docs-proba__kartochka",
    "bytes": 146,
    "sha256": "…",
    "inserts": { "op/menu": 1 },
    "sources": [],
    "frame_refs": [],
    "binds": 1,
    "created_at_gmt": "2026-09-25 20:18:25",
    "updated_at_gmt": "2026-09-25 20:18:25",
    "updated_by": 1,
    "block": "docs-proba",
    "element": "kartochka",
    "modifier": null,
    "option": "onpress_frame_20a39aa2b124c145",
    "origin": "custom",
    "system_update_available": false,
    "resettable": false
  },
  "inserts": { "op/menu": 1 },
  "inserts_total": 1,
  "sources": [],
  "frame_refs": [],
  "binds": 1,
  "renders_on_request": false,
  "has_doctype": false,
  "has_body": false,
  "warnings": [],
  "bake": {
    "status": "ok",
    "response": {
      "baked": true,
      "frame_id": "20a39aa2b124c145",
      "bytes": 685,
      "source_bytes": 146,
      "baked_option": "onpress_frame_20a39aa2b124c145_baked",
      "renders_on_request": false,
      "blocks": 1,
      "inserts": 1,
      "unknown_inserts": [],
      "binds": 1,
      "repeats": [],
      "frames": [],
      "unresolved": [],
      "warnings": [],
      "published": { "published": false, "pages": [] },
      "pages": []
    }
  }
}

Отчёт о разметке: inserts, inserts_total, sources, frame_refs (ссылки по id приведены к слагам), binds, renders_on_request и live_reasons, has_doctype, has_body, warnings, frame_refs_missing. Ключи inserts называют вставки коротким именем — так их считает отчёт, в разметке пишите полную форму onpress/…. Что значат поля bake.response — в сборке. dry_run отвечает тем же отчётом с dry_run: true, applied: false и без bake.

На эталонном сайте запись идёт сквозь в библиотеку и на все сайты, где фрейм системный: ответ несёт ещё поле system. На остальных сайтах правка системного фрейма делает его своим.

Отказы: 400 invalid_slug (pattern, hint), 400 frame_html_required, 422 comments_not_allowed (без комментариев), 400 frame_url_not_supported, 400 frame_ref_conflict (во вставке onpress/frame два ключа ссылки называют разные фреймы; conflicts — пары ключей и значений; слаг и id одного фрейма конфликтом не считаются), 409 slug_taken (id занявшего — замените его разметку через PUT), 413 frame_too_large (больше 2 МБ; max_bytes), 403 insufficient_role (запись на эталоне не суперадмином сети), 409 wrong_realm (сайт другого контура).

Прочитать

curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/frames/site__header" | jq '.frame | {id, slug, referenced_by, pages, files, html}'

Ответ {success, frame}: всё, что в элементе списка (с полями происхождения и описью files), плюс html — разметка, которую фрейм выводит сейчас (у системного — версия библиотеки), referenced_by — слаги фреймов, которые его вкладывают, pages — id страниц на этом фрейме. Содержимое файлов здесь не отдаётся — его читают ручкой файла. Отказы: 404 frame_not_found, 400 frame_ref_required.

Заменить разметку

Тело — как у загрузки (html обязателен, slug можно сменить — с теми же последствиями, что у переименования). Ответ — как у загрузки с updated: true и rebaked — пересборкой фреймов, вкладывающих этот (транзитивно). Файлы фрейма правка разметки не трогает. Новая разметка у системного фрейма делает его своим (origin: "custom", customized_at_gmt): правка остаётся на этом сайте, обновления платформы до него больше не доходят. Разметка, совпавшая с системной с точностью до пробелов, оставляет его системным. На эталоне разметка тоже становится новой версией библиотеки — см. эталонный сайт. Отказы: как у загрузки плюс 404 frame_not_found.

Переименовать

ПолеСмысл
slugновый слаг; единственное поле, которое правит PATCH
dry_run, bakeкак у загрузки
curl -s -X PATCH "$API/site/$SITE/frames/docs-proba__kartochka" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"slug": "docs-proba__card"}'
{
  "success": true,
  "site_id": "SITE_ID",
  "frame": { "id": "20a39aa2b124c145", "slug": "docs-proba__card", "block": "docs-proba", "element": "card", "modifier": null, "…": "…" },
  "renamed": {
    "from": "docs-proba__kartochka",
    "to": "docs-proba__card",
    "frames_updated": ["docs-proba--lending"],
    "details": [ { "id": "53c0ec423d1f7072", "slug": "docs-proba--lending", "replaced": 1 } ]
  },
  "bake": { "status": "ok" },
  "rebaked": { "status": "ok", "…": "…" }
}

Во фреймах сайта, ссылавшихся на старый слаг, ссылки onpress/frame (и устаревшей onpress/partial) переписываются на новый; ссылка, записанная алиасом ключа, переписывается основным ключом name, если его во вставке ещё нет; остальная разметка не меняется. Страницы не трогаются — они хранят id. Новый слаг у системного фрейма делает его своим. На эталоне слаг фрейма библиотеки меняется везде — см. эталонный сайт. Отказы: 400 nothing_to_update (в теле только name или ничего), 410 gone (только default/is_default), 400 invalid_slug, 409 slug_taken, 400 frame_url_not_supported, 404 frame_not_found.

Удалить

curl -s -X DELETE "$API/site/$SITE/frames/docs-proba__faq" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "SITE_ID",
  "deleted": { "id": "838a082b034be249", "slug": "docs-proba__faq", "block": "docs-proba", "element": "faq", "modifier": null },
  "unbound_pages": [],
  "referenced_by": ["docs-proba"],
  "warnings": ["frames docs-proba still insert \"docs-proba__faq\"; the insert prints nothing until a frame with this slug appears again"],
  "bake": { "status": "ok" }
}

Уходят разметка, файлы фрейма и запись реестра. У страниц фрейма снимается привязка (unbound_pages) и статическая копия — на сайте v2 они начинают отвечать 404. Вкладывающие фреймы не правятся (referenced_by). bake: false в теле — не просить сборку. Удаление с эталона библиотеку не трогает: сайты, где фрейм системный, выводят его по-прежнему, в warnings — system_frame_kept: …; убрать фрейм из библиотеки — отдельная ручка. Отказы: 404 frame_not_found.

Пробное удаление. dry_run в теле или ?dry_run=1 в строке запроса ничего не удаляет и отвечает планом: что уйдёт с сайта (would_delete.files, would_delete.unbound_pages — страницы, которые потеряют фрейм и статическую копию), кто продолжит на него ссылаться (referenced_by — фреймы со вставкой, affected_frames — они же вместе с вкладывающими их, body_pages — страницы, чьё тело зовёт фрейм по имени) и что будет с библиотекой (library.kept: true — у системного фрейма библиотека и другие сайты не затрагиваются).

curl -s -X DELETE "$API/site/$SITE/frames/promo__probe?dry_run=1" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "dry_run": true,
  "applied": false,
  "frame": { "id": "26824a8c18220eb4", "slug": "promo__probe", "block": "promo", "element": "probe", "modifier": null, "origin": "custom" },
  "would_delete": { "sites": ["SITE_ID"], "files": ["style.css"], "unbound_pages": [] },
  "referenced_by": ["promo__wrap"],
  "affected_frames": ["promo__wrap"],
  "body_pages": [{ "id": 7076, "title": "Проба", "status": "publish", "path": "/proba/" }],
  "warnings": [
    "frames promo__wrap still insert \"promo__probe\"; the insert outputs nothing until a frame with this slug appears again",
    "the bodies of pages 7076 call \"promo__probe\"; the call outputs nothing after the delete"
  ]
}

Поставить на страницу

ПолеСмысл
pageобязательно: id, слаг или путь страницы
cleartrue — снять фрейм со страницы
bakeкак у загрузки
curl -s -X POST "$API/site/$SITE/frames/docs-proba--lending/assign" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"page": "proba-api"}'
{
  "success": true,
  "site_id": "SITE_ID",
  "frame": { "id": "53c0ec423d1f7072", "slug": "docs-proba--lending", "…": "…" },
  "page": { "id": 6428, "title": "Проба API", "url": "/proba-api/" },
  "meta_key": "_onpress_frame",
  "cleared": false,
  "static": { "published": true, "url": "/proba-api", "bytes": 15368, "reason": "", "message": "", "was_published": true, "was_url": "/proba-api", "removed": false, "changed": false },
  "republish": { "status": "ok", "…": "…" }
}

static — судьба статической копии этой страницы после смены фрейма (поля как у PATCH /pages/{ref}), republish.status — ok, skipped, unavailable, failed; неудача не отменяет привязку. Пробного прогона у ручки нет. Отказы: 400 dry_run_not_supported, 400 page_required, 404 frame_not_found, 404 page_not_found, 409 ambiguous_page.

Пересобрать вручную

ПолеКого пересобрать
allвсе фреймы сайта и статические копии страниц
menusзависимые от меню
pagesвыводящие страницы, их заголовки и адреса
languagesязыкозависимые
settingsзависимые от настроек сайта
datasetsмассив имён наборов — читающие их
framesмассив слагов или id — вкладывающие их
curl -s -X POST "$API/site/$SITE/frames/rebake" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"datasets": ["docs-proba-faq"]}'
{
  "success": true,
  "site_id": "SITE_ID",
  "changed": { "datasets": ["docs-proba-faq"] },
  "rebaked": {
    "status": "ok",
    "total": 2,
    "baked": 0,
    "not_needed": 2,
    "frames": [
      { "id": "838a082b034be249", "slug": "docs-proba__faq", "because": ["datasets: docs-proba-faq"], "bake": "not_needed", "detail": "renders on request from the source, has no baked copy" },
      { "id": "e627bf4dbefcc374", "slug": "docs-proba", "because": ["contains docs-proba__faq"], "bake": "not_needed", "detail": "renders on request from the source, has no baked copy" }
    ],
    "cache": {
      "status": "ok",
      "scope": "pages",
      "pages": [6428],
      "flushed": { "urls": { "status": "flushed", "by": "wpsc_delete_url_cache", "urls": ["https://example.com/proba-api/"], "skipped": [] } }
    }
  }
}

Поля rebaked — в сборке. За вызов — не больше 25 фреймов (остальные в skipped).

С {"all": true} заодно собираются заново все статические копии страниц сайта — те, что отдаются готовым файлом. Это нужно после обновления платформы: в копии заморожены шапка и подвал страницы на момент сборки. Итог — в поле static:

"static": {
  "status": "ok",
  "total": 1,
  "baked": 1,
  "static": { "status": "ok", "pages": [{ "id": 7036, "published": true, "url": "/home-next" }] }
}

status — ok, partial (часть страниц не собралась, подробности в failures) или failed; у сайта без статических копий — nothing с reason. total — страниц со статической копией, baked — собранных заново; больше 200 за вызов не собирается (остальные в skipped, предел в cap). pages — по странице: id, published, url; страница, которой копия больше не положена, снимается с публикации. Без all поля static нет. Отказы: 400 nothing_to_rebake, 400 dry_run_not_supported.

Файлы фрейма

ПунктРучкаТело
Прочитать файлGET /site/{siteId}/frames/{ref}/files?name={name}—
Записать файлPUT /site/{siteId}/frames/{ref}/files?name={name}{"content": ".card{padding:24px}"}
Переименовать файлPATCH /site/{siteId}/frames/{ref}/files?name={name}{"name": "main.js"}
Удалить файлDELETE /site/{siteId}/frames/{ref}/files?name={name}{}

Рядом с разметкой фрейм может держать свои стили и скрипты — файлы .css и .js. Опись — поле files фрейма в списке и в карточке: {имя: {sha256, bytes, type}}, type — css или js. Имя файла передают параметром name: адрес с именем в пути (…/files/style.css) перехватывает раздача статики, и он отвечает 404.

Как они попадают на страницу. Стили всех фреймов, которые выводятся на странице, — самого фрейма страницы, вложенных, вставленных в тело и в повторители — собираются в один блок <style id="op-frames-css"> в конце <head>, после стилей сайта: отдельного запроса на фрейм нет, вспышки без стилей нет, фрейм, выведенный на странице несколько раз, приносит свои правила один раз. Правила идут в порядке, в котором фреймы встречаются на странице, css-файлы одного фрейма — по имени. На страницу уходит сжатая копия: style.css хранится как записан, а при записи платформа сжимает его (пробелы, комментарии, короткие записи цветов и чисел) — размер сжатой копии в ответе записи, поле minified_bytes. Скрипты подключаются файлом: один <script> на фрейм перед </body>, адрес с хешем содержимого, правка видна сразу без сброса кэша. Фрейм — целый документ получает стили в свой <head>, скрипты — перед </body>.

Стили — в файле, а не в разметке. Блок <style> в разметке фрейма повторяется на странице столько раз, сколько раз выведен фрейм, и идёт несжатым; тот же css в style.css приходит один раз и сжатым. Комментарии в css не нужны — их всё равно срезает сжатие; метки кусков пишутся сторожами :root{--имя:1} … :root{--имя-end:1}.

Пределы: имя — латиница в нижнем регистре, цифры, - и _, до 48 символов, расширение .css или .js (style.css, script.js); файл — до 512 КБ; у фрейма — до 16 файлов. Картинки и шрифты в файлы не кладут — они живут в медиатеке, а в css на них ссылаются по адресу.

Происхождение. Правка файла у системного фрейма делает его своим, как правка разметки; «Вернуть системный» и сброс к системному возвращает и разметку, и файлы библиотеки. На эталоне правка файла выпускает новую системную версию. Новая версия библиотеки, установка из неё и отвязка переносят файлы вместе с разметкой.

Каждая запись пересобирает страницы фрейма (bake: false — не пересобирать) и снимает их кэш — поле cache, как у сброса к системному. dry_run: true показывает фрейм после правки без записи.

Прочитать файл

curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/frames/docs-proba__files/files?name=style.css"
{
  "success": true,
  "site_id": "SITE_ID",
  "frame": { "id": "380c8a1119a967ca", "slug": "docs-proba__files" },
  "file": { "name": "style.css", "sha256": "…", "bytes": 32, "type": "css", "content": ".docs-proba-files{padding:32px}\n" }
}

Отказы: 404 frame_not_found, 404 file_not_found, 400 invalid_file_name.

Записать файл

Создаёт файл или заменяет его содержимое целиком.

ПолеТипСмысл
contentstringобязательно; текст файла
bake, dry_runboolкак у загрузки фрейма
curl -s -X PUT "$API/site/$SITE/frames/docs-proba__files/files?name=style.css" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"content": ".docs-proba-files{padding:24px}\n"}'
{
  "success": true,
  "applied": true,
  "site_id": "SITE_ID",
  "frame": {
    "id": "380c8a1119a967ca",
    "slug": "docs-proba__files",
    "files": { "style.css": { "sha256": "…", "bytes": 32, "type": "css" } },
    "origin": "custom",
    "…": "…"
  },
  "file": { "name": "style.css", "sha256": "…", "bytes": 32, "type": "css", "created": true, "minified_bytes": 31 },
  "pages": [],
  "bake": { "status": "ok", "…": "…" },
  "cache": { "status": "nothing", "reason": "no page prints this frame — there is no page cache to drop" }
}

file.created — true, если файла не было; file.minified_bytes — размер сжатой копии, которая уходит на страницу (у .css; нет поля — css не разобрался, и на страницу идёт как записан). Отказы: 400 invalid_file_name (pattern, hint), 400 file_content_required, 422 comments_not_allowed (без комментариев), 400 too_many_files (max_files), 413 file_too_large (bytes, max_bytes), 404 frame_not_found, 403 insufficient_role (на эталоне не суперадмином).

Переименовать файл

PATCH с {"name": "<новое имя>"}: содержимое переезжает под новое имя, расширение можно сменить в пределах .css и .js. Ответ — как у записи, вместо file — renamed: {from, to}.

{ "success": true, "applied": true, "renamed": { "from": "script.js", "to": "main.js" }, "frame": { "files": { "main.js": { "…": "…" }, "style.css": { "…": "…" } }, "…": "…" }, "bake": { "status": "ok" } }

Отказы: 404 file_not_found, 409 file_exists (имя занято другим файлом), 400 invalid_file_name.

Удалить файл

curl -s -X DELETE "$API/site/$SITE/frames/docs-proba__files/files?name=main.js" -H "Authorization: Bearer $OP_TOKEN"

Ответ — как у записи, вместо file — deleted: "main.js"; в frame.files файла больше нет. bake и dry_run можно передать в теле или в строке запроса. Отказы: 404 file_not_found, 400 invalid_file_name.

Системные и свои фреймы

ПунктРучкаТело
Происхождение фреймаGET /site/{siteId}/frames
GET /site/{siteId}/frames/{ref}
—
Правка системного фреймаPUT /site/{siteId}/frames/{ref}
PATCH /site/{siteId}/frames/{ref}
{"html": "…"} или {"slug": "…"}
Вернуть системныйPOST /site/{siteId}/frames/{ref}/revert{} или {"dry_run": true}
Сделать своим без правкиPOST /site/{siteId}/frames/{ref}/detach{}
Сбросить к системномуPOST /site/{siteId}/frames/{ref}/reset{} или {"dry_run": true}
Эталонный сайтPUT /site/{siteId}/frames/{ref} на эталоне{"html": "…"}
Библиотека системных фреймовGET /frames/system?sites=1
Системный фреймGET /frames/system/{ref}
PUT /frames/system/{ref}
{"html": "…"}
Сделать фрейм сайта системнымPOST /frames/system{"blog_id": 268, "frame": "site__header"}
Поставить фрейм библиотеки на сайтPOST /frames/system/{ref}/install{"blog_id": 233} или {"all": true}
Убрать из библиотекиDELETE /frames/system/{ref}{"dry_run": true}

У платформы есть общая библиотека фреймов — системные фреймы. Новый сайт получает их системными: фрейм выводит общую версию, и когда её обновляют, обновление сразу доходит до сайта. Как только разметку, файлы или слаг фрейма поменяли на самом сайте (ручки выше, дашборд, агент), фрейм становится своим: правки сайта остаются, обновления библиотеки его больше не касаются. Так для всех, включая администратора платформы; новую версию для всех сайтов выпускает только платформа — правкой на эталоне или ручкой библиотеки. «Вернуть системный» ставит фрейм обратно.

Ручки сайта пишут только в свой сайт; ручки библиотеки — без сайта в адресе, читать их может любой пользователь, писать — только суперадмин сети (403 insufficient_role). Стенд и боевой контур держат библиотеки раздельно: новая версия доходит только до сайтов своего контура, сайты другого перечислены в skipped_other_contour.

Раскатка новой версии, установка, сброс и отвязка сразу снимают кэш страниц, где фрейм выводится: страниц на самом фрейме, страниц фреймов, которые его вкладывают (по цепочке), и страниц, вставивших его в тело. Поле cache у каждого сайта:

ПолеСмысл
statusok — кэш снят; nothing — фрейм не выводится ни на одной странице, снимать нечего; failed — не удалось, reason
scopepages — сняты страницы поштучно; site — снят кэш всего сайта: страниц больше 400 или их не удалось счесть
pagesсколько страниц снято (у сброса к системному — их id)

Происхождение фрейма

Поля в каждом фрейме ответа списка и карточки:

ПолеСмысл
originsystem — фрейм выводит версию библиотеки; custom — свой фрейм сайта
system_versionу системного — версия библиотеки, которую он выводит; у своего, отошедшего от системного, — версия, от которой отошёл; у фрейма, заведённого на сайте, поля нет
system_updated_at_gmtкогда в библиотеке вышла текущая версия; только если фрейм есть в библиотеке
customized_at_gmtкогда фрейм стал своим; только у изменённого системного
system_update_availableу своего фрейма в библиотеке вышла версия новее той, от которой он отошёл
resettableфрейм можно сбросить к системному: он свой, а в библиотеке есть его версия
{
  "id": "cb7ccee58078d1fb",
  "slug": "site__header",
  "…": "…",
  "origin": "custom",
  "system_version": 1,
  "system_updated_at_gmt": "2026-09-30 08:11:25",
  "customized_at_gmt": "2026-09-13 11:34:34",
  "system_update_available": false,
  "resettable": true
}

Правка системного фрейма

Замена разметки, переименование и правка файлов системного фрейма на любом сайте, кроме эталона, делают его своим: origin: "custom", system_version — версия, от которой он отошёл, customized_at_gmt — когда. Новые версии библиотеки его пропускают (в их ответе он в custom_sites). Разметка и файлы, совпавшие с библиотекой, при том же слаге — обычная запись, фрейм остаётся системным. Если переименование своего фрейма переписало ссылку на него в системных фреймах сайта, они тоже становятся своими: renamed.details[].detached и предупреждение system_frames_detached.

Раскатить правку на все сайты, где фрейм системный, можно только платформенным путём: записью на эталоне или ручкой библиотеки PUT /frames/system/{ref} — см. системный фрейм.

Сделать фрейм своим, ничего не меняя, — POST /frames/{ref}/detach: разметка и файлы те же, но обновления платформы до него больше не доходят. Ответ {"detached": true, "frame": …, "cache": …}, у своего — already_custom: true. Отказы: 409 frame_not_system, 409 base_blog (эталон).

Вернуть системный

POST /frames/{ref}/revert ставит своему фрейму текущую версию библиотеки: фрейм снова системный, страницы пересобираются, кэш снимается. Подходит фрейм, у которого в библиотеке есть версия с тем же id (такой фрейм отошёл от системного) или с тем же слагом (у фрейма свой id, он заменяется библиотечным: привязки страниц переезжают на новый id, ссылки по слагу не рвутся). Такие фреймы в списке отмечены resettable: true, второй случай — ещё и system_slug_match: true. Своя разметка и файлы перед возвратом сохраняются в снимок — поле snapshot.

curl -s -X POST "$API/site/$SITE/frames/author__head/revert" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' -d '{}'
{
  "success": true,
  "site_id": "SITE_ID",
  "reverted": true,
  "mode": "reset",
  "frame": { "id": "308bb11594598ddd", "slug": "author__head", "origin": "system", "system_version": 7, "…": "…" },
  "bake": { "status": "ok", "…": "…" },
  "cache": { "status": "nothing" },
  "snapshot": { "option": "onpress_frames_reverted_308bb11594598ddd", "saved_at_gmt": "2026-10-02 19:03:59" }
}

mode — reset (тот же id, дальше как у сброса: pages, rebaked) или replace (тот же слаг: frame.id — уже библиотечный, replaced — прежний фрейм, pages_moved — сколько страниц переехало, installed — вложенные фреймы, которых на сайте не было). Фрейм уже системный — reverted: false, already_system: true. dry_run: true отвечает revert: {mode, version, library_id} без записи.

Отказы: 404 frame_not_found, 409 frame_not_system (в библиотеке нет фрейма ни с этим id, ни с этим слагом), 409 base_blog (эталон), 409 system_frame_missing.

Сбросить к системному

POST /frames/{ref}/reset выбрасывает правки сайта: фрейм снова выводит версию библиотеки вместе с её файлами и дальше получает её обновления. Заодно пересобираются он сам и фреймы, которые его вкладывают, и снимается кэш их страниц. dry_run: true показывает фрейм после сброса без записи, bake: false — не пересобирать.

curl -s -X POST "$API/site/$SITE/frames/site__header/reset" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' -d '{}'
{
  "success": true,
  "site_id": "SITE_ID",
  "reset": true,
  "frame": { "id": "cb7ccee58078d1fb", "slug": "site__header", "…": "…", "origin": "system", "system_version": 1, "system_update_available": false, "resettable": false },
  "pages": [6191, 6238],
  "bake": { "status": "ok", "…": "…" },
  "rebaked": { "status": "ok", "…": "…" },
  "cache": { "status": "ok", "scope": "pages", "pages": [6191, 6238], "flushed": { "…": "…" } }
}

Фрейм уже системный — 200 с reset: false и already_system: true, ничего не пишется. pages — страницы на этом фрейме, bake — как у замены разметки, rebaked приходит, если фрейм кто-то вкладывает, cache — сброс кэша страниц.

Отказы: 404 frame_not_found, 409 frame_not_system (фрейм заведён на сайте, системной версии у него нет; id, slug), 409 system_frame_missing (фрейм есть в библиотеке, но разметки его версии нет).

Эталонный сайт

Библиотека ведётся с одного сайта — эталона. Для боевого контура это base-v2.onpress.pro; его номер отдают GET /frames/system (поле base_blog) и список фреймов самого эталона (is_base: true). Пока эталон назначен:

  • Правка фрейма на эталоне — это новая системная версия. Загрузка, замена разметки, переименование и правка файлов на эталоне не делают фрейм своим: он остаётся системным, его разметка и файлы сразу уходят в библиотеку новой версией и раскатываются на все сайты, где фрейм системный. Писать во фреймы эталона может только суперадмин сети.
  • Публиковать в библиотеку и убирать из неё — только с эталона. POST /frames/system с другого сайта — 409 not_base_blog; DELETE /frames/system/{ref} с blog_id другого сайта — тоже.
  • Новый сайт клонируется с эталона. POST /sites без donor берёт эталон донором — подробно в справочнике сайтов.
  • На сам эталон из библиотеки не ставят — 409 base_blog, фрейм библиотеки и так взят с него.

Ответ записи на эталоне — как у обычной записи плюс поле system:

{
  "success": true,
  "applied": true,
  "updated": true,
  "site_id": "SITE_ID",
  "frame": { "id": "380c8a1119a967ca", "slug": "docs-proba__files", "origin": "system", "system_version": 4, "…": "…" },
  "bake": { "status": "ok" },
  "system": {
    "published": true,
    "version": 4,
    "updated_sites": [
      { "site_id": "SITE_ID", "slug": "docs-proba__files", "bake": "ok", "cache": { "status": "ok", "scope": "pages", "pages": 1 } }
    ],
    "custom_sites": []
  },
  "warnings": []
}

system.updated_sites и custom_sites — как у новой версии системного фрейма. Если запись на эталоне прошла, а библиотека не обновилась, ответ всё равно 200: system.published: false, system.error и предупреждение system_publish_failed: … в warnings. Разметка уже на эталоне — повторите публикацию POST /frames/system с номером эталона и слагом фрейма.

Переименование фрейма библиотеки на эталоне меняет слаг везде: на эталоне, в библиотеке и на всех сайтах, где фрейм системный; фреймы, у которых переписалась ссылка, своими не становятся и выходят в библиотеке новой версией (в ответе system.renamed_sites и system.republished). Сделать фрейм эталона своим или вернуть системным нельзя (409 base_blog); удаление с эталона библиотеку не трогает (system_frame_kept). Эталона нет — ограничений нет: публиковать в библиотеку можно с любого сайта своего контура.

Библиотека системных фреймов

GET /frames/system — все системные фреймы, по слагу.

curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/frames/system?sites=1"
{
  "success": true,
  "total": 50,
  "registry_option": "onpress_system_frames",
  "base_blog": 268,
  "frames": [
    {
      "id": "c13525876cadfc4b",
      "slug": "about",
      "block": "about",
      "element": null,
      "modifier": null,
      "version": 13,
      "bytes": 14442,
      "sha256": "…",
      "updated_at_gmt": "2026-10-02 11:01:41",
      "updated_by": 1,
      "source_blog": 268,
      "sites": { "system": [236, 264], "custom": [], "other_contour": [233] }
    }
  ]
}

version растёт на единицу с каждой новой версией, source_blog — сайт, с которого фрейм попал в библиотеку, base_blog — эталон своего контура (null — не назначен). У фрейма с файлами есть files (опись, как у фрейма сайта) и bundle_sha256 — общий хеш разметки и файлов: по нему видно, что версия поменялась, даже если разметка та же. ?sites=1 добавляет sites: номера сайтов, где фрейм системный (system), где свой (custom), и сайты другого контура (other_contour).

Системный фрейм

GET /frames/system/{ref} — один системный фрейм (id или слаг): поля из списка, всегда с sites, и html — разметка текущей версии. Отказы: 404 system_frame_not_found.

PUT /frames/system/{ref} с {"html": "…"} (синонимы markup, content) выпускает новую версию: version + 1, файлы версии остаются прежними, и новая разметка сразу доходит до всех сайтов своего контура, где фрейм системный, — с пересборкой фрейма и вкладывающих его и сбросом кэша их страниц. Свои фреймы не трогаются и перечислены в custom_sites. Та же разметка и те же файлы, что уже в библиотеке, — 200 с applied: false, unchanged: true, версия не растёт. dry_run: true показывает будущую версию и сайты без записи, bake: false — не пересобирать.

curl -s -X PUT "$API/frames/system/docs-proba__files" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d "$(jq -n --rawfile html docs-proba__files.html '{html: $html}')"
{
  "success": true,
  "applied": true,
  "frame": { "id": "380c8a1119a967ca", "slug": "docs-proba__files", "version": 3, "bytes": 141, "sha256": "…", "updated_at_gmt": "2026-10-02 16:57:15", "updated_by": 1, "source_blog": 268, "…": "…" },
  "updated_sites": [
    {
      "blog_id": 233,
      "slug": "docs-proba__files",
      "bake": "ok",
      "cache": { "status": "ok", "scope": "pages", "pages": 1 },
      "installed": [
        { "blog_id": 233, "slug": "docs-proba__inner", "status": "installed", "bake": "ok", "cache": { "status": "nothing", "reason": "no page prints this frame — there is no page cache to drop" } }
      ]
    }
  ],
  "custom_sites": []
}

У каждой строки updated_sites: bake — исход сборки (ok, failed…), cache — сброс кэша страниц, error — если сайт обновить не удалось.

Вложенные фреймы доезжают сами. Если новая версия вкладывает через onpress/frame фрейм, которого на сайте нет, а в библиотеке он есть, раскатка тут же ставит его на сайт системным — строкой в installed (поля как у установки). Поставленный фрейм проверяется так же, до 4 уровней вложения. Эталону ничего не ставится, слаг, занятый своим фреймом сайта, отсутствующим не считается. То же делают запись на эталоне и POST /frames/system.

Отказы: 403 insufficient_role, 400 frame_html_required, 404 system_frame_not_found (такого фрейма в библиотеке нет — сначала POST /frames/system), 413 frame_too_large.

Сделать фрейм сайта системным

POST /frames/system с {"blog_id": …, "frame": "<слаг или id>"} (вместо blog_id можно domain, вместо frame — ref или slug) кладёт разметку и файлы фрейма этого сайта в библиотеку новой версией, а сам фрейм на этом сайте делает системным. Фрейм с тем же id на других сайтах своего контура, где он системный, получает эту версию; где он свой — остаётся как был (custom_sites). Ответ — как у новой версии системного фрейма, dry_run и bake — тоже. Пока назначен эталон, источником может быть только он.

curl -s -X POST "$API/frames/system" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"blog_id": 268, "frame": "site__header", "dry_run": true}'

Отказы: 403 insufficient_role, 400 blog_required (нет ни blog_id, ни domain), 400 frame_ref_required (нет frame), 404 frame_not_found (на сайте нет такого фрейма), 409 not_base_blog (эталон назначен, а сайт — не он; base_blog, blog_id), 409 wrong_realm (сайт другого контура), 413 frame_too_large.

Поставить фрейм библиотеки на сайт

Новая версия раскатывается только туда, где фрейм уже есть. Новый фрейм, заведённый на эталоне, до существующих сайтов сам не доходит — его ставят этой ручкой. На сайте появляется запись с тем же id, системная, с разметкой и файлами библиотеки; страницы, где он выводится, пересобираются, кэш снимается.

ПолеТипСмысл
blog_idintсайт; вместо него можно domain
allbooltrue — все сайты своего контура, где есть хотя бы один системный фрейм, кроме эталона
replace_customboolу сайта свой фрейм с тем же слагом — заменить его системным: id меняется, привязки страниц переезжают на новый id, ссылки по слагу продолжают работать
dry_runboolтолько отчёт
bakeboolпересобрать страницы (по умолчанию true)
curl -s -X POST "$API/frames/system/docs-proba__files/install" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"blog_id": 233}'
{
  "success": true,
  "applied": true,
  "frame": { "id": "380c8a1119a967ca", "slug": "docs-proba__files", "version": 2, "…": "…" },
  "sites": [
    { "blog_id": 233, "slug": "docs-proba__files", "status": "installed", "bake": "ok", "cache": { "status": "nothing", "reason": "no page prints this frame — there is no page cache to drop" } }
  ]
}

sites[].status:

СтатусСмысл
installedфрейм поставлен
replacedсвой фрейм с тем же слагом заменён системным; replaced: {id, slug} — каким, pages_moved — сколько привязок страниц переехало
already_systemфрейм уже стоит системным, ничего не сделано
already_customфрейм с этим id стоит своим; hint — вернуть его к библиотеке сбросом POST /frames/{ref}/reset
errorс all: true — сайт не удалось обработать (error, message), остальные идут дальше

Фреймы, которые поставленный фрейм вкладывает и которых на сайте нет, ставятся той же ручкой следом — строками в sites с because: "inserted by <слаг>".

Отказы: 403 insufficient_role, 400 blog_required (нет ни blog_id, ни all), 404 system_frame_not_found, 409 system_frame_missing, 409 base_blog (сайт — эталон), 409 slug_taken_by_custom (у сайта свой фрейм с этим слагом; id, library_id — повторите с replace_custom: true), 409 slug_taken_by_system (слаг занят другим системным фреймом), 409 wrong_realm (сайт другого контура).

Убрать из библиотеки

DELETE /frames/system/{ref} убирает фрейм из библиотеки. Сначала каждый сайт своего контура, где фрейм системный, отпускается: фрейм становится своим с той же разметкой и файлами, что были в библиотеке, страницы выводятся как прежде, кэш их страниц снимается. Только потом из библиотеки уходят запись и разметка.

ПолеСмысл
blog_id или domainнеобязательно; если передан при назначенном эталоне — должен быть эталоном
dry_runтолько отчёт; можно в строке запроса
curl -s -X DELETE "$API/frames/system/docs-proba__inner" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "applied": true,
  "removed": { "id": "488fe4aaf5894677", "slug": "docs-proba__inner", "version": 1, "…": "…" },
  "detached_sites": [
    { "blog_id": 233, "slug": "docs-proba__inner", "cache": { "status": "ok", "scope": "pages", "pages": 1 } }
  ]
}

detached_sites — отпущенные сайты (у dry_run — без cache), skipped_other_contour — сайты другого контура, где фрейм системный: их отпустит только сервис их контура. Пока эталон назначен, фрейм сначала удаляют с самого эталона (DELETE /site/{siteId}/frames/{ref}), иначе — 409 frame_on_base.

Отказы: 403 insufficient_role, 404 system_frame_not_found, 409 not_base_blog (blog_id — не эталон), 409 frame_on_base (фрейм ещё стоит на эталоне; base_blog, id, slug), 409 system_frame_missing.

Снятые ручки

GET, PUT и любые другие методы /frames/defaults, а также POST /frames/{ref}/default отвечают 410 gone: умолчаний и типов у фреймов нет, страница называет фрейм сама.

arrow_backНазад
Справочник: переводы
Далееarrow_forward
Справочник: данные
На этой странице
  • Фреймы сайта
    • Без комментариев
      • Список
        • Загрузить
          • Прочитать
            • Заменить разметку
              • Переименовать
                • Удалить
                  • Поставить на страницу
                    • Пересобрать вручную
                  • Файлы фрейма
                    • Прочитать файл
                      • Записать файл
                        • Переименовать файл
                          • Удалить файл
                        • Системные и свои фреймы
                          • Происхождение фрейма
                            • Правка системного фрейма
                              • Вернуть системный
                                • Сбросить к системному
                                  • Эталонный сайт
                                    • Библиотека системных фреймов
                                      • Системный фрейм
                                        • Сделать фрейм сайта системным
                                          • Поставить фрейм библиотеки на сайт
                                            • Убрать из библиотеки
                                          • Снятые ручки
                                          1. Главная
                                          2. Docs
                                          3. Документация OnPress v2
                                          4. Документация OnPress v2
                                          5. Справочник API
                                          6. Справочник: фреймы
                                          OnPress
                                          OnPress
                                          ИП Зуев И.В. ИНН: 360408359441
                                          info@onpress.pro
                                          © 2026
                                          политика конфиденциальности публичная оферта
                                          • visa
                                          • mastercard
                                          • sber
                                          • tpay