Parse Yandex SERP via Yandex Cloud Search API v2 (sync + async).
Infocontexts (Smart Snippets)
The Search API returns not only a link and a snippet of a couple of sentences, but a fragment of the found page of about 500 tokens — relevant to the query and with quotes from the document. There is already enough information to answer, and you don't need to process the page yourself.
This is why the skill is installed into an agent: a single request is enough for an answer, not just for a list of links.
Enabled by default, no separate script needed:
bash scripts/web_search_sync.sh --query "как считается НДС для УСН в 2026" --region-id 225
Texts are not printed in the response — they go into cache/results/<hash>.md, and
stdout receives an index, one line per document. Then read the pack as a file: in full,
if you need all the material, or with grep, if you need one source. Searching again
for the same phrase for text that is already in the pack is wasted money.
Three limitations that change the choice of command:
- Synchronous mode only.
web_search_async.shwill not return infocontexts. - Only
SEARCH_TYPE_RU. With another search type, the skill will execute the request, but without infocontexts, and will say so. - No more than 20 documents. You cannot ask for more: with
--resultsabove 20, the API returns not 20, but half as many — at the same price. The skill clamps it itself. - More expensive. 1,500 ₽ per 1000 requests versus 488 ₽ for regular synchronous.
When you need only positions and domains — --no-snippets (or
search.smart_snippets.enabled: false in the config).
Details, response format, debugging, and error analysis: references/SMART_SNIPPETS.md.
Config
To work, you need a Yandex.Cloud service account with the role search-api.webSearch.user.
IAM via an authorized JSON key and a service account API key are supported.
Step-by-step setup for both options: config/README.md.
Existing IAM configurations work without changes. For the API key, set
auth.mode: "api_key" в config.json и YANDEX_AI_API_KEY в config/.env.
Workflow
STOP! Before any search:
-
Determine the region:
- If the user specified a city/region — find the ID automatically:
bash scripts/search_region.sh --name "Казань" - If the region is not clear from the context — ASK and WAIT for an answer:
DO NOT CONTINUE until the user responds!"Для какого региона искать? - Вся Россия (по умолчанию) - Москва - Конкретный город (какой?)" - The resulting name →
search_region.sh --name "..."→ you get the ID - For ambiguous cases (Moscow city vs oblast) — clarify with the user
- If the user specified a city/region — find the ID automatically:
-
Search mode is taken from
config.json→search.mode(by defaultsync). Do not ask — use what is in the config. Exception: if infocontexts are needed, the mode is alwayssync, and the search type isSEARCH_TYPE_RU; they are not available in the asynchronous API or in other search bases. -
Verify config: make sure that
yandex_cloud_folder_idare set, the corresponding credential (theauth.modefield is optional). Do not print the key or token. -
Run search with the resulting region ID
-
Present results: with snippets — read the pack
cache/results/<hash>.mdand answer based on it, citing the sources; without snippets — position, title, URL, snippet
Scripts
iam_token_get.sh
Generate or validate IAM token from Service Account key. Needed only when
auth.mode is iam.
bash scripts/iam_token_get.sh
Token is cached in cache/iam_token.json and auto-refreshed when expired.
web_search_sync.sh
Synchronous search — one query at a time, immediate results. The only mode that supports smart snippets.
# Single query — с выдержками страниц
bash scripts/web_search_sync.sh \
--query "купить дымоход" \
--region-id 213
# Только позиции и ссылки, без выдержек
bash scripts/web_search_sync.sh \
--query "купить дымоход" \
--region-id 213 \
--no-snippets
# Batch from file — по строке на запрос в stdout, пак на каждый запрос
bash scripts/web_search_sync.sh \
--file queries.txt \
--region-id 225
| Param | Required | Default | Values |
|---|---|---|---|
--query, -q |
yes* | - | Search text |
--file, -f |
yes* | - | File with queries (one per line) |
--region-id, -r |
no | from config (225) | Region ID |
--results, -n |
no | 20 with snippets, otherwise from the config (10) | With snippets it is clamped to 20; without them 1-100 |
--page, -p |
no | 0 | Page number |
--search-type |
no | SEARCH_TYPE_RU | SEARCH_TYPE_RU / SEARCH_TYPE_TR / SEARCH_TYPE_COM / SEARCH_TYPE_KK / SEARCH_TYPE_BE / SEARCH_TYPE_UZ |
--family-mode |
no | FAMILY_MODE_MODERATE | FAMILY_MODE_NONE / FAMILY_MODE_MODERATE / FAMILY_MODE_STRICT |
--snippets |
no | on | Request excerpts from pages |
--no-snippets |
no | - | Only links and short snippets |
* Either --query or --file is required.
Results saved to cache/results/<hash>.md (pack with excerpts),
cache/results/<hash>.json (parsed) и cache/results/<hash>.raw — the original
response body: JSON with infocontexts, XML without them.
web_search_async.sh
Asynchronous batch search — submit many queries, poll for results.
# Submit batch and wait
bash scripts/web_search_async.sh \
--file queries.txt \
--region-id 213
# Resume after timeout/interrupt
bash scripts/web_search_async.sh --resume
| Param | Required | Default | Values |
|---|---|---|---|
--file, -f |
yes | - | File with queries |
--region-id, -r |
no | from config (225) | Region ID |
--poll-interval |
no | 10 | Poll interval (minutes) |
--max-wait |
no | 120 | Max wait before timeout (minutes) |
--resume |
no | - | Continue polling pending ops |
Async workflow:
- Script submits all queries as async operations
- Polls every
poll_intervalminutes for completion - Downloads and parses results as they complete
- If
max_waitexceeded: prints summary + resume command - On restart with
--resume: continues fromcache/ops/, no duplicates
NOTE for agent: Async execution can take minutes to hours.
The script handles polling automatically. If it times out,
re-run with --resume to continue.
Infocontexts are not available in asynchronous mode — only links and
short snippets will be returned. If you need page fragments — web_search_sync.sh --file.
However, async is ~16 times cheaper than synchronous and ~50 times cheaper than infocontexts.
regions_tree.sh
Show common region IDs.
bash scripts/regions_tree.sh
search_region.sh
Find region ID by name.
bash scripts/search_region.sh --name "Казань"
Output Format
Each search result contains:
position— rank in SERPtitle— page titleurl— page URLsnippet— text snippet (up to 300 chars)domain— site domainextract— infocontext: a fragment of the page; an empty string if there is none
Results cached in cache/results/:
<hash>.md— pack: title, URL, and infocontext for each document<hash>.raw— the original response body: XML for regular results, JSON for infocontexts (the format is chosen by the server)<hash>.json— parsed JSON array, a unified format for both cases
<hash> — the first 12 characters of the md5 of the query text.
Do not print infocontexts to stdout. 20 documents of ~500 tokens each do not
fit into the sandbox output buffer, and the script will fail silently. The scripts print
the index, the texts are read from the pack via Read/grep.
Tests
Offline tests: no network, no service account.
sh scripts/tests/run.sh
They check the construction of the request body, parsing of both response formats (XML and JSON), rendering of the pack, and parsing of CLI flags. The request body can also be viewed manually, without paying for anything:
YSA_DRY_RUN=1 bash scripts/web_search_sync.sh --query "тест"
Popular Region IDs
| Region | ID |
|---|---|
| Russia | 225 |
| Moscow | 213 |
| Moscow and the Moscow region | 1 |
| Saint Petersburg | 2 |
| Yekaterinburg | 54 |
| Novosibirsk | 65 |
| Kazan | 43 |
Run bash scripts/regions_tree.sh for full list.
Pricing
Pricing is per request. Prices per 1000 requests, including VAT:
| Request type | ₽ |
|---|---|
| Daytime synchronous | 488 |
| Nighttime synchronous (00:00–07:59 UTC+3) | 366 |
| Daytime deferred (async) | 30,5 |
| Search infocontext requests in the RU region | 1 500 |
Infocontexts are about three times more expensive than a regular synchronous request. If you need
only positions for a large list of queries — async or --no-snippets.
Current price list: https://aistudio.yandex.ru/docs/ru/search-api/pricing
Example Session
User: Разберись, как в 2026 считается НДС для УСН, и дай ответ со ссылками
Claude: [Регион из контекста не следует, но вопрос общероссийский → 225]
[Проверяет конфигурацию авторизации без вывода секрета]
[Ищет с выдержками — они включены по умолчанию]
bash scripts/web_search_sync.sh --query "НДС для УСН 2026 порядок расчёта" --region-id 225
=== Results for: НДС для УСН 2026 порядок расчёта ===
Region: 225 | Page: 0 | Snippets: true
# символов домен заголовок
1 1840 nalog.gov.ru Об изменениях в главе 26.2 НК РФ
2 1512 consultant.ru НДС при УСН с 2026 года
3 0 example-blog.ru Что изменится для упрощенцев
...
Всего: 20, с выдержками: 17
Пак: cache/results/a1b2c3d4e5f6.md (48 KB) — читай его вместо повторного поиска
[Читает пак и отвечает по нему, а не по заголовкам]
Read cache/results/a1b2c3d4e5f6.md
По порогу выручки: ... (nalog.gov.ru)
По ставкам: ... (consultant.ru)
User: Найди топ выдачи яндекса по запросу "купить сэндвич дымоход" в Москве
Claude: Уточню: Москва-город или Москва и область?
User: Москва город
Claude: [Находит ID региона]
bash scripts/search_region.sh --name "Москва"
→ Москва = 213
[Проверяет конфигурацию авторизации без вывода секрета]
[Задача про позиции в выдаче, содержание страниц не нужно —
отключает инфоконтексты: дешевле втрое]
bash scripts/web_search_sync.sh --query "купить сэндвич дымоход" \
--region-id 213 --no-snippets
=== Results for: купить сэндвич дымоход ===
Region: 213 | Page: 0 | Snippets: false
1. Сэндвич-дымоходы купить в Москве — Леруа Мерлен
https://leroymerlin.ru/...
Широкий ассортимент сэндвич-дымоходов...
2. Дымоходы сэндвич — купить в интернет-магазине
https://...
...
Всего: 10, с выдержками: 0
JSON: cache/results/7f3a91c2e5d8.json
Raw: cache/results/7f3a91c2e5d8.raw
User: Проверь выдачу по запросам из файла queries.txt в Казани
Claude: [Находит ID региона]
bash scripts/search_region.sh --name "Казань"
→ Казань = 43
[Проверяет конфигурацию авторизации без вывода секрета]
[Батч по одному запросу; в stdout — строка на запрос,
тексты и разбор лежат в файлах]
bash scripts/web_search_sync.sh --file queries.txt --region-id 43
запрос результаты пак
дымоход сэндвич цена 20 док., выдержек 18 cache/results/a1b2c3d4e5f6.md
купить дымоход казань 20 док., выдержек 15 cache/results/b2c3d4e5f6a1.md
дымоход нержавейка 20 док., выдержек 19 cache/results/c3d4e5f6a1b2.md
=== Batch complete: 3/3 queries processed ===