🛠️Яндекс.Вебмастер API: 5 запросов вместо ручного захода в панель
Пять эндпоинтов API Вебмастера, которые закрывают ежедневный мониторинг: диагностика, страницы в поиске, запросы, история обхода и переобход. С curl-примерами и разбором квот.
Интерфейс Яндекс.Вебмастера — нормальный инструмент, но у него есть свойство, которое злит: чтобы понять «всё ли в порядке с сайтом», нужно открыть четыре разных экрана и глазами сравнить графики. Каждый день. По каждому сайту.
У Вебмастера есть API. Он покрывает почти всё, что показывает панель, и позволяет собрать проверку в один скрипт, который отработает за пару секунд и напишет вам, только если что-то сломалось. Ниже — пять запросов, которые в моей практике закрывают ежедневный мониторинг, и грабли, на которые я наступил, пока их собирал.
Это продолжение разбора Метрика API — та же логика, только про индексацию, а не про поведение.
Что нужно один раз, до всех запросов
OAuth-токен
API Вебмастера ходит по OAuth-токену Яндекса, а не по логину-паролю. Порядок:
- Завести приложение на oauth.yandex.ru → «Создать приложение».
- Выбрать платформу «Веб-сервисы», в Redirect URI можно указать
https://oauth.yandex.ru/verification_code. - В правах отметить
Яндекс.Вебмастер→ «Управление сайтами» (webmaster:hostinfoиwebmaster:verify). - Получить код по ссылке
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}.
Как это собирается в один скрипт
Схема, которая у меня крутится по крону раз в сутки:
- Дёрнуть
/diagnostics/, отфильтроватьFATAL/CRITICAL. Есть → алерт. - Дёрнуть
/search-urls/in-search/history/за 14 дней, сравнить последнее значение со средним за предыдущую неделю. Просадка больше 15% → алерт. - Дёрнуть
/indexing/samples/, посчитать долю не-200 ответов. Больше порога → алерт. - Сложить сырые JSON в файл с датой в имени — чтобы через месяц было с чем сравнивать. Это, пожалуй, самое ценное: Вебмастер хранит историю ограниченно, а свой архив — сколько угодно.
- Молчать, если всё в порядке.
Последний пункт — принципиальный. Отчёт, который приходит каждый день, перестают читать через неделю. Сообщение, которое приходит раз в месяц, читают всегда.
Грабли, которые стоит знать заранее
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. Она полная, но устроена по эндпоинтам, а не по задачам, — поэтому первый заход в неё обычно заканчивается ничем. Начните с этих пяти, остальное добавите по мере надобности.