🛠️Яндекс.Вебмастер API: 5 запросов вместо ручного захода в панель

Пять эндпоинтов API Вебмастера, которые закрывают ежедневный мониторинг: диагностика, страницы в поиске, запросы, история обхода и переобход. С curl-примерами и разбором квот.

редакция seodb#яндекс#вебмастер#api#мониторинг#индексация#техническое-seo

Интерфейс Яндекс.Вебмастера — нормальный инструмент, но у него есть свойство, которое злит: чтобы понять «всё ли в порядке с сайтом», нужно открыть четыре разных экрана и глазами сравнить графики. Каждый день. По каждому сайту.

У Вебмастера есть API. Он покрывает почти всё, что показывает панель, и позволяет собрать проверку в один скрипт, который отработает за пару секунд и напишет вам, только если что-то сломалось. Ниже — пять запросов, которые в моей практике закрывают ежедневный мониторинг, и грабли, на которые я наступил, пока их собирал.

Это продолжение разбора Метрика API — та же логика, только про индексацию, а не про поведение.

Что нужно один раз, до всех запросов

OAuth-токен

API Вебмастера ходит по OAuth-токену Яндекса, а не по логину-паролю. Порядок:

  1. Завести приложение на oauth.yandex.ru → «Создать приложение».
  2. Выбрать платформу «Веб-сервисы», в Redirect URI можно указать https://oauth.yandex.ru/verification_code.
  3. В правах отметить Яндекс.Вебмастер → «Управление сайтами» (webmaster:hostinfo и webmaster:verify).
  4. Получить код по ссылке https://oauth.yandex.ru/authorize?response_type=token&client_id=<ваш client_id> — токен вернётся прямо во фрагменте URL.

Токен живёт долго (год по умолчанию), но это полноценный ключ от аккаунта — держать его в переменной окружения, не в коде.

export YA_TOKEN="y0_AgAAAA..."

Все запросы дальше идут с заголовком:

Authorization: OAuth $YA_TOKEN

user_id и host_id

Два идентификатора, без которых не собрать ни один URL.

curl -s -H "Authorization: OAuth $YA_TOKEN" \
  https://api.webmaster.yandex.net/v4/user/
# {"user_id": 2184652699}
curl -s -H "Authorization: OAuth $YA_TOKEN" \
  https://api.webmaster.yandex.net/v4/user/2184652699/hosts/

В ответе будет список сайтов с полем host_id вида https:seodb.tech:443. Вот здесь первые грабли: в URL этот идентификатор нужно percent-кодировать целиком, вместе с двоеточиями:

https%3Aseodb.tech%3A443

Если подставить host_id как есть — получите 404 без внятного объяснения. Я потратил на это минут двадцать, прежде чем догадался посмотреть, что именно уходит в запрос.

Дальше базовый префикс у всех пяти запросов одинаковый, обозначу его так:

BASE="https://api.webmaster.yandex.net/v4/user/2184652699/hosts/https%3Aseodb.tech%3A443"
AUTH=(-H "Authorization: OAuth $YA_TOKEN")

Запрос 1. Диагностика — что Яндекс считает поломкой прямо сейчас

curl -s "${AUTH[@]}" "$BASE/diagnostics/"

Возвращает список проблем с разбивкой по severity: FATAL, CRITICAL, POSSIBLE_PROBLEM, RECOMMENDATION. Это тот самый раздел «Диагностика сайта» в панели, только в JSON.

Что здесь ловится и почему это первый запрос в списке:

  • SITE_ERROR / DNS_ERROR — сайт лежит или не резолвится. Робот увидит это раньше, чем вы;
  • MAIN_PAGE_ERROR — главная отдаёт не 200;
  • NO_ROBOTS_TXT, ROBOTS_ERROR — robots.txt пропал или стал невалидным (типовой сюрприз после деплоя);
  • SSL_CERTIFICATE_ERROR — сертификат протух. Отдельно больно, если ACME-обновление тихо отвалилось;
  • DISALLOW_IN_ROBOTS на важных разделах;
  • THREATS — сайт помечен как заражённый.

Практическое правило: FATAL и CRITICAL — повод разбудить себя алертом. Всё остальное — в еженедельный отчёт, иначе RECOMMENDATION будет шуметь постоянно.

Мини-скрипт «есть ли пожар»:

curl -s "${AUTH[@]}" "$BASE/diagnostics/" \
  | jq -r '.problems[]? | select(.severity=="FATAL" or .severity=="CRITICAL")
           | "\(.severity) \(.problem_type) \(.state)"'

Пустой вывод — всё в порядке. Непустой — идти смотреть.

Запрос 2. Страницы в поиске — история, а не текущее число

curl -s "${AUTH[@]}" \
  "$BASE/search-urls/in-search/history/?date_from=2026-08-01&date_to=2026-09-08"

Отдаёт временной ряд: сколько страниц сайта было в поиске в каждую дату. Именно история важнее текущего значения: одно число «в поиске 412 страниц» ничего не говорит, а падение с 412 до 190 за трое суток — говорит очень многое.

Что даёт этот ряд:

  • ловит выпадение раздела из индекса раньше, чем вы заметите просадку трафика в Метрике (индекс проседает первым, трафик — следом);
  • отделяет «сайт под фильтром» от «страницы выпали из индекса». Разные проблемы с разным лечением — подробнее в разборе про провал трафика;
  • показывает, как быстро индексируется новый раздел после запуска.

Рядом есть парный эндпоинт по событиям добавления/удаления:

curl -s "${AUTH[@]}" "$BASE/search-urls/events/samples/?limit=100"

Он возвращает конкретные URL с типом события (APPEARED_IN_SEARCH, REMOVED_FROM_SEARCH) и причиной удаления. Когда график упал — это второй запрос, который отвечает «а какие именно страницы».

Запрос 3. Поисковые запросы — по каким фразам вас реально показывают

curl -s "${AUTH[@]}" \
  "$BASE/search-queries/popular/?order_by=TOTAL_SHOWS\
&query_indicator=TOTAL_SHOWS&query_indicator=TOTAL_CLICKS\
&query_indicator=AVG_SHOW_POSITION&limit=100"

Обратите внимание: query_indicator передаётся несколько раз, по одному на каждую метрику. Это не список через запятую — с запятой API вернёт ошибку валидации.

Доступные индикаторы: TOTAL_SHOWS, TOTAL_CLICKS, AVG_SHOW_POSITION, AVG_CLICK_POSITION.

Зачем это в ежедневном мониторинге: показы падают раньше кликов, а позиция падает раньше показов. Если сравнивать текущую выгрузку с выгрузкой недельной давности по одним и тем же запросам, деградация видна за несколько дней до того, как её станет заметно в аналитике.

Для молодого сайта тут же обнаруживается неприятное: половина запросов, по которым вас показывают, — не те, под которые вы писали страницу. Это не баг, а сигнал, что страница попала в другой кластер интентов и её надо либо переписывать, либо принимать новый интент.

Запрос 4. История обхода — что робот получает в ответ

curl -s "${AUTH[@]}" \
  "$BASE/indexing/history/?date_from=2026-08-01&date_to=2026-09-08"

Ряд по количеству обойдённых страниц и по кодам ответа, которые робот получил. Отдельно есть срез по конкретным ошибкам:

curl -s "${AUTH[@]}" "$BASE/indexing/samples/?limit=100"

Здесь ловится то, чего не видно ни в Метрике, ни в браузере:

  • всплеск 5xx в конкретные часы — почти всегда упирается в лимиты хостинга или в то, что робот пришёл во время деплоя;
  • рост 404 после смены структуры URL — значит, где-то остались старые ссылки и не проставлены редиректы;
  • падение числа обойдённых страниц при неизменном сайте — краулинговый бюджет ушёл на мусорные URL (фильтры, сортировки, UTM-хвосты).

Если вы хоть раз мигрировали сайт, этот запрос — единственный честный способ увидеть, как выглядела миграция глазами робота, а не глазами вашего браузера.

Запрос 5. Переобход — единственный, который что-то меняет

Первые четыре запроса читают. Пятый — пишет.

curl -s -X POST "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://seodb.tech/blog/yandex-webmaster-api-5"}' \
  "$BASE/recrawl/queue/"

Это программный аналог кнопки «Переобход страниц». Отправляете URL — робот приходит быстрее, чем пришёл бы сам.

Квота проверяется отдельным GET:

curl -s "${AUTH[@]}" "$BASE/recrawl/quota/"
# {"daily_quota": 150, "quota_remainder": 148}

Важные детали, которые стоили мне пары суток недоумения:

  • Квота считается за сутки и не резиновая. Для небольшого сайта это порядка 100–150 URL в день, значение зависит от размера и качества сайта и меняется само. Если гнать переобход пачкой на весь sitemap, квота кончится, а нужная страница в очередь не попадёт.
  • Экономная схема — 2 URL на публикацию: сама новая страница и страница-листинг, с которой на неё стоит ссылка. Без второго URL робот может ещё неделю не знать, что ссылка вообще появилась.
  • Переобход не гарантирует индексацию. Он гарантирует визит. Если страница слабая или дублирует существующую, робот придёт и не возьмёт её в поиск.
  • Ответ приходит с task_id, статус задачи смотрится через GET /recrawl/queue/{task_id}.

Как это собирается в один скрипт

Схема, которая у меня крутится по крону раз в сутки:

  1. Дёрнуть /diagnostics/, отфильтровать FATAL/CRITICAL. Есть → алерт.
  2. Дёрнуть /search-urls/in-search/history/ за 14 дней, сравнить последнее значение со средним за предыдущую неделю. Просадка больше 15% → алерт.
  3. Дёрнуть /indexing/samples/, посчитать долю не-200 ответов. Больше порога → алерт.
  4. Сложить сырые JSON в файл с датой в имени — чтобы через месяц было с чем сравнивать. Это, пожалуй, самое ценное: Вебмастер хранит историю ограниченно, а свой архив — сколько угодно.
  5. Молчать, если всё в порядке.

Последний пункт — принципиальный. Отчёт, который приходит каждый день, перестают читать через неделю. Сообщение, которое приходит раз в месяц, читают всегда.

Грабли, которые стоит знать заранее

  • host_id кодируется целиком, включая двоеточия: https%3Aseodb.tech%3A443. Самая частая причина 404 на ровном месте.
  • query_indicator — повторяющийся параметр, не список через запятую.
  • Даты в формате YYYY-MM-DD, диапазон ограничен (для большинства отчётов — до года назад). Слишком широкий период отдаёт 400, а не обрезает сам.
  • Права токена нужны на чтение И на управление. Токен только с webmaster:hostinfo читает отчёты, но не поставит переобход.
  • Сайт должен быть подтверждён в Вебмастере. API не умеет работать с неподтверждённым хостом, а сообщение об этом невнятное.
  • Лимит частоты запросов есть, хоть и не афишируется. Ставьте паузу между вызовами в цикле по сайтам, иначе поймаете 429.

Что API не умеет

Честности ради — не всё, что есть в панели, доступно программно:

  • нет полного экспорта всех запросов, только выборка популярных;
  • «Рекомендованные запросы» и часть аналитики по региональности — только в интерфейсе;
  • данные по внешним ссылкам приходят выборкой (/links/external/samples/), а не полным списком.

Так что панель не отменяется. Она перестаёт быть местом, куда вы обязаны заходить ежедневно, — и становится местом, куда вы идёте, когда скрипт уже сказал, что смотреть.

Итог

Пять эндпоинтов: diagnostics, search-urls/in-search/history, search-queries/popular, indexing/history, recrawl/queue. Час на сборку скрипта, дальше он экономит по десять минут в день на каждом сайте и — что важнее — ловит проблемы в тот день, когда они возникли, а не через две недели, когда вы заметили провал трафика.

Официальная документация: yandex.ru/dev/webmaster. Она полная, но устроена по эндпоинтам, а не по задачам, — поэтому первый заход в неё обычно заканчивается ничем. Начните с этих пяти, остальное добавите по мере надобности.