• Быстрый старт
    • Доступ и токен
  • СУЩНОСТИ
    • Страницы
      • Markdown
      • Аналитика страниц
    • Фреймы
      • Блоки
      • Бинды data-op-bind
      • Повторитель onpress/repeat
      • Сборка и копии
      • Фреймы в Markdown
      • Фреймы с данными
      • Готовые фреймы
    • Данные
    • Медиа
  • УСТРОЙСТВО САЙТА
    • Сайты
    • Настройки сайта
    • Меню
    • Языки и переводы
    • Стили и оформление
  • УПРАВЛЕНИЕ
    • Домены
    • Соцсети и контакты
    • SEO
    • Аналитика
    • Кэш
    • Дашборд и вход
    • Пользователи и профиль
    • Сайдбар документации
    • Ошибки и проблемы
  • КЕЙСЫ
    • Создание сайтов
    • Работа с контентом
    • Фреймы и данные
    • Настройка сайта
    • Перевод страницы
  • ПРИЛОЖЕНИЯ
    • Приложения
      • Закрытый доступ
      • Данные приложения
      • Внешние данные
      • Демо
    • Быстрый старт
    • Доступ и токен
  • СУЩНОСТИ
    • Страницы
    • Фреймы
    • Данные
    • Медиа
  • УСТРОЙСТВО САЙТА
    • Сайты
    • Настройки сайта
    • Меню
    • Языки и переводы
    • Стили и оформление
  • УПРАВЛЕНИЕ
    • Домены
    • Соцсети и контакты
    • SEO
    • Аналитика
    • Кэш
    • Дашборд и вход
    • Пользователи и профиль
    • Сайдбар документации
    • Ошибки и проблемы
    • Редиректы
    • Кредиты и автоматизация
    • Входящие
    • Кросспостинг
OnPress OnPress
  • Документация
  • Контакты
Войти
Обзор Справочник API
    • Быстрый старт
    • Доступ и токен
  • СУЩНОСТИ
    • Страницы
      • Markdown
      • Аналитика страниц
    • Фреймы
      • Блоки
      • Бинды data-op-bind
      • Повторитель onpress/repeat
      • Сборка и копии
      • Фреймы в Markdown
      • Фреймы с данными
      • Готовые фреймы
    • Данные
    • Медиа
  • УСТРОЙСТВО САЙТА
    • Сайты
    • Настройки сайта
    • Меню
    • Языки и переводы
    • Стили и оформление
  • УПРАВЛЕНИЕ
    • Домены
    • Соцсети и контакты
    • SEO
    • Аналитика
    • Кэш
    • Дашборд и вход
    • Пользователи и профиль
    • Сайдбар документации
    • Ошибки и проблемы
  • КЕЙСЫ
    • Создание сайтов
    • Работа с контентом
    • Фреймы и данные
    • Настройка сайта
    • Перевод страницы
  • ПРИЛОЖЕНИЯ
    • Приложения
      • Закрытый доступ
      • Данные приложения
      • Внешние данные
      • Демо
    • Быстрый старт
    • Доступ и токен
  • СУЩНОСТИ
    • Страницы
    • Фреймы
    • Данные
    • Медиа
  • УСТРОЙСТВО САЙТА
    • Сайты
    • Настройки сайта
    • Меню
    • Языки и переводы
    • Стили и оформление
  • УПРАВЛЕНИЕ
    • Домены
    • Соцсети и контакты
    • SEO
    • Аналитика
    • Кэш
    • Дашборд и вход
    • Пользователи и профиль
    • Сайдбар документации
    • Ошибки и проблемы
    • Редиректы
    • Кредиты и автоматизация
    • Входящие
    • Кросспостинг
Управление
Markdown
Открыть в ИИ
  • Открыть в ChatGPT
  • Открыть в Claude
  • Открыть в Gemini
  • Открыть в Perplexity
  • Открыть в Grok
  • Открыть в DeepSeek

SEO

Здесь все эндпоинты SEO сайта: проверка по чеклисту, обход страниц, ссылки, статус в Google, SEO-настройки, карточка приложения, карта сайта, robots.txt, llms.txt, IndexNow, позиции в выдаче и платная отправка на индексацию; как этим пользоваться, рассказано на странице SEO.

info

Во всех примерах API — https://onpress.pro/api/v2, SITE — id сайта (SITE_ID), OP_TOKEN — токен op_XXXX, example.com — домен сайта. Все пути на странице — от $API/site/$SITE. Права на всех эндпоинтах страницы — администратор сайта. Как выбирается сайт и в какой форме приходят отказы — Доступ и токен.

POST /seo/audit

Проверяет весь чеклист раздела SEO на сервере и сохраняет итог: SEO-настройки и настройки сайта, тему, языки и главные, набор author, счётчики и консоли, файлы robots.txt и llms.txt, визиты ботов и обход страниц. Длится столько же, сколько обход страниц: от секунд до минуты; второй POST, пока идёт первый, получает его результат. Источник, который не ответил, переводит свои пункты в unknown и называется в errors, остальные пункты считаются. Например, проверить сайт:

curl -s -X POST "$API/site/$SITE/seo/audit" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "x9HTLHECq",
  "checked": true,
  "format": 1,
  "checked_at": "2026-09-29T09:25:16.998Z",
  "took_ms": 1202,
  "site_url": "https://example.com",
  "totals": { "counted": 38, "ok": 19, "todo": 16, "warn": 3, "na": 1, "unknown": 0 },
  "sitemap": { "url": "https://example.com/sitemap_index.xml", "consoles": { "gsc": { "state": "not_connected" }, "ywm": { "state": "not_connected" } }, "error": null },
  "files": { "robots": { "state": "ok", "http": 200, "url": "https://example.com/robots.txt" }, "llms": { "state": "none", "http": 404, "url": "https://example.com/llms.txt" } },
  "bots": { "…": "…" },
  "errors": [],
  "checks": [
    {
      "id": "identity",
      "group": "Basics",
      "status": "ok",
      "title": { "key": "seo.checks.identity.title" },
      "why": { "key": "seo.checks.identity.why" },
      "summary": "Example",
      "fields": [ { "label": { "key": "seo.checks.identity.fields.title" }, "value": "Example" } ],
      "fix": { "title": "…", "command": "curl -X PATCH …" }
    }
  ]
}
Поле ответаОписание
checked_at, took_msкогда прошла проверка и сколько длилась
totalscounted, ok, todo, warn, na, unknown; na и unknown в counted не входят
sitemapадрес карты сайта и что о ней знают Search Console и Вебмастер — в форме GET /sitemap
filesживые robots.txt и llms.txt: robots.state — ok, warn (закрывает весь сайт Disallow: /, так бывает у закрытого сайта) или fail (не отдаётся, http); llms.state — ok, none (404, файл не собран) или fail
botsкогда поисковые и ИИ-боты последний раз заходили за robots.txt и картой сайта
errorsисточники, которые не ответили
checksпункты чеклиста, см. пункты проверки

Пункт: id, group (Basics, Indexing, Languages, Markup, Speed, Pages — в консоли «Контент»), status — ok, todo (сделать), warn (требует внимания), na (неприменимо), unknown (источник не ответил); summary, fields, note, rows — строки таблицы пункта, pages — страницы с нарушением; fix — готовая команда curl с этим сайтом; builtin: true — то, что платформа делает сама. Тексты — не фразы, а ключи словаря консоли: {"key", "params"}, {"list": […]}, {"join": […], "sep"}, {"age": iso}; простая строка — значение как есть.

Своих отказов у эндпоинта нет: сломанный источник не останавливает проверку, а попадает в errors.

GET /seo/audit

Отдаёт сохранённый итог без новой проверки — раздел SEO консоли при открытии делает ровно этот вызов. Например, прочитать последний итог:

curl -s "$API/site/$SITE/seo/audit" -H "Authorization: Bearer $OP_TOKEN"

Ответ — в форме POST /seo/audit и ещё два поля, прочитанные вживую: running: true, пока идёт проверка, и access — состояние «сайт открыт / закрыт» (closed, supported, reason, url, retry_after; null, если прочитать не удалось). До первой проверки — checked: false, checked_at: null, checks: [].

Пункты проверки

Своего хранилища у чеклиста нет: всё, что он показывает, лежит в настройках сайта, SEO-настройках, теме и страницах и правится там же. Пункты canonical, redirects, not-found и карта сайта собраны в один tech-basics, Метрика, GA4, Search Console и Вебмастер — в counters, проверки H1 и уровней — в headings. Пункты группы Languages есть только на многоязычном сайте; на одноязычном homes стоит последним пунктом «Основы».

ПунктГруппаЧто проверяетЧем чинить
identityBasicsназвание сайтаPUT /data/settings/name
site-iconBasicsиконка сайта: favicon и логотип организации в разметкеPUT /data/settings/icon
homesBasicsу каждого языка опубликованная главнаяPUT /data/site.front_page, перевод главной
countersIndexingМетрика, GA4, Search Console, Вебмастер; статус — худший из четырёх[`PUT /data/settings/{metrika\ga\gsc\webmaster}`](#data)
tech-basicsIndexingкарта сайта XML, canonical на саму страницу, 301 после переноса, 404 с noindexкарта — PATCH /seo sitemap.enabled; остальное платформа делает сама
auto-sitemap-hreflang, auto-hreflang, auto-x-defaultLanguagesкарта с альтернативами языков, hreflang с обратными ссылками, x-default на основной языкделает платформа
schema-websiteMarkupWebSite на главной: name, url, descriptionописание — PATCH /data/site.settings
schema-organizationMarkupOrganization на главной: name, url, logo, желательно sameAsPATCH /data/site.organization, PATCH /data/site.socials
schema-pageMarkupWebPage главной и Article первой статьисвойство seo_description, набор author
schema-authorMarkupPerson автора статьи и ProfilePagePUT /data/author
schema-breadcrumbsMarkupBreadcrumbList с name у каждого звенавложенность страниц: свойство url с родителем
schema-howtoMarkupHowTo с шагами по порядкуфрейм howto или текст страницы
schema-faqMarkupFAQPage, один узел на страницублок вопросов на странице
schema-appMarkupSoftwareApplication: name и offers или aggregateRatingPATCH /seo/app
schema-ogMarkupog:title, og:description, og:url, og:type, og:image, twitter:cardPATCH /seo social
auto-webpSpeedкартинки отдаются в WebPделает платформа
auto-lcp-preloadSpeedpreload и fetchpriority="high" у картинки первого экранаделает платформа
auto-web-vitalsSpeedLCP, INP, CLS домена из Chrome UX Report—
page-cacheSpeedстраницы отдаются из кэшаделает платформа
keywordsPagesключ страницы стоит в <title> и meta descriptionсвойства seo_title, seo_description
pages-metaPagesу страниц есть <title> и meta descriptionseo_title, seo_description
pages-lengthPagestitle не длиннее 65 знаков, описание — 165seo_title, seo_description
headingsPagesровно один H1 и уровни без пропусковтело страницы
pages-noindexPagesкакие страницы закрыты noindexсвойство noindex
images-altPagesу картинок тела есть alt![alt](url) в теле страницы
contactsPagesполитика, условия, контакты и контакты в подвале по каждому языкупубликация страниц, набор footer

Страницы чинит публикация Markdown с нужными свойствами или текстом — POST /pages/markdown или точечно PATCH /pages/{ref}/markdown. Готовые команды по каждой странице — в fix пункта, до 25 страниц; сайт в них назван в пути, /site/{site_id}/…, а настройки сайта правятся через данные — site.settings, site.organization, site.socials. Например, вписать ключ в title и описание страницы 6949:

curl -s -X POST "$API/site/$SITE/pages/markdown" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"markdown": "---\nid: 6949\nfocus_keyword: \"чат бот\"\nseo_title: \"Чат бот онлайн без регистрации\"\nseo_description: \"Бесплатный чат бот: …\"\n---\n\n<тело из выгрузки без изменений>"}'

homes. Строка на язык: lang, is_default, id, title, url, status, reason. Строка в порядке, когда по / сайт показывает страницу, у языка она есть среди переводов главной, опубликована, у неё есть фрейм и её адрес отвечает 200 без редиректа этой самой страницей. Иначе reason: posts (вместо страницы — лента записей), noPage (главной на языке нет), notPage, notPublished, noFrame, wrongPage (по адресу другая страница), redirect, closed (сайт закрыт), unreachable, http. Нет главной языка — POST /pages/markdown с translation_of: <id главной> и lang или привязка готовой страницы POST /pages/{ref}/translations/{lang}; нет фрейма — PATCH /pages/{ref} с frame; по адресу другая страница или редирект — POST /cache/flush.

counters. «Метрика» в порядке, когда у сайта есть номер счётчика, «Google Analytics» — measurement ID, «Search Console» и «Вебмастер» — когда права подтверждены (verified: true). Строка в консоли ведёт в «Аналитика → Счётчики».

tech-basics. В rows — строка на каждую часть, status ok или warn; сломано хоть что-то — весь пункт не ok. У строки карты — url индекса, count адресов (сумма <url> по дочерним картам живого индекса) и bots — когда боты последний раз забирали карту. Подтверждение остальных частей — signals.canonical, signals.redirects и signals.not_found обхода. На сайте публичны только страницы: архивов авторов, дат, вложений, рубрик и меток, их лент и типа записей post нет (он остаётся только там, где уже есть опубликованные записи) — такие адреса отвечают 404 и в карту сайта не попадают.

keywords. Проверяются опубликованные страницы обхода, у которых задан ключ — свойство focus_keyword; несколько ключей — через запятую, точку с запятой или с новой строки. Title и Description сверяются с отданной разметкой: фразой целиком по границам слов, без учёта регистра и диакритики (ё = е), кавычки, тире и знаки препинания отбрасываются; в китайском, японском, тайском и бирманском — вхождением без границ слов. Статус: все страницы с ключом в порядке — ok, есть нарушения — todo, ключ не задан ни у одной — na. Строка: id, title, lang, url, keywords, title_ok, description_ok (null, когда страница не открылась, причина в reason), missing, seen (title, description), status; нарушения идут первыми.

headings. В полях — «Ровно один H1: N из N» и «Уровни без пропусков: N из N», в pages — страницы с нарушениями, статус — худший из двух. problems[].kind: no_h1, many_h1 (count, text второго), jump — скачок уровня (from, to, text), рядом outline — лестница заголовков. Навигация, подвал и боковая колонка не учитываются; H1 — первая строка # … в теле или заголовок, который печатает фрейм.

images-alt. Картинки тела каждой открытой страницы обхода, без шапки, меню, подвала и боковой колонки. Нет атрибута alt — нарушение; alt="" засчитывается только декоративной картинке (role="presentation" или aria-hidden="true"). В rows — src, file, alt (null — атрибута нет, "" — пустой), page. Alt вписывается в тело страницы: ![alt](url) становится <img alt="alt">.

contacts. По каждому языку опубликованы политика конфиденциальности, условия использования и страница контактов, а в подвале главной — почта или телефон (mailto:, tel:) и ссылки на оба документа. Документ находится по слагу страницы языка: privacy, privacy-policy, polite, politika…, политика…; terms, terms-of-use, oferta, оферта; contacts, contact, kontakty, контакты. Строка: lang, is_default, privacy, terms, contacts ({id, title, url} или null), footer_contact, footer_legal, status, reason. Подвал из набора footer правится PUT /data/footer с тем же lang; набора нет — 404 source_not_found, подвал тогда задан фреймом.

Schema-разметка. Пункты schema-* показывают не настройки, а то, что сайт отдаёт: узлы JSON-LD и теги Open Graph, снятые с живых страниц без кук. Страницы-образцы: главная, первая статья (Article, BlogPosting, NewsArticle), страница с вопросами, страница автора (ProfilePage), страница с крошками и одна внутренняя. Статус: узел есть и обязательные поля заполнены — ok; обязательное поле пустое или ссылка {"@id": …} ведёт на объект, которого нет на странице, — warn; узла нет, хотя он нужен, — todo; к сайту не относится — na; образец не открылся — unknown. В rows — строка на образец: page (home, article, faq, profile, breadcrumbs, app, inner), label, id, lang, url, status, title — тип узла, language (json или markup), code — узел как есть или мета-теги строками (null — узла нет), missing, recommended, refs, note. Код режется на 24 КБ.

Отдельные узлы. Organization строит кто-то один: пока в site.organization пусто name, узел выводит SEO-граф из раздела organization /seo с sameAs из social.profiles; как только name заполнено, сайт выводит узел из site.organization (логотип — иконка сайта, sameAs — site.socials), поле «Источник» говорит, какой действует. Person тема собирает из набора author только на страницах, чей фрейм объявил набор: набор есть, а Person не выводит ни одна страница — todo. BreadcrumbList строится по вложенности страниц, первое звено — главная языка; плоский сайт — na. HowTo печатает фрейм howto в теле страницы; без него платформа собирает узел из трех и больше подзаголовков «Шаг 1…» или нумерованного списка от трех пунктов под H2/H3 со словом инструкции, а шаги фрейма steps важнее текста. Два FAQPage или два HowTo на странице — warn.

Скорость. auto-webp — warn, если есть картинки не в WebP, в pages до 50 страниц (note — сколько картинок не в WebP), всего — pages_total. auto-web-vitals — по порогам CrUX по p75 (телефоны, если есть): все «хорошо» — ok, есть «нужно улучшить» — warn, есть «плохо» — todo (LCP хорошо ≤ 2,5 с, плохо > 4 с), данных нет — na. page-cache — главная и две страницы обхода по два захода без кук, второй обязан прийти из кэша; в rows — адрес, status, ttfb_ms.

GET /seo/pages

Обходит опубликованные страницы по HTTP и читает ту разметку, которую сервер отдаёт на самом деле: до 2000 страниц, 8 одновременно, 15 с на страницу. Пункты pages-*, headings, images-alt и keywords проверки считаются по этому же обходу. Например, проверить русские страницы:

curl -s "$API/site/$SITE/seo/pages?lang=ru" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "x9HTLHECq",
  "lang": "ru",
  "checked_at": "2026-10-28T06:37:00.882Z",
  "took_ms": 2808,
  "totals": { "pages": 35, "crawled": 35, "checked": 30, "skipped_noindex": 5, "unreachable": 0 },
  "meta": { "count": 0, "pages": [] },
  "lengths": { "count": 22, "title_max": 65, "description_max": 165, "pages": [ { "id": 6231, "url": "/ru/docs/", "long": ["title"], "title_text": "…" } ] },
  "headings": { "count": 3, "pages": [ { "id": 6234, "url": "/ru/docs/install/", "problems": [ { "kind": "many_h1", "count": 2, "text": "Установка" } ], "outline": ["…"] } ] },
  "noindex": { "count": 5, "pages": [ { "id": 6240, "url": "/ru/errors/", "status": 404 } ] },
  "unreachable": [],
  "signals": { "pages": 30, "canonical": { "…": "…" }, "schema": { "…": "…" }, "images": { "…": "…" }, "preload": { "…": "…" }, "hreflang": { "…": "…" }, "og": { "…": "…" }, "redirects": { "…": "…" }, "not_found": { "…": "…" } },
  "summary": { "…": "…" },
  "pages": [ "…" ]
}
ПараметрТипПо умолчаниюОписание
langstringallязык страниц

meta.pages[] — страницы с пустым <title> или meta description (missing, title_text, description_text). lengths.pages[] — title длиннее title_max или описание длиннее description_max (long, тексты и длины). headings.pages[] — нарушения заголовков. noindex.pages[] — страницы, которые отдаются с noindex, с кодом ответа; на заголовки они не проверяются. unreachable — открытые страницы, ответившие не 2xx (reason: http_error, timeout, unreachable, not_html). signals — то, что платформа делает сама: canonical (with, self, other, missing), redirects, not_found, schema, images (img, webp, without_webp), preload, hreflang (missing_return), home.x_default, og; списки режутся до 50 адресов. Больше 2000 страниц — в totals появляется truncated_at.

КодСтатусКогдаЧто делать
unknown_language422такого языка на сайте нет; языки — в languagesвозьмите слаг из ответа
no_public_pages409ни у одной опубликованной страницы нет адресаопубликуйте страницы

POST /seo/links/check, GET /seo/links

POST ставит фоновую проверку мёртвых ссылок и ссылок на страницу другого языка и сразу отвечает 202 с status: "running" и started_at; GET отдаёт ход или итог. Каждая ссылка из текста с анкором и состоянием цели — ссылки страниц. Например, запустить проверку и прочитать итог:

curl -s -X POST "$API/site/$SITE/seo/links/check" -H "Authorization: Bearer $OP_TOKEN"
curl -s "$API/site/$SITE/seo/links" -H "Authorization: Bearer $OP_TOKEN"

Ответ GET: status — none (проверки не было), running, done, failed, interrupted; started_at, finished_at; в итоге — dead, wrong_lang, unconfirmed и totals. Причина мёртвой ссылки — http_404, http_410, http_5xx, dns, soft_404; неподтверждённой — timeout, tls, redirect_loop или код ответа, который закрывает страницу от роботов.

КодСтатусКогдаЧто делать
check_running409на сайте уже идёт проверкадождитесь итога в GET /seo/links
checks_busy429сервер проверяет ссылки других сайтовповторите через несколько минут

GET /seo/link-graph

Строит граф внутренних ссылок по телам опубликованных страниц: входящие и исходящие ссылки, сироты и вес страницы. Граф кэшируется и пересчитывается сам, когда меняются страницы. Например, граф русских страниц:

curl -s "$API/site/$SITE/seo/link-graph?lang=ru" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "x9HTLHECq",
  "lang": "ru",
  "scope": "body",
  "cached": false,
  "built_at": "2026-10-28T06:37:00.882Z",
  "weight": { "method": "…", "iterations": 20, "damping": 0.85, "scale": "…" },
  "summary": { "pages": 120, "orphans": 4, "avg_inbound": 3.2, "site_pages": 120, "site_edges": 410, "site_unresolved_links": 2 },
  "pages": [ { "id": 6231, "url": "/ru/docs/", "lang": "ru", "inbound": 12, "inbound_links": 15, "outbound": 8, "outbound_links": 9, "orphan": false, "front": false, "weight": 4.1 } ]
}
ПараметрТипПо умолчаниюОписание
langstringallязык страниц
fresh1—пересчитать мимо кэша
КодСтатусКогдаЧто делать
unknown_language422такого языка на сайте нетвозьмите слаг из languages
polylang_inactive409lang передан сайту с одним языкомуберите lang
too_many_pages413опубликовано больше 5000 страниц—

GET /seo/index-status, POST /seo/index-status

Отдаёт вердикт Search Console URL Inspection по странице: GET — по одной, POST — до 100 разом. Результат держится сутки. Например, статус страницы 5776:

curl -s "$API/site/$SITE/seo/index-status?ref=5776" -H "Authorization: Bearer $OP_TOKEN"
ПараметрТипПо умолчаниюОписание
refstring—GET: id, слаг или путь страницы, обязательно
refsarray—POST: до 100 id, слагов или путей, обязательно
refreshboolfalseспросить Google заново; не чаще раза в час на страницу
langstring—язык, если слаг есть в нескольких языках

Ответ: property — ресурс Search Console, quota — остаток квоты, page (у POST — pages и summary: total, live, cached, deferred, failed). У страницы — verdict, coverage_state, indexing_state, robots_txt_state, page_fetch_state, last_crawl_time, google_canonical, checked_at, source (live, cache, none). Квота — 1900 проверок в сутки на ресурс; что не влезло в квоту, в POST приходит с deferred, а не отказом всего пакета.

КодСтатусКогдаЧто делать
ref_required, refs_required400нет ref или пустой refsпередайте страницу
too_many_refs400больше 100 страницразбейте на части
invalid_ref400элемент refs не число и не строкаисправьте список
unknown_field400в теле POST поле кроме refs, refresh, langуберите поле
page_not_found404страницы нетпроверьте ref
not_published409страница не опубликованаопубликуйте её
gsc_not_connected409Search Console не подключенаPUT /data/settings/gsc
gsc_quota_exhausted429квота на сутки кончилась; Retry-Afterповторите после срока
gsc_busy503Google не ответил в срокповторите запрос

GET /seo, PATCH /seo

GET отдаёт SEO-настройки сайта: разделитель и шаблоны заголовков, метаописания, флаги noindex, хлебные крошки, организацию для SEO-графа, Open Graph, карту сайта; PATCH правит любые разделы — шлите только меняемые. Постраничные title, description и noindex здесь не живут: они в свойствах страницы. Например, включить карту сайта:

curl -s -X PATCH "$API/site/$SITE/seo" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"sitemap": {"enabled": true}}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "changed": ["sitemap.enabled"],
  "seo": { "separator": "sc-dash", "separator_char": "-", "sitemap": { "enabled": true, "entries_per_page": 1000, "author": false, "index_url": "https://example.com/sitemap_index.xml", "…": "…" }, "robots_url": "https://example.com/robots.txt", "…": "…" },
  "cache": { "…": "…" }
}
РазделКлючи
separatorстрока — ключ разделителя: sc-dash, sc-pipe, sc-middot…
titlesшаблоны: home, page, post, 404, author, archive, search
metadeschome, page, post, author, archive
noindexarchive, author, author_noposts (bool), post_types, taxonomies — карты {имя: да или нет}
attachmentsredirect_to_parent (bool)
breadcrumbsenabled, bold_last (bool), separator, home, prefix
organizationtype (company, person), name, alternate_name, logo (id картинки), person_user_id, person_name, person_logo (id); при чтении — logo_id, logo_url, person_logo_id
socialopen_graph, twitter (bool), twitter_card (summary, summary_large_image), default_image (id картинки), profiles — facebook, twitter (без @), instagram, linkedin, youtube, wikipedia, mastodon, pinterest, other (массив адресов); при чтении — default_image_id
sitemapenabled, author (bool; не действует — архивов авторов нет), entries_per_page (1–10 000); при чтении ещё post_types, taxonomies, governed_by, index_url
index_nowenabled, key; при чтении ещё supported. Отправка IndexNow идёт через POST /indexnow, этот раздел её не включает

При чтении рядом ещё separator_char и robots_url. Ответ записи — changed (изменённые ключи), seo после записи и cache. Состав карты сайта задают noindex.post_types и noindex.taxonomies, в карте только страницы. Свою организацию лучше задавать в данных — PATCH /data/site.organization: пока там пусто name, узел Organization строится из раздела organization этого эндпоинта.

КодСтатусКогдаЧто делать
nothing_to_change400пустое телопришлите раздел
unknown_field400незнакомый раздел или ключ, в том числе незнакомая соцсеть или тип записей; допустимые — в messageуберите поле
invalid_{раздел}, invalid_{ключ}400раздел не объект или значение не той формы: строка, целое число, да/нетисправьте значение
invalid_separator400не ключ вида sc-dashвозьмите ключ из чтения
invalid_organization_type400type не company и не personисправьте тип
invalid_logo, invalid_default_image400картинки с таким id на сайте нетвозьмите id из GET /media
invalid_person_user400пользователя person_user_id нетпроверьте id
invalid_twitter_card400не summary и не summary_large_imageисправьте значение
invalid_profiles400social.profiles не объект или other не массивисправьте профили
invalid_entries_per_page400не от 1 до 10 000исправьте число
sitemap_composition_readonly400прислан sitemap.post_types или sitemap.taxonomiesсостав карты задают noindex.post_types и noindex.taxonomies
invalid_index_now_key400index_now.key не 8–128 знаков a-f0-9 и не "auto"исправьте ключ
index_now_key_missing400index_now.enabled: true без ключапришлите key
index_now_unsupported409index_now.enabled: trueотправляйте адреса через POST /indexnow
yoast_missing409SEO-настройки на сайте недоступны—

GET /seo/app, PATCH /seo/app

Карточка приложения — узел SoftwareApplication на главной. Тема выводит узел, когда карточка включена и заполнены name, rating_value и rating_count; картинка узла — иконка сайта. PATCH принимает любое подмножество полей, null или "" очищают поле. Например, заполнить карточку:

curl -s -X PATCH "$API/site/$SITE/seo/app" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"name": "Example", "category": "WebApplication", "operating_systems": ["Chrome", "Windows"], "price": 0, "currency": "USD", "rating_value": 4.8, "rating_count": 127}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "changed": ["name", "category", "operating_systems", "price", "rating_value", "rating_count"],
  "app": {
    "enabled": true,
    "name": "Example",
    "description": "",
    "category": "WebApplication",
    "operating_systems": ["Chrome", "Windows"],
    "price": 0,
    "currency": "USD",
    "rating_value": 4.8,
    "rating_count": 127,
    "image": "https://example.com/…/icon-512.png",
    "missing": [],
    "output": true,
    "choices": {
      "category": { "BrowserApplication": "Browser Application", "BusinessApplication": "Business Application", "EducationalApplication": "Educational Application", "UtilitiesApplication": "Utilities Application", "WebApplication": "Web Application" },
      "operating_systems": { "Chrome": "Google Chrome", "Windows": "Windows", "…": "…" },
      "currency": { "USD": "USD", "EUR": "EUR", "GBP": "GBP", "RUB": "RUB" }
    }
  },
  "cache": { "…": "…" }
}
ПолеТипПо умолчаниюОписание
enabledbooltrueвыводить узел; выключенный не выводится при любых полях
namestring—название приложения, обязательно для вывода
descriptionstring—описание
categorystringBrowserApplicationapplicationCategory, одно из choices.category
operating_systemsstring[][]платформы из choices.operating_systems: Chrome, Firefox, Edge, Safari, Opera, Brave, Windows, macOS, Linux, Android, iOS; выходят строкой через запятую
pricenumber—цена, 0 и больше; 0 — бесплатно
currencystringUSDвалюта из choices.currency
rating_valuenumber—оценка от 1 до 5, обязательна для вывода
rating_countinteger—число оценок, от 1, обязательно для вывода

GET отдаёт app в той же форме без changed и cache. missing — каких из трёх обязательных полей не хватает, output — выйдет ли узел на главной, choices — допустимые значения, их задаёт тема сайта. changed называет только реально изменившиеся поля; после записи кэш страниц сбрасывается, узел виден на главной сразу.

КодСтатусКогдаЧто делать
nothing_to_change400в теле ни одного поляпришлите хотя бы одно
unknown_field400поле вне спискауберите поле
invalid_enabled400не да/нетпришлите true или false
invalid_name, invalid_description400не строкапришлите строку
invalid_category, invalid_currency400значение вне choicesвозьмите значение из choices
invalid_operating_systems400не массив строк или платформа вне choicesвозьмите ключи из choices.operating_systems
invalid_price, invalid_rating_value, invalid_rating_count400число вне диапазонаисправьте число
theme_fields_missing409тема сайта не знает настроек приложения—

GET /sitemap, POST /sitemap/submit

GET отдаёт, что Search Console и Вебмастер знают о карте сайта sitemap_index.xml; POST отправляет карту в подключённые консоли. Отправляет сам сайт через подключённую аналитику. Например, отправить карту в обе консоли:

curl -s -X POST "$API/site/$SITE/sitemap/submit" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"service": "all"}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "service": "all",
  "sitemap": "https://example.com/sitemap_index.xml",
  "gsc": { "state": "submitted", "sitemap": "https://example.com/sitemap_index.xml" },
  "ywm": { "state": "already", "already": true, "sitemap": "https://example.com/sitemap_index.xml", "sitemap_id": "d1a3d870-ab57-32f5-bc04-fec6d92f3bb2" }
}
ПолеТипПо умолчаниюОписание
servicestringallgsc, ywm или all
sitemap_urlstringкарта сайтаабсолютный адрес карты

Ответ по каждому сервису, поле state. Google при чтении: submitted (last_submitted, last_downloaded, is_pending, errors, warnings) или not_submitted (known — какие карты Google знает); при отправке — submitted, Google перечитает карту. Яндекс при чтении: added (sitemap_id, added_date) или not_added (known); при отправке — added или already: отдельного «перечитай» у Вебмастера нет, добавленные карты он обходит сам. Отказ сервиса — тоже state: not_connected (не подключён), not_verified (сайт не подтверждён, 401/403), api_error (code, message — как ответил сервис). Итог проверки несёт то же состояние в sitemap.consoles.

КодСтатусКогдаЧто делать
invalid_service400service не gsc, ywm или allисправьте значение
invalid_sitemap_url400не абсолютный адрес http(s)пришлите полный адрес

GET /sitemap/urls

Отдаёт все адреса, которые сайт отдаёт поисковикам в карте: индекс sitemap_index.xml и каждую дочернюю карту из него. Список читается с самого сайта в момент запроса и совпадает с XML строка в строку, в том же порядке. Например, прочитать карту:

curl -s "$API/site/$SITE/sitemap/urls" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "x9HTLHECq",
  "sitemap": "https://example.com/sitemap_index.xml",
  "total": 73,
  "sitemaps": [
    { "url": "https://example.com/page-sitemap.xml", "path": "/page-sitemap.xml", "lastmod": "2026-10-03T10:30:00+00:00", "status": 200, "count": 73 }
  ],
  "urls": [
    { "loc": "https://example.com/", "images": 0, "lastmod": "2026-09-12T17:48:01+00:00", "sitemap": "/page-sitemap.xml" },
    { "loc": "https://example.com/primery/", "images": 2, "lastmod": "2026-09-12T18:04:47+00:00", "sitemap": "/page-sitemap.xml" }
  ],
  "took_ms": 516
}

total — сколько адресов в картах; у дочерней карты, которая не ответила, — error и count: 0; images — сколько картинок у адреса в карте.

КодСтатусКогдаЧто делать
sitemap_unavailable502индекс карты не ответил; sitemap, status, при обрыве — reasonпроверьте карту в GET /seo и повторите
site_home_missing409у сайта нет адреса—

GET /robots, PUT /robots, DELETE /robots

GET отдаёт robots.txt, который сайт отдаёт сейчас, PUT записывает свой текст, DELETE возвращает общий шаблон сети: закрыты служебные разделы, ленты, поиск, /page/, плюс Sitemap: своей карты. Свой текст отдаётся как есть, строка Sitemap: дописывается, только если её в тексте нет. Например, закрыть раздел /private/:

curl -s -X PUT "$API/site/$SITE/robots" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"content": "User-agent: *\nDisallow: /private/\n"}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "content": "User-agent: *\nDisallow: /private/\n\nSitemap: https://example.com/sitemap_index.xml\n",
  "custom": true,
  "default_content": "User-agent: *\n…",
  "url": "https://example.com/robots.txt",
  "site_closed": false,
  "changed": true,
  "warnings": []
}
ПолеТипПо умолчаниюОписание
contentstring—PUT: текст файла до 64 КБ, обязательно

Строка — пустая, # комментарий или Директива: значение. Незнакомая директива, правило до первого User-agent и Sitemap не абсолютным адресом запись не останавливают — они в warnings (line, text, message). У закрытого сайта robots.txt отдаёт User-agent: * / Disallow: / без Sitemap: (site_closed: true), свой текст сохраняется и возвращается при открытии.

КодСтатусКогдаЧто делать
invalid_robots400строка не той формы; errors (line, text, message) и warningsисправьте строки
invalid_content400не строка или управляющие символыпришлите текст
empty_content400пустой текствернуть шаблон — DELETE /robots
too_large413больше 64 КБ; limitсократите текст

GET /llms, PUT /llms, DELETE /llms

GET отдаёт llms.txt сайта, PUT записывает свой текст, DELETE снимает текст — /llms.txt снова отвечает 404. Своего умолчания нет: без текста файл отвечает 404, собрать его по страницам — POST /llms/build. Например, записать свой текст:

curl -s -X PUT "$API/site/$SITE/llms" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"content": "# Example\n\n## Pages\n\n- [Тарифы](https://example.com/pricing.md): цены и планы.\n"}'
ПолеТипПо умолчаниюОписание
contentstring—PUT: текст файла до 64 КБ, обязательно

Ответ: content, exists, auto (текст собран сборкой и пересобирается сам), url, site_closed; у записи — ещё changed и warnings (первая строка не # Название — предупреждение). Свой текст, сохранённый PUT, автоматическим не бывает и сам не меняется; вернуть автоматику — снова вызвать сборку. У закрытого сайта /llms.txt отвечает 404, что бы ни было сохранено.

КодСтатусКогдаЧто делать
invalid_content400не строка или управляющие символыпришлите текст
empty_content400пустой текстснять текст — DELETE /llms
too_large413больше 64 КБ; limitсократите текст

POST /llms/build

Собирает llms.txt в формате llmstxt.org по опубликованным страницам всех языков и сохраняет; GET /llms/build или {"dry_run": true} показывают результат без записи. Каждая ссылка ведёт на markdown-копию страницы — адрес с .md. Собрать разом llms.txt и все markdown-копии — POST /markdown/build. Например, собрать и сохранить:

curl -s -X POST "$API/site/$SITE/llms/build" -H "Authorization: Bearer $OP_TOKEN"
{ "success": true, "site_id": "x9HTLHECq", "content": "# Example\n\n## Pages\n\n- [Тарифы](https://example.com/pricing.md): …", "pages": 60, "bytes": 18140, "saved": true, "dry_run": false, "url": "https://example.com/llms.txt" }
ПолеТипПо умолчаниюОписание
dry_runboolfalseпоказать текст без записи

Не попадают страницы с noindex, без фрейма, под паролем, служебная 404 и страницы с неопубликованным родителем. Разделы: сначала страницы без раздела, потом по разделу на каждую корневую страницу с детьми, в конце записи. До 600 ссылок, из них записей до 100; если текст не укладывается в 64 КБ, сначала укорачиваются описания, потом хвосты разделов. Собранный текст помечается auto: true и пересобирается сам после каждой публикации, правки, снятия с публикации, переноса и удаления страницы. Флаг «не индексировать сайт» сборку не останавливает.

КодСтатусКогдаЧто делать
too_large413собранный текст не уложился в 64 КБзакройте лишние страницы noindex

GET /indexnow, POST /indexnow

POST бесплатно отправляет адреса сайта в IndexNow, оттуда их получают Bing, Яндекс, Seznam, Naver и другие участники протокола; GET отдаёт ключ, файл подтверждения на домене и журнал последних отправок. Ключ один на сеть, файл https://<домен>/<ключ>.txt сайт отдаёт сам и перед отправкой проверяет. Автоотправки при публикации нет. Например, отправить две страницы:

curl -s -X POST "$API/site/$SITE/indexnow" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"urls": ["https://example.com/", "/pricing/"]}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "host": "example.com",
  "mode": "urls",
  "dry_run": false,
  "count": 2,
  "sent": 2,
  "rejected": [],
  "batches": [ { "count": 2, "status": 200, "ok": true, "took_ms": 412 } ],
  "key_location": "https://example.com/01a6….txt"
}
ПолеТипПо умолчаниюОписание
urlsarray—полные адреса или пути сайта (/about/), до 50 000; нужен urls или all
allboolfalseвсе опубликованные страницы всех языков, кроме закрытых noindex и паролем (skipped_hidden — сколько пропущено)
dry_runboolfalseпроверить адреса и ключ без отправки

Адрес чужого хоста, в том числе www-варианта, не уходит, а возвращается в rejected с причиной (foreign_host, invalid_url, invalid_scheme, not_a_string). Адреса уходят пачками по 10 000. GET отдаёт host, endpoint, key (configured, source, location, served; файл не отдаётся — status, error) и log — последние 50 отправок.

КодСтатусКогдаЧто делать
urls_required400нет ни urls, ни allпередайте одно из двух
conflicting_fields400переданы и urls, и allоставьте одно
invalid_urls400urls не массивпришлите массив
no_urls400ни одного адреса этого сайта; host, rejectedпроверьте домен в адресах
too_many_urls413больше 50 000 адресовразбейте на части
indexnow_not_configured409у сети нет ключа IndexNow—
indexnow_key_file_missing409файл ключа не отдаётся с доменапроверьте key в GET /indexnow
indexnow_bad_request, indexnow_key_rejected, indexnow_url_rejected, indexnow_quota, indexnow_network502IndexNow отказал или не ответил; batchesповторите позже

Данные сайта для SEO

Название, иконка, описание, главная, счётчики, организация, соцсети, автор и подвал — это данные сайта, и пишутся они через /data; поля и отказы — на странице Настройки сайта. Например, заполнить описание сайта, которое идёт в узел WebSite:

curl -s -X PATCH "$API/site/$SITE/data/site.settings" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"description": "Бесплатный ИИ-чат без регистрации"}'
ЧтоЭндпоинтПункт проверкиПодробно
название сайтаPUT /data/settings/nameidentityполя настроек
иконка: favicon и логотип в разметкеPUT /data/settings/iconsite-iconполя настроек
сайт открыт или закрытPUT /data/settings/closedaccess в GET /seo/auditполя настроек
описание и видимость поисковикам blog_publicPATCH /data/site.settingsschema-websitesite.settings
главная сайта и языковPUT /data/site.front_pagehomesглавная
Метрика, GA4, Search Console, Вебмастер`PUT /data/settings/{metrika\ga\gsc\webmaster}`countersсчётчики
организацияPATCH /data/site.organizationschema-organizationорганизация
соцсети: sameAs и twitter:sitePATCH /data/site.socialsschema-organization, schema-ogсоцсети
автор статейPUT /data/authorschema-authorсправочник данных
контакты и документы в подвалеPUT /data/footer с langcontactsсправочник данных

Закрытый сайт (closed: true) отвечает посетителям 503 с X-Robots-Tag: noindex, robots.txt отдаёт Disallow: /, карты сайта отвечают 503, llms.txt — 404. Трафик по страницам из Search Console и GA4 — GET /pages/{ref}/traffic, рекомендации по странице — поле advice того же ответа.

GET /serp/settings, PUT /serp/settings

Позиции сайта в выдаче Google и Яндекса по запросам снимает SerpApi; на этих эндпоинтах стоит страница «Позиции» раздела SEO консоли. GET отдаёт способ съёма, плановую проверку, свой ключ, цену, лимиты и расход, PUT меняет способ и плановую проверку. Способ, свой ключ и суточные счётчики принадлежат владельцу токена и общие для всех его сайтов; запросы и история позиций принадлежат сайту. Например, прочитать настройки:

curl -s "$API/site/$SITE/serp/settings" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "mode": "credits",
  "auto": false,
  "key": null,
  "platform": { "configured": true },
  "credits": { "action": "serp_position", "price": 1, "available": 20, "balance": 20, "topup_path": "/settings/credits" },
  "limits": { "max_queries_per_site": 50, "max_checks_per_day": 50, "manual_cooldown_minutes": 60, "manual_checks_per_hour": 10, "min_interval_days": 7, "platform_max_depth": 30, "own_max_depth": 100, "concurrency": 2, "queue_max": 20 },
  "budget": { "mode": "credits", "auto": false, "queries_total": 0, "planned_checks_month": 0, "planned_checks_month_site": 0, "checks_today": 0, "manual_last_hour": 0, "price": 1, "planned_credits_month": 0, "credits_available": 20, "credits_known": true, "allowance_today": 50 }
}
ПолеТипПо умолчаниюОписание
modestringcreditscredits — ключ платформы, 1 кредит за снятую позицию; own — свой ключ SerpApi, платформа ничего не списывает
autoboolfalseплановая проверка раз в сутки; смена mode без auto переключает и её: own включает, credits выключает
refresh1—GET: перечитать остаток поисков своего ключа, поиск на это не тратится

Способы. За кредиты кредит сначала резервируется, списывается после сохранения позиции, в том числе когда сайт не нашёлся в пределах глубины, и возвращается, если съём не удался. Один поиск — страница из десяти результатов; съём останавливается, как только нашёлся адрес сайта или его поддомена, поэтому позиция в топ-10 стоит один поиск, а запрос глубиной 30 — до трёх. Позиция за пределами глубины сохраняется как position: null. Плановая проверка снимает запросы, у которых подошёл срок по interval_days: сначала ни разу не снятые, потом взятые из ключей страниц, потом самые давние; своим ключом она тратит не больше равной доли остатка до сброса тарифа и оставляет 10 поисков на ручные проверки.

ЛимитПредел
запросов на сайт50
снятых позиций в сутки на пользователя50 — плановые и ручные вместе, сутки по UTC
как часто снимается запросinterval_days от 7 до 90
ручная проверка одного запросараз в 60 минут
ручных проверок на пользователя10 в час, по одной за раз
глубиназа кредиты — до 30, свой ключ — до 100
одновременных съёмов на сервере2, ещё 20 ждут в очереди

platform.configured — есть ли на сервере ключ платформы; credits — цена позиции, баланс и страница пополнения. budget: queries_total (запросов на всех сайтах пользователя), planned_checks_month и planned_checks_month_site, checks_today, manual_last_hour, allowance_today; за кредиты — price, planned_credits_month, credits_available, credits_known; своим ключом — searches_total, searches_left, searches_used, days_left, reserve, per_day, spent_today, planned_searches_month, planned_searches_until_reset, fits и max_queries_weekly.

КодСтатусКогдаЧто делать
invalid_mode422не credits и не ownисправьте значение
invalid_auto422не boolпришлите true или false
own_key_required409own без привязанного ключапривяжите ключ PUT /serp/key

PUT /serp/key, DELETE /serp/key

PUT привязывает свой ключ SerpApi — один на пользователя для всех сайтов, новый заменяет прежний; DELETE отвязывает: способ возвращается на credits, плановая проверка своим ключом выключается, история позиций остаётся. При привязке ключ проверяется бесплатным запросом сведений об аккаунте SerpApi. Например, привязать ключ:

curl -s -X PUT "$API/site/$SITE/serp/key" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"api_key": "ВАШ_КЛЮЧ_SERPAPI"}'
ПолеТипПо умолчаниюОписание
api_keystring—приватный ключ SerpApi, от 32 до 128 латинских букв и цифр, обязательно

Ответ — как у GET /serp/settings. Ключ хранится зашифрованным и обратно не отдаётся: key — mask (•••• и последние четыре знака), status (ok, exhausted — поиски кончились, invalid — SerpApi ключ не принимает), status_message, plan, searches_total, searches_left, searches_used, hourly_limit, renewal_date, refreshed_at.

КодСтатусКогдаЧто делать
invalid_api_key422ключ не той формы или SerpApi его отвергпроверьте ключ в кабинете SerpApi
serpapi_unavailable502SerpApi не ответил на проверкуповторите запрос
key_not_found404DELETE: отвязывать нечего—
serp_not_configured503на сервере не настроено хранение ключей—

GET /serp/queries, POST /serp/queries

GET отдаёт запросы сайта с последней позицией, изменением и историей, POST добавляет запрос. Например, следить за запросом на русском:

curl -s -X POST "$API/site/$SITE/serp/queries" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"query": "чат бот онлайн", "lang": "ru"}'
{
  "success": true,
  "query": { "id": 23, "query": "чат бот онлайн", "engine": "google", "gl": "ru", "hl": "ru", "device": "desktop", "lang": "ru", "page_id": null, "source": "manual", "depth": 30, "interval_days": 7, "last_checked_at": null, "last_error": "", "checked": false, "position": null, "url": null, "previous_position": null, "delta": null, "history": [], "expected_searches_per_month": 12.9 }
}
ПолеТипПо умолчаниюОписание
querystring—текст от 2 до 400 знаков, обязательно
langstring—язык страницы; из него берутся страна и язык выдачи: ru → ru/ru, en → us/en; без него — us/en
gl, hlstringиз langстрана (две буквы) и язык выдачи
enginestringgooglegoogle или yandex
devicestringdesktopdesktop или mobile
depthint3010, 20, 30, 50 или 100; за кредиты — не больше 30
interval_daysint7от 7 до 90
page_idint—страница сайта, к которой относится запрос

Ответ GET: queries (сначала взятые из ключей страниц), depths — глубины, доступные в текущем способе, limits, budget. У запроса: source (page — из ключа страницы, manual — добавлен руками), checked, position и url последнего съёма, previous_position, delta (положительное — поднялся; null, если одна из позиций вне топа), history — последние 12 съёмов {at, position}, expected_searches_per_month.

КодСтатусКогдаЧто делать
invalid_query, invalid_engine, invalid_gl, invalid_hl, invalid_depth422значение не той формы; поле — в fieldисправьте поле
depth_not_allowed422глубже 30 за кредиты; maxуменьшите глубину или привяжите свой ключ
invalid_interval422не целое от 7 до 90; minисправьте интервал
query_exists409такой запрос с тем же поисковиком, страной, языком и устройством уже есть; id—
too_many_queries409на сайте уже 50 запросов; limitснимите ненужный

DELETE /serp/queries/{id}

Снимает запрос вместе с историей позиций и отвечает {"success": true, "id": 23}. Например, снять запрос 23:

curl -s -X DELETE "$API/site/$SITE/serp/queries/23" -H "Authorization: Bearer $OP_TOKEN"
КодСтатусКогдаЧто делать
query_not_found404запроса нет на этом сайтевозьмите id из GET /serp/queries

POST /serp/queries/sync

Берёт первый ключ каждой опубликованной страницы (свойство focus_keyword) и заводит запрос на языке страницы. Запросы, чей ключ со страницы пропал, выключаются, история остаётся; сверх 50 запросов на сайт не добавляет. Например, сверить запросы с ключами страниц:

curl -s -X POST "$API/site/$SITE/serp/queries/sync" -H "Authorization: Bearer $OP_TOKEN"

Ответ: pages_with_keyword, added, kept, disabled, skipped_over_limit, limit. Своих отказов нет.

GET /serp/queries/{id}/positions

Отдаёт query и positions от старых к новым: at, position (null — вне топа), url — найденный адрес сайта, searches — сколько поисков ушло. Например, сто последних съёмов запроса 23:

curl -s "$API/site/$SITE/serp/queries/23/positions?limit=100" -H "Authorization: Bearer $OP_TOKEN"
ПараметрТипПо умолчаниюОписание
limitint100сколько съёмов, не больше 500
КодСтатусКогдаЧто делать
query_not_found404запроса нет на этом сайтевозьмите id из GET /serp/queries

POST /serp/queries/{id}/check

Снимает позицию сразу; платит тот, кто вызвал: кредитом или поиском своего ключа. Ответ: searches, credits (1 за кредиты, 0 своим ключом), mode и query с новой позицией. Например, снять позицию запроса 23:

curl -s -X POST "$API/site/$SITE/serp/queries/23/check" -H "Authorization: Bearer $OP_TOKEN"

При любом отказе ничего не снято и не списано; причина последнего отказа, кроме лимитов и нехватки кредитов, остаётся в last_error запроса.

КодСтатусКогдаЧто делать
insufficient_credits402не хватает кредитов; required, available, topup_pathпополните баланс
check_cooldown429запрос проверяли руками меньше 60 минут назад; retry_after_sec, cooldown_minutesподождите
manual_hourly_limit42910 ручных проверок за час; retry_after_secподождите
daily_limit_reached42950 позиций за сутки; limit, usedдождитесь 00:00 UTC
queue_full429очередь сервера полна; retry_after_secповторите через минуту
check_in_progress409идёт другая ваша проверкадождитесь её
no_own_key409способ own без ключапривяжите ключ
invalid_api_key409привязанный ключ перестал работатьпривяжите рабочий
no_searches_left409поиски кончились, в том числе посреди съёма — тогда результат не сохраняетсядождитесь сброса тарифа
serpapi_failed502SerpApi не справился; kind: throttled, network, failedповторите позже
platform_key_missing503на сервере не настроен ключ платформыснимайте своим ключом
credits_unavailable503кредиты недоступныповторите позже
query_not_found404запроса нет на этом сайте—

GET /indexing/account, DELETE /indexing/account

Платная отправка страниц в поиск: одна страница — 2 кредита, для всех пользователей одинаково. Страница уходит в Google и Яндекс, а тем же вызовом — в IndexNow для Bing и других поисковиков. В консоли это кнопка «Отправить на индексацию» в строке раздела «Страницы», журнал — «Инструменты → Индексация». Кредиты списываются с того, кто отправляет, журнал общий для сайта. GET /indexing/account отдаёт цену, баланс и суточные пределы. Например:

curl -s "$API/site/$SITE/indexing/account" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "linked": false,
  "bot_url": "https://t.me/Link_indexing_bot?start=…",
  "platform": { "enabled": true, "price_per_page": 2, "unit": "credits", "credits": { "balance": 20, "held": 0, "available": 20 }, "top_up_path": "/settings/credits", "daily_limit": { "user": 500, "site": 1000 } }
}

platform: enabled — отправка доступна, price_per_page, credits (balance, held — в резерве, available), top_up_path, daily_limit — страниц в сутки на владельца и на сайт. linked — привязан ли свой ключ сервиса; DELETE его отвязывает (removed). PUT /indexing/account со своим ключом отвечает 410 own_key_disabled: отправка идет только за кредиты.

GET /indexing/pages

Отдаёт опубликованные страницы, свежие правки сверху, и состояние их отправки. Например, первые 50 русских:

curl -s "$API/site/$SITE/indexing/pages?lang=ru&per_page=50" -H "Authorization: Bearer $OP_TOKEN"
ПараметрТипПо умолчаниюОписание
langstringвсеязык
searchstring—строка поиска по страницам
pageint1страница списка
per_pageint50до 100

У страницы: id, title, url, lang, modified, noindex (закрыта от индексации или паролем), state — new (ни разу не отправлялась), changed (правилась после отправки), sent; engines — когда уходила в каждый поисковик; suggested — новая или изменённая и открытая. Рядом total, page, per_page, total_pages.

POST /indexing/estimate

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

curl -s -X POST "$API/site/$SITE/indexing/estimate" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"urls": ["https://example.com/", "https://example.org/x/"]}'
{
  "success": true,
  "site_id": "x9HTLHECq",
  "host": "example.com",
  "mode": "platform",
  "pages": 1,
  "links": 1,
  "estimated_cost": 2,
  "unit": "credits",
  "price_per_page": 2,
  "already_sent": [],
  "rejected": [ { "url": "https://example.org/x/", "reason": "foreign_host" } ],
  "credits_available": 20,
  "enough": true,
  "top_up_path": "/settings/credits"
}
ПолеТипПо умолчаниюОписание
urlsarray—полные адреса страниц сайта, до 2000, обязательно
forceboolfalseотправить и страницы, ушедшие за последние 7 дней
enginesarray["google", "yandex"]поисковики: google, yandex, bing; цена от их числа не зависит

Чужие адреса возвращаются в rejected с причиной (foreign_host, invalid_url, invalid_scheme, not_a_string). Страница, уже отправленная за 7 дней, попадает в already_sent (url, engine, at). estimated_cost — pages × price_per_page. Индексацию поисковики не гарантируют.

КодСтатусКогдаЧто делать
urls_required400нет urls или пустой списокпередайте адреса
no_urls400ни одного адреса этого сайта; host, rejectedпроверьте домен
engines_required, invalid_engine400пустой или незнакомый enginesgoogle, yandex, bing
platform_only400передан mode, отличный от platformуберите mode
platform_normal_only, invalid_se_type400передан se_type или priorityуберите поля
too_many_urls413больше 2000 адресовразбейте на части
credits_unavailable503кредиты недоступныповторите позже

POST /indexing/submit

Отправляет страницы: тело как у оценки плюс confirm: true и expected_cost — сумма из оценки. Сервер считает сумму заново и отправляет, только если подтверждённая не меньше; сумма резервируется перед отправкой, а списывается только за страницы, которые ушли. Например, отправить главную:

curl -s -X POST "$API/site/$SITE/indexing/submit" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"urls": ["https://example.com/"], "confirm": true, "expected_cost": 2}'
{ "success": true, "site_id": "x9HTLHECq", "id": "8f0c…", "mode": "platform", "pages": 1, "charged": 2, "unit": "credits", "already_sent": [], "rejected": [] }
ПолеТипПо умолчаниюОписание
urls, force, engines——как у оценки
confirmbool—подтверждение платного действия, обязательно
expected_costnumber—сумма из оценки в кредитах, обязательно
idempotency_keystring—защищает от двойной отправки при повторе запроса

Ответ: id — номер отправки в журнале, pages — сколько страниц ушло, charged — сколько списано. Порядок проверок: подтверждение, сумма, суточный предел, баланс — при любом отказе ничего не отправлено и не списано, кроме send_failed.

КодСтатусКогдаЧто делать
confirmation_required409нет confirm; в теле estimateподтвердите сумму
cost_changed409expected_cost меньше суммы; в теле estimateподтвердите новую сумму
nothing_to_send409всё уже отправлено за 7 дней; already_sentпередайте force: true
submit_in_progress409идёт другая ваша отправкадождитесь её
duplicate_submission409idempotency_key уже использован — ничего не отправлено—
insufficient_credits402не хватает кредитов; required, available, top_up_path, estimateпополните баланс
daily_limit429суточный предел; limit, used, leftотправьте завтра
send_failed502отправка сорвалась на середине: ушедшие страницы списаны, pages и charged говорят сколькоповторите остальные
platform_unavailable503отправка сейчас недоступнаповторите позже
отказы оценки—см. POST /indexing/estimate—

GET /indexing/submissions, POST /indexing/submissions/refresh

GET отдаёт журнал отправок сайта, новые сверху; POST …/refresh сразу обновляет незавершённые отправки и отвечает {"checked": 0, "updated": 0}. Например, журнал с обновлением состояний:

curl -s "$API/site/$SITE/indexing/submissions?refresh=1" -H "Authorization: Bearer $OP_TOKEN"
{
  "success": true,
  "site_id": "x9HTLHECq",
  "total": 1,
  "page": 1,
  "per_page": 50,
  "total_pages": 1,
  "summary_30d": { "sends": 1, "pages": 1, "done": 1, "charged": 2 },
  "items": [ { "id": "8f0c…", "url": "https://example.com/", "pages": 1, "status": "done", "charged": 2, "created_at": "2026-10-06T09:06:09Z", "updated_at": "2026-10-06T12:00:00Z" } ]
}
ПараметрТипПо умолчаниюОписание
pageint1страница журнала
per_pageint50до 200
statusstring—sent (отправлено), active (в работе), done (готово), failed (ошибка)
urlstring—отправки этой страницы
searchstring—часть адреса
refresh1—сначала обновить незавершённые отправки, итог — в refreshed

Строка: id, url (первая страница отправки), pages, status, charged (null — отправка не за кредиты), created_at, updated_at; summary_30d — за последние 30 дней.

КодСтатусКогдаЧто делать
invalid_status400status вне спискаисправьте значение
arrow_backНазад
Справочник: кросспостинг
Далееarrow_forward
Аналитика
На этой странице
  • POST /seo/audit
    • GET /seo/audit
      • Пункты проверки
        • GET /seo/pages
          • POST /seo/links/check, GET /seo/links
            • GET /seo/link-graph
              • GET /seo/index-status, POST /seo/index-status
                • GET /seo, PATCH /seo
                  • GET /seo/app, PATCH /seo/app
                    • GET /sitemap, POST /sitemap/submit
                      • GET /sitemap/urls
                        • GET /robots, PUT /robots, DELETE /robots
                          • GET /llms, PUT /llms, DELETE /llms
                            • POST /llms/build
                              • GET /indexnow, POST /indexnow
                                • Данные сайта для SEO
                                  • GET /serp/settings, PUT /serp/settings
                                    • PUT /serp/key, DELETE /serp/key
                                      • GET /serp/queries, POST /serp/queries
                                        • DELETE /serp/queries/{id}
                                          • POST /serp/queries/sync
                                            • GET /serp/queries/{id}/positions
                                              • POST /serp/queries/{id}/check
                                                • GET /indexing/account, DELETE /indexing/account
                                                  • GET /indexing/pages
                                                    • POST /indexing/estimate
                                                      • POST /indexing/submit
                                                        • GET /indexing/submissions, POST /indexing/submissions/refresh
                                                        1. Главная
                                                        2. Docs
                                                        3. Документация OnPress v2
                                                        4. Справочник API
                                                        5. SEO
                                                        OnPress
                                                        OnPress
                                                        ИП Зуев И.В. ИНН: 360408359441
                                                        info@onpress.pro
                                                        © 2026
                                                        политика конфиденциальности публичная оферта
                                                        • visa
                                                        • mastercard
                                                        • sber
                                                        • tpay