Yandex Rank Tracker: Keyword Positions by Region
Check and track where a site ranks on Yandex. One run per keyword returns the ranked organic list for a chosen Yandex domain, language, and region, with a search_timestamp on every item, so you can find your position today and keep a history of it.
When to use this skill
- The user wants a Yandex rank tracker or a Yandex rank checker for a domain or URL.
- They ask "where do we rank on Yandex for X" or "what position is our page in Moscow".
- They want Yandex tracking of keyword positions on a weekly or daily schedule.
- They are watching Russian-market or CIS-market SERP positions and want the movement, not just a one-off SERP read.
Not for: bulk SERP archives with no rank question attached (use the companion bulk Yandex scraper skill), Yandex Images or Yandex Videos vertical work, or Google positions.
What one run gives you (one dataset item per page, per result type)
Every dataset item is one page of one result type, tagged by item_type (organic runs give item_type set to organic). The ranked rows sit in the nested organic_results array on that item, each row carrying position, title, link, displayed_link, and snippet. The item itself carries the tracking context you need to store alongside the position: text (the keyword), search_timestamp, search_domain and search_domain_description, search_language and search_language_description, search_location, page_number, results_per_page, result_count, total_results_found, total_pages, pages_processed, pagination_limit_reached, max_pages_set, and pagination_stopped_by_limit. The unused result-type arrays (ads_results, knowledge_graph, inline_images, inline_videos, image_results, video_results) come back empty on an organic run.
Prerequisites
The Actor
Run it with the Apify CLI
Check the first page of Moscow rankings for a Russian keyword:
apify actors call "johnvc/yandex-scrape-yandex-search-results-at-scale---per-result" -i '{"text":"купить ноутбук","yandex_domain":"yandex.ru","lang":"ru","lr":"213","max_pages":1}' \
--json \
--user-agent apify-awesome-skills/apify-yandex-rank-tracker \
2>/dev/null
Go two pages deep when the target site sits outside the top ten:
apify actors call "johnvc/yandex-scrape-yandex-search-results-at-scale---per-result" -i '{"text":"crm software","yandex_domain":"yandex.com","lang":"en","lr":"84","max_pages":2}' \
--json \
--user-agent apify-awesome-skills/apify-yandex-rank-tracker \
2>/dev/null
Re-read a scheduled run's dataset later, without paying again:
apify datasets get-items <DATASET_ID> --format json --user-agent apify-awesome-skills/apify-yandex-rank-tracker 2>/dev/null
Every call carries the three flags this repo expects, --json (or --format json), --user-agent apify-awesome-skills/apify-yandex-rank-tracker, and 2>/dev/null.
Run it from Claude or another AI agent (MCP)
The Actor is MCP-ready. Add the hosted server URL:
https://mcp.apify.com/?tools=actors,docs,johnvc/yandex-scrape-yandex-search-results-at-scale---per-result
Then ask, for example, "Check where example.ru ranks on yandex.ru for 'доставка цветов' in Moscow and tell me the position." MCP setup docs: https://docs.apify.com/platform/integrations/mcp
Workflow
- Pin the market. One tracked keyword is one Actor input. Set
yandex_domain, lang, and lr together so the position you record is reproducible. Positions differ by region, so a rank history is only comparable when these three stay fixed.
- Set the depth.
max_pages 1 covers the top ten, which answers most rank questions. Use 2 or 3 only when the site is not on page one. Each page is one billable item.
- Run one keyword per run. Keep the run inputs in your own list of tracked keywords rather than trying to batch several into one query string.
- Find the position. Read the item where
item_type is organic, walk organic_results, and match your domain against link or displayed_link. Domain matching on displayed_link is more forgiving than exact URL matching. A page-2 item continues the numbering from page 1, so position is a SERP-wide rank.
- Log it. Store keyword,
search_timestamp, search_domain, search_location, matched position (or "not found in N results"), and the matched link. That row is the rank history. Not found is a real data point, so keep it.
- Schedule the repeat. Wrap the same input in an Apify Schedule for weekly or daily tracking, then diff the newest position against the previous one to report movement.
Inputs that matter for rank tracking
text (string, required): the tracked keyword
yandex_domain (enum): yandex.com, yandex.ru, yandex.by, yandex.kz, yandex.uz, yandex.com.tr
lang (enum, 19 languages) and lr (region ID string, for example 213 Moscow, 2 Saint Petersburg, 225 Russia, 84 USA)
max_pages (integer, default 2, max 100): tracking depth and the cost driver
include_organic_results (boolean, default true): leave on for rank work
sort_mode and period: leave at relevance and all for rank tracking, since sorting by date changes the ordering you are measuring
Ads, knowledge graph, inline media, and the dedicated Images and Videos verticals are billable extras that do not help a rank check. Leave them off here.
Cost
Billing is per dataset item, and one item is one page of one result type. A single-page rank check on one keyword is one item. Tracking 20 keywords weekly at one page each is 20 items per run and about 80 items a month. Multiply by the live per-result price in references/gotchas.md before committing to a schedule, and confirm the estimate with the user for anything large.
Honest limits
- A position is the SERP at crawl time for that
lr region. Yandex results move, so two runs minutes apart can differ by a position or two.
- Change
yandex_domain, lang, or lr and you have started a new series, not continued the old one.
- The Actor returns the SERP. It does not store history for you, so the logging step is yours.
- Only the fields listed above are guaranteed. Extra per-row fields appear only when Yandex shows them for that query.
- No search volume, no keyword difficulty, and no competitor discovery. This measures position only.
Troubleshooting
- Site not in
organic_results: it may rank below your max_pages depth. Raise max_pages by one and retry before concluding it does not rank.
- Positions look wrong for the market:
lr alone does not switch language. Set yandex_domain, lang, and lr together.
- Fewer pages than
max_pages: Yandex ran out of results. Check pagination_limit_reached and pages_processed on the item.
- Position jumps run to run: compare
search_location and search_language on both items before assuming a real ranking change.
See references/gotchas.md for cost guardrails and error recovery, and references/actor-index.md for the Actor routing table.
Related Yandex and international SERP Actors
1---2name: apify-yandex-rank-tracker3description: Use this as a yandex rank tracker. Check where a domain or URL ranks on Yandex for a keyword, in a specific Yandex domain, language, and lr region, using the Apify Yandex Search per-result Actor (johnvc/yandex-scrape-yandex-search-results-at-scale---per-result). Each run returns ranked organic rows with position, title, link, displayed_link, and snippet, so you match your site against the SERP and log the position with the run timestamp for a rank history. Use when the user wants a yandex rank tracker or yandex rank checker, wants to check Yandex rankings or keyword positions, wants yandex tracking of a site across Moscow, Saint Petersburg, or other regions, or wants to monitor Russian-market SERP positions over time on a schedule. Pay-per-result billing, MCP-ready for Claude and other AI agents.4license: MIT5---67# Yandex Rank Tracker: Keyword Positions by Region89Check and track where a site ranks on Yandex. One run per keyword returns the ranked organic list for a chosen Yandex domain, language, and region, with a `search_timestamp` on every item, so you can find your position today and keep a history of it.1011## When to use this skill1213- The user wants a Yandex rank tracker or a Yandex rank checker for a domain or URL.14- They ask "where do we rank on Yandex for X" or "what position is our page in Moscow".15- They want Yandex tracking of keyword positions on a weekly or daily schedule.16- They are watching Russian-market or CIS-market SERP positions and want the movement, not just a one-off SERP read.1718Not for: bulk SERP archives with no rank question attached (use the companion bulk Yandex scraper skill), Yandex Images or Yandex Videos vertical work, or Google positions.1920## What one run gives you (one dataset item per page, per result type)2122Every dataset item is one page of one result type, tagged by `item_type` (organic runs give `item_type` set to `organic`). The ranked rows sit in the nested `organic_results` array on that item, each row carrying `position`, `title`, `link`, `displayed_link`, and `snippet`. The item itself carries the tracking context you need to store alongside the position: `text` (the keyword), `search_timestamp`, `search_domain` and `search_domain_description`, `search_language` and `search_language_description`, `search_location`, `page_number`, `results_per_page`, `result_count`, `total_results_found`, `total_pages`, `pages_processed`, `pagination_limit_reached`, `max_pages_set`, and `pagination_stopped_by_limit`. The unused result-type arrays (`ads_results`, `knowledge_graph`, `inline_images`, `inline_videos`, `image_results`, `video_results`) come back empty on an organic run.2324## Prerequisites2526- Apify account (sign up at https://apify.com?fpr=9n7kx3&fp_sid=skillrepo).27- Authentication via `apify login`, or an `APIFY_TOKEN` environment variable (Apify Console, Settings, Integrations).2829## The Actor3031- Store page: https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result?fpr=9n7kx3&fp_sid=skillrepo32- Actor ID: `johnvc/yandex-scrape-yandex-search-results-at-scale---per-result`33- Pricing: pay per result, meaning per dataset item, plus a negligible start fee (see `references/gotchas.md`).3435## Run it with the Apify CLI3637Check the first page of Moscow rankings for a Russian keyword:3839```bash40apify actors call "johnvc/yandex-scrape-yandex-search-results-at-scale---per-result" -i '{"text":"купить ноутбук","yandex_domain":"yandex.ru","lang":"ru","lr":"213","max_pages":1}' \41 --json \42 --user-agent apify-awesome-skills/apify-yandex-rank-tracker \43 2>/dev/null44```4546Go two pages deep when the target site sits outside the top ten:4748```bash49apify actors call "johnvc/yandex-scrape-yandex-search-results-at-scale---per-result" -i '{"text":"crm software","yandex_domain":"yandex.com","lang":"en","lr":"84","max_pages":2}' \50 --json \51 --user-agent apify-awesome-skills/apify-yandex-rank-tracker \52 2>/dev/null53```5455Re-read a scheduled run's dataset later, without paying again:5657```bash58apify datasets get-items <DATASET_ID> --format json --user-agent apify-awesome-skills/apify-yandex-rank-tracker 2>/dev/null59```6061Every call carries the three flags this repo expects, `--json` (or `--format json`), `--user-agent apify-awesome-skills/apify-yandex-rank-tracker`, and `2>/dev/null`.6263## Run it from Claude or another AI agent (MCP)6465The Actor is MCP-ready. Add the hosted server URL:6667`https://mcp.apify.com/?tools=actors,docs,johnvc/yandex-scrape-yandex-search-results-at-scale---per-result`6869Then ask, for example, "Check where example.ru ranks on yandex.ru for 'доставка цветов' in Moscow and tell me the position." MCP setup docs: https://docs.apify.com/platform/integrations/mcp7071## Workflow72731. Pin the market. One tracked keyword is one Actor input. Set `yandex_domain`, `lang`, and `lr` together so the position you record is reproducible. Positions differ by region, so a rank history is only comparable when these three stay fixed.742. Set the depth. `max_pages` 1 covers the top ten, which answers most rank questions. Use 2 or 3 only when the site is not on page one. Each page is one billable item.753. Run one keyword per run. Keep the run inputs in your own list of tracked keywords rather than trying to batch several into one query string.764. Find the position. Read the item where `item_type` is `organic`, walk `organic_results`, and match your domain against `link` or `displayed_link`. Domain matching on `displayed_link` is more forgiving than exact URL matching. A page-2 item continues the numbering from page 1, so `position` is a SERP-wide rank.775. Log it. Store keyword, `search_timestamp`, `search_domain`, `search_location`, matched `position` (or "not found in N results"), and the matched `link`. That row is the rank history. Not found is a real data point, so keep it.786. Schedule the repeat. Wrap the same input in an Apify Schedule for weekly or daily tracking, then diff the newest position against the previous one to report movement.7980## Inputs that matter for rank tracking8182- `text` (string, required): the tracked keyword83- `yandex_domain` (enum): `yandex.com`, `yandex.ru`, `yandex.by`, `yandex.kz`, `yandex.uz`, `yandex.com.tr`84- `lang` (enum, 19 languages) and `lr` (region ID string, for example `213` Moscow, `2` Saint Petersburg, `225` Russia, `84` USA)85- `max_pages` (integer, default 2, max 100): tracking depth and the cost driver86- `include_organic_results` (boolean, default true): leave on for rank work87- `sort_mode` and `period`: leave at `relevance` and `all` for rank tracking, since sorting by date changes the ordering you are measuring8889Ads, knowledge graph, inline media, and the dedicated Images and Videos verticals are billable extras that do not help a rank check. Leave them off here.9091## Cost9293Billing is per dataset item, and one item is one page of one result type. A single-page rank check on one keyword is one item. Tracking 20 keywords weekly at one page each is 20 items per run and about 80 items a month. Multiply by the live per-result price in `references/gotchas.md` before committing to a schedule, and confirm the estimate with the user for anything large.9495## Honest limits9697- A position is the SERP at crawl time for that `lr` region. Yandex results move, so two runs minutes apart can differ by a position or two.98- Change `yandex_domain`, `lang`, or `lr` and you have started a new series, not continued the old one.99- The Actor returns the SERP. It does not store history for you, so the logging step is yours.100- Only the fields listed above are guaranteed. Extra per-row fields appear only when Yandex shows them for that query.101- No search volume, no keyword difficulty, and no competitor discovery. This measures position only.102103## Troubleshooting104105- Site not in `organic_results`: it may rank below your `max_pages` depth. Raise `max_pages` by one and retry before concluding it does not rank.106- Positions look wrong for the market: `lr` alone does not switch language. Set `yandex_domain`, `lang`, and `lr` together.107- Fewer pages than `max_pages`: Yandex ran out of results. Check `pagination_limit_reached` and `pages_processed` on the item.108- Position jumps run to run: compare `search_location` and `search_language` on both items before assuming a real ranking change.109110See `references/gotchas.md` for cost guardrails and error recovery, and `references/actor-index.md` for the Actor routing table.111112## Related Yandex and international SERP Actors113114- Yandex Search Scraper, pay per event edition (full SERP reads): https://apify.com/johnvc/Scrape-Yandex?fpr=9n7kx3&fp_sid=skillrepo115- Yandex Reverse Image Search API: https://apify.com/johnvc/yandex-reverse-image-search?fpr=9n7kx3&fp_sid=skillrepo116- Baidu Search Scraper (Chinese market): https://apify.com/johnvc/Baidu-Search-Scraper?fpr=9n7kx3&fp_sid=skillrepo117- Naver Search API (Korean market): https://apify.com/johnvc/naver-search-api?fpr=9n7kx3&fp_sid=skillrepo