Справочник: страницы
Все ручки — ручки сайта: $API/site/$SITE/pages…. Права — администратор сайта или суперадмин. Как работают страницы в целом — страницы, поля frontmatter — frontmatter.
POST /pages/markdown
Опубликовать страницу из markdown или обновить существующую (upsert).
Тело
| Поле | Тип | Обязательно | Смысл |
|---|---|---|---|
markdown | string | да | весь документ с frontmatter |
frame | string | нет | фрейм страницы (слаг или id); перекрывает frontmatter |
blocks | array | нет | дополнительные блоки после тела: core/*, блоки плагина onpress/*, {"type":"raw","content":"…"} |
create_missing_parents, link_soft, slug_lookup | bool | нет | флаги публикации; frontmatter главнее |
faq_autodetect | bool | нет | собрать раздел FAQ в блок плагина wp:onpress/faq-items |
faq_markers | string[] | нет | заголовки раздела FAQ для faq_autodetect |
template | string | нет | игнорируется, предупреждение template_ignored |
Сайт выбирается адресом запроса; domain во frontmatter только сверяется.
curl -s -X POST "$API/site/$SITE/pages/markdown" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --rawfile md page.md '{markdown: $md}')"
Ответ
{
"success": true,
"updated": false,
"id": 6446,
"status": "publish",
"lang": "ru",
"parent": 0,
"url": "/start/",
"link": "https://test.onpress.pro/ru/start/",
"visible": true,
"translations": { "ru": 6446 },
"frame": { "id": "a2dc0bc0d2da6961", "slug": "start", "meta_key": "_onpress_frame" },
"printed": { "how": "on_request", "url": "/start/", "link": "https://test.onpress.pro/ru/start/", "frame": { "id": "a2dc0bc0d2da6961", "slug": "start", "renders_on_request": true } },
"lang_changed": { "changed": true, "from": null, "to": "ru" },
"warnings": [],
"edit_url": "https://test.onpress.pro/wp-admin/post.php?post=6446&action=edit",
"view_url": "https://test.onpress.pro/ru/start/",
"meta": { "name": "Первая страница", "slug": "start", "…": "…" },
"blocks": [ { "blockName": "core/paragraph", "attrs": {}, "innerHTML": "…" } ],
"preview_url": null
}
| Поле | Когда есть | Смысл |
|---|---|---|
updated | всегда | true — обновлена существующая |
id, status, lang, parent | всегда | записанная страница |
url, link | всегда | путь в дереве; полный адрес (null у неопубликованной) |
visible | всегда | видит ли посетитель (опубликованы она и все предки) |
translations | всегда | группа переводов {язык: id} |
translation_group | с translation_of | {origin, term_id, created, changed, unlinked} |
translation_link_error | link_soft пропустил неудачный translation_of | {error, message} |
frame | если во входе был frame | {id, slug, meta_key} или {cleared: true} |
printed | всегда | {how, url, link, frame, published_by}; how — static, on_request, not_published, theme |
slug_changed | слаг занят | {requested, applied, reason} |
lang_changed | язык страницы сменился | {changed, from, to} |
created_stubs | create_missing_parents создал родителей | [{id, slug}] |
warnings | всегда | предупреждения |
edit_url, view_url, preview_url | всегда | адрес в админке, адрес страницы, адрес предпросмотра (null у опубликованной) |
meta | всегда | разобранный frontmatter |
blocks | всегда | блоки, в которые превратилось тело |
Отказы
| Код | HTTP | Когда |
|---|---|---|
markdown_required | 400 | нет markdown или не строка |
blocks_invalid | 400 | blocks не массив |
dry_run_not_supported | 400 | dry_run в теле — пробного прогона нет |
invalid_status | 400 | статус вне publish, draft, pending, private, future |
frame_single | 400 | во frame список |
block_unsupported | 400 | тип блока в blocks вне разрешённых |
frame_not_found | 404 | фрейма нет на сайте |
ambiguous_page | 409 | слаг у нескольких страниц; matches |
lang_mismatch | 409 | id — страница другого языка |
domain_mismatch | 409 | domain во frontmatter — другой сайт |
translation_group_conflict, front_page_group_conflict | 409 | найденная по слагу страница состоит в другой группе |
translation_link_failed | 422 или 409 | translation_of не сработал; reason |
parent_not_found | 422 | сегмент url — не страница; segment |
absolute_url_in_path | 422 | схема или домен в url |
unknown_language | 422 | lang нет на сайте; languages |
page_vanished | 500 | страница исчезла во время записи — повторить |
post_type_not_supported | 501 | type не page |
acf_block_unsupported | 501 | ACF-блок в blocks |
GET /pages
Список страниц.
| Параметр | По умолчанию | Смысл |
|---|---|---|
lang | все языки | слаг языка или all; ответ всегда называет язык в lang |
status | publish,draft,pending,private,future | CSV статусов или any (с корзиной); синоним statuses |
parent | — | id, слаг или путь родителя; 0 — верхний уровень; any или пусто — без фильтра |
frame | — | слаг или id фрейма; none — страницы без фрейма |
slug | — | точный слаг |
search | — | подстрока заголовка или слага |
page | 1 | страница выдачи |
per_page | 50 | до 200 |
orderby | menu_order | menu_order, title, date, modified, id, slug |
order | asc | asc, desc |
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/pages?lang=en&parent=0&per_page=2"
{
"success": true,
"site_id": "x9HTLHECq",
"lang": "en",
"lang_filtered": true,
"languages": ["en", "ru"],
"default_lang": "en",
"statuses": ["publish", "draft", "pending", "private", "future"],
"filters": { "parent": 0 },
"total": 34,
"page": 1,
"per_page": 2,
"total_pages": 17,
"orderby": "menu_order",
"order": "asc",
"items": [
{
"id": 6183,
"title": "Documentation",
"slug": "docs",
"status": "publish",
"lang": "en",
"url": "/docs/",
"link": "https://test.onpress.pro/docs/",
"parent": 0,
"menu_order": 0,
"children_count": 17,
"is_front": false,
"date": "2026-09-12 12:48:11",
"modified": "2026-09-21 16:20:24",
"frame": { "id": "af33214f168f8efd", "slug": "obolochka-dokumentaciya", "meta_key": "_onpress_frame_page" },
"topic": [],
"seo": { "title": "OnPress v2 documentation — a site platform driven by its API", "description": "…", "keyword": "" },
"target": "",
"anchor": "",
"static": { "published": false, "url": null, "app_key": "page-6183" }
}
]
}
Счётчик страниц выдачи — total_pages (не pages). url — с префиксом языка. Даты — местное время сайта в виде ГГГГ-ММ-ДД ЧЧ:ММ:СС. frame.meta_key показывает, через какую мету привязан фрейм (_onpress_frame — нынешняя, _onpress_frame_page — старая). static — есть ли статическая копия.
Отказы: 422 unknown_language, 422 unknown_status, 422 unknown_orderby, 404 frame_not_found, 404 page_not_found и 409 ambiguous_page (для parent), 409 polylang_inactive.
GET /pages/{ref}
Одна страница целиком.
| Параметр | По умолчанию | Смысл |
|---|---|---|
lang | — | в каком языке искать и с чем сверить |
markdown | true | false — не выгружать тело (быстрее) |
as | — | translation_source — frontmatter выгрузки с translation_of вместо id, без status |
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/pages/proba-api?lang=ru"
Ответ: lang, languages, default_lang, объект page и рядом markdown.
Поле page | Смысл |
|---|---|
| поля элемента списка | id, title, slug, status, lang, url, link, parent, menu_order, children_count, is_front, date, modified, frame, topic, seo, target, anchor, static |
excerpt | выдержка |
path | путь без префикса языка |
parents | цепочка родителей от корня: [{id, title, slug, status}] |
translations | группа переводов |
frontmatter | frontmatter в том виде, в каком его пишет публикация, плюс frame |
meta | вся значимая мета страницы (без служебного шума) |
edit_url, view_url, preview_url | адреса |
Если выгрузка тела не удалась, страница всё равно возвращается: markdown: null и markdown_error: {code, message}.
Отказы: 404 page_not_found, 404 not_a_page, 409 ambiguous_page (candidates), 409 page_language_mismatch (actual_lang), 422 unknown_language, 409 polylang_inactive.
GET /pages/{ref}/markdown
Только тело — ровно тот формат, который принимает публикация.
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/pages/ru~proba-api/markdown"
{
"success": true,
"site_id": "x9HTLHECq",
"lang": "ru",
"id": 6431,
"frame": { "id": "e627bf4dbefcc374", "slug": "docs-proba", "meta_key": "_onpress_frame" },
"markdown": "---\nid: 6431\nname: \"Проба API по-русски\"\nslug: \"proba-api\"\ndate: \"2026-09-25 15:20:31\"\nstatus: \"publish\"\nurl: \"/proba-api/\"\nlang: \"ru\"\nframe: \"docs-proba\"\n---\n\nРусский текст.",
"meta": { "id": 6431, "name": "Проба API по-русски", "slug": "proba-api", "date": "2026-09-25 15:20:31", "status": "publish", "url": "/proba-api/", "lang": "ru", "frame": "docs-proba" }
}
Параметры lang и as — как у GET /pages/{ref}. Отказы — те же плюс 501 exporter_missing (на сайте нет выгрузчика) и export_failed.
PATCH /pages/{ref}
Поменять выдержку и/или фрейм, не трогая тело.
| Поле | Тип | Смысл |
|---|---|---|
excerpt | string | новая выдержка; "" или null очищают |
frame | string или null | слаг или id фрейма; null, false, "", "none" снимают |
lang | string | язык для сверки (также в строке запроса) |
republish | bool | false — не трогать статическую копию; по умолчанию true |
curl -s -X PATCH "$API/site/$SITE/pages/ru~proba-api" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"excerpt": "Выдержка ru", "frame": null}'
{
"success": true,
"site_id": "x9HTLHECq",
"lang": "ru",
"languages": ["en", "ru"],
"default_lang": "en",
"page": { "id": 6431, "title": "Проба API по-русски", "slug": "proba-api", "status": "publish", "lang": "ru", "url": "/ru/proba-api/", "link": "https://test.onpress.pro/ru/proba-api/", "excerpt": "Выдержка ru", "frame": null },
"changed": ["excerpt", "frame"],
"excerpt": { "from": "", "to": "Выдержка ru" },
"frame": { "from": { "id": "e627bf4dbefcc374", "slug": "docs-proba", "meta_key": "_onpress_frame" }, "to": null },
"static": { "published": false, "url": "", "path": null, "bytes": 0, "reason": "no_frame", "message": "", "was_published": false, "was_url": "", "removed": false, "changed": false },
"republish": { "status": "ok", "static": { "…": "…" }, "frame": null, "flushed": { "object": true, "supercache": { "status": "flushed" } } }
}
changed — что реально изменилось; ничего — перепубликации нет (republish.status: "skipped", reason: "nothing_changed"). static.reason: renders_on_request, no_frame, not_public, bad_path, пусто — копия на месте. republish.status: ok, skipped, unavailable, failed — неудача не отменяет правку.
Отказы: 400 nothing_to_update (нет ни excerpt, ни frame), 400 excerpt_invalid, 400 frame_single, 404 frame_not_found, 404 page_not_found, 409 ambiguous_page, 409 page_language_mismatch, 409 polylang_inactive, 422 unknown_language.
Голый слаг с lang ищется среди страниц этого языка — так же, как у GET: PATCH /pages/proba-api с {"lang": "ru"} правит русскую страницу. 409 page_language_mismatch приходит, только если id или путь с префиксом называют страницу другого языка.
DELETE /pages/{ref}
| Поле (тело или строка запроса) | По умолчанию | Смысл |
|---|---|---|
force | false | удалить безвозвратно вместо корзины |
with_children | false | удалить всё поддерево |
lang | — | язык для сверки |
dry_run | false | показать план |
curl -s -X DELETE "$API/site/$SITE/pages/6428?with_children=1&dry_run=1" -H "Authorization: Bearer $OP_TOKEN"
{
"success": true,
"site_id": "x9HTLHECq",
"lang": "en",
"dry_run": true,
"mode": "trash",
"page": { "id": 6428, "title": "Проба API", "slug": "proba-api", "lang": "en" },
"targets": [
{ "id": 6429, "title": "Дочерняя проба", "slug": "dochernyaya-proba", "status": "draft", "lang": "en", "url": "/?page_id=6429", "frame": "", "translations": [], "app_key": "page-6429", "static": { "published": false, "url": "" } },
{ "id": 6428, "title": "Проба API", "slug": "proba-api", "status": "publish", "lang": "en", "url": "/proba-api/", "frame": "e627bf4dbefcc374", "translations": { "ru": 6431 }, "app_key": "page-6428", "static": { "published": false, "url": "" } }
],
"translations": { "en": 6428, "ru": 6431 }
}
Настоящий вызов отвечает mode (trash или delete), page (с status_before), removed — по записи на удалённую страницу (removed, static с was_published, was_url, published, removed, translations_unlinked, translations_kept), translations: {before, after}, flushed, home_url и restore — подсказку, как найти страницу в корзине (null после force). Поддерево удаляется снизу вверх. Отказ ядра по одной странице приходит в её записи (removed: false, error: "delete_failed"), а не ошибкой запроса.
Отказы: 409 page_has_children (children), 409 front_page_delete (главная, страница блога или главная языка), 409 page_has_no_language (с lang у страницы без языка), 409 page_language_mismatch, 404 page_not_found, 409 ambiguous_page, 422 unknown_language, 502 internal_unavailable.
POST /pages/language
Проставить язык страницам.
| Поле | Смысл |
|---|---|
lang | язык; по умолчанию — основной |
missing | true — взять все страницы без языка |
pages | массив ссылок на страницы (id, слаг, путь); синоним одиночного page |
statuses | статусы для missing через запятую; по умолчанию publish |
dry_run | показать и не писать |
curl -s -X POST "$API/site/$SITE/pages/language" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"missing": true, "dry_run": true}'
{ "success": true, "site_id": "x9HTLHECq", "lang": "en", "dry_run": true, "total": 0, "changed": 0, "pages": [] }
Каждая страница в pages: {id, title, url, lang: {from, to}, changed}. Всё в одной транзакции. Отказы: 400 nothing_to_update (ни pages, ни missing), 409 polylang_inactive, 422 unknown_language, 404 page_not_found.