Yandex SERP Scraper: Rank Tracking, Ads and Regions
Yandex SERP Scraper is an Apify actor (API) by CheapAPI Labs. Yandex search results for rank tracking with ads and AI answers in about 640 Russian and 80 Turkish regions. It costs $6.00 per 1,000 result pages on the Apify Free plan and $4.00 on Gold, billed through your Apify account with no API key.
Compared with the most used Yandex actor on Apify Store (about 2,200 users): 1,000 search terms with 10 results each costs $6 on Free and $4 on Gold here and $130 and $74 there (Apify Store listing prices, checked October 2026).
Our prices updated 30 October 2026; competitor prices as checked in the comparison. 12 Apify users have run this actor (Apify Store count, 30 October 2026).
What does Yandex SERP Scraper return?
Scrape Yandex search results in bulk as clean JSON: organic rankings with title, URL, snippet and page date, or the full results page with ads and result blocks in on page order. Works for yandex.ru, yandex.com.tr, yandex.com, yandex.kz, yandex.by and yandex.uz, with about 640 cities and regions in Russia and 80 in Turkey (1,100+ worldwide) selectable on yandex.ru and yandex.com.tr (Moscow, Saint Petersburg, Kazan, Istanbul …) and IP based location on the other domains. Optional AI answers written by Yandex search, with sources. No proxies, browser or Yandex account needed.
90 to 95% cheaper for 1,000 search terms than the two most used Yandex Actors, which charge per single term run (Store prices, October 2026).
| Quick facts | |
|---|---|
| Price | $6 per 1,000 searches of up to 20 results (Free plan), $4 on Gold+; no start fee |
| Depth | up to 250 results per search term, Yandex's exact positions |
| Where | yandex.ru, .com.tr, .com, .kz, .by, .uz; ~640 Russian and ~80 Turkish regions |
| Volume | up to 10,000 searches per run, about 6 minutes per 1,000 |
| Extras | full page with ads and AI overview, rank changes, monitoring, AI answers |
Why this Actor
- $6 per 1,000 searches of up to 20 results on the Free plan and $4 on Gold and above plus Apify platform usage (about $0.05 to $0.08 per 1,000 terms), no start or setup fee; the only other charges are the Full results page rate ($0.008 Free / $0.005 Gold per 10 results), the $0.0012 no results fee and the optional $0.06 AI answer.
- Bulk in one run: paste hundreds or thousands of search terms; each usually finishes in 2 to 10 seconds (rare queue delays of up to about 95 s are covered by an automatic backup request).
- Up to 250 results per search term with Yandex's exact positions (100 results come from a single results page).
- City level rankings: pick a region by name ("Moscow", "Kazan", "Istanbul") or Yandex region ID, or one per search term (
купить диван | Kazan); desktop or mobile. - AI answers (optional, $0.06 per search term): the answer Yandex search writes for a term (Russian, Kazakh, Uzbek), with its cited sources.
- One Actor for the whole job: city regions, the full results page (ads, AI overview, knowledge panel), rank change tracking and monitoring. The only cheaper listing is a very new per call Actor (~2 users) for plain pages.
- Monitoring: Only new results delivers just the URLs that appeared since your last run, you pay for those, plus $0.0012 per processed request when a term has nothing new.
- Rank tracking built in: list your domains and get
isTrackedon every result, or one row per search term with each domain's position, and, with Compare with the previous run, the position change of every result since your last run (free). - Full results page with AI overview: ads, the Alice AI quick answer with its sources, the knowledge panel, image/video/product blocks and related searches, in page order.
- Fair billing: charged per started group of 20 delivered organic results (10 on the full results page); search terms Yandex rejects are free, and a search that finds nothing costs only a $0.0012 no results fee.
One example row from a real run, shortened:
{
"id": "da771f1da55fe13c",
"runId": "Hs4ujkV031SOo3a9H",
"searchQuery": "python",
"searchDomain": "yandex.ru",
"region": "Russia",
"regionId": 225,
"language": "auto",
"device": "desktop",
"scrapedAt": "2026-10-01T19:36:02.717Z",
"type": "organic",
"position": 1,
"title": "The official home of the Python Programming Language",
"url": "https://www.python.org/",
"domain": "python.org",
"snippet": "The core of extensible programming is defining functions. Python allows mandatory and optional arguments, keyword arguments, and even arbitrary argument lists. More about defining functions in Python 3.",
"headline": null,
"passages": [
"The core of extensible programming is defining functions. Python allows mandatory and optional arguments, keyword arguments, and even arbitrary argument lists. More about defining functions in Python 3."
],
"modifiedDate": "2006-10-29",
"documentLanguage": "en",
"mimeType": "text/html",
"savedCopyUrl": "https://yandexwebcache.net/yandbtm?fmode=inject&",
"isTracked": false,
"totalResults": 244710,
"correctedQuery": null
}Which fields do you get?
Result type "Organic results" (default), one row per organic result:
| Field | Type | Example |
|---|---|---|
searchQuery |
string | купить ноутбук |
searchDomain |
string | yandex.ru |
type |
string | organic (ai-answer and related-searches for the extra rows) |
region, regionId |
string, number | Moscow, 213 |
position |
number | 1 (Yandex's exact position, 1 to 250) |
title |
string | Ноутбуки для работы купить по низкой цене… |
url |
string | https://www.mvideo.ru/noutbuki-… |
domain |
string | mvideo.ru |
snippet |
string | snippet passages joined (or the page description) |
passages |
array | the snippet's separate text passages |
headline |
string / null | page description shown by Yandex |
modifiedDate |
string / null | 2018-05-21, page date reported by Yandex (not always the last edit) |
documentLanguage |
string / null | ru |
mimeType |
string / null | text/html, application/pdf … |
savedCopyUrl |
string / null | Yandex's cached copy of the page |
isTracked |
boolean | true when the domain is in Track domains |
totalResults |
number / null | 37812154 (Yandex's estimate) |
correctedQuery |
string / null | the spelling Yandex searched instead |
domainGroupPosition |
number | only with Results per website 2 to 3 |
previousPosition, positionChange, isNew, previousRunAt |
number / null, number / null, boolean, string | with Compare with the previous run: 7, 3 (moved up 3 places), false |
id |
string | e714ca1d5650c2f4, same search, position and URL give the same id (not unique per run) |
runId, scrapedAt, language, device |
string | the run that collected the row, collection time, interface language setting (auto = domain default; the page language is documentLanguage) and device (desktop in Organic results mode; the Device option applies to the full results page only) |
Result type "Full results page", one row per block of the results page, in order:
| Field | Type | Example |
|---|---|---|
type |
string | organic, ad or block |
position |
number | place on the page among all blocks (1, 2, 3 …) |
organicPosition / adPosition |
number / null | position among organic results / among ads |
title, url, domain, snippet |
as above (url is null for ads) |
|
breadcrumbs |
array | ["Ноутбуки, планшеты, компьютеры", "Ноутбуки"] |
rating |
number / null | 4.6, shop rating shown next to the result |
sitelinks |
array | links under a result: [{"title": "Менеджер", "url": "https://spb.hh.ru/vacancies/menedzher"}] |
blockType, blockSubtype, blockText |
ai-overview (Alice AI quick answer, full text), knowledge-panel, images, videos, products, ads-block … |
|
blockLinks |
array | links of a block, the AI overview's sources, a knowledge panel's links, image/video items: [{"title": "ru.wikipedia.org", "url": "https://ru.wikipedia.org/wiki/…"}] |
relatedSearches |
array | on a related-searches row: ["эйфелева башня в париже", "эйфелева башня высота", …] |
page |
number | results page the block came from |
htmlUrl |
string | link to the saved page HTML (when Save the page HTML is on) |
totalResults, correctedQuery, modifiedDate, passages and domainGroupPosition exist only in Organic results mode (the full results page does not contain them).
AI answer (option), one extra row per search term with type: "ai-answer":
| Field | Type | Example |
|---|---|---|
answerText |
string / null | Выбор ноутбука для учёбы зависит от того, что именно предстоит делать. [1] … (Markdown; [1] = first source) |
answerSources |
array | [{"url": "https://hi-tech.mail.ru/…", "title": "25 лучших ноутбуков для учебы 2026…", "used": true}] |
answerRejected |
boolean | true when Yandex declined to answer |
The row also carries the common fields (id, runId, searchQuery, searchDomain, scrapedAt). region, regionId, device and position are null, because the answer is not region specific and is requested once per search term even with Several regions.
Example AI answer row (real output, shortened):
{
"id": "5a9d3af82cdb697c",
"runId": "Hs4ujkV031SOo3a9H",
"searchQuery": "python",
"searchDomain": "yandex.ru",
"region": null,
"regionId": null,
"language": "auto",
"device": null,
"scrapedAt": "2026-10-01T19:36:02.717Z",
"type": "ai-answer",
"position": null,
"answerText": "**Python** — **высокоуровневый язык программирования общего назначения** с динамической типизацией и автоматическим управлением памятью. [1][5] Создан нидерландским программистом Гвидо ван Россумом в 1991 году. [5] \n\n**Н …",
"answerSources": [
{
"url": "https://ru.wikipedia.org/wiki/Python",
"title": "Python — Википедия",
"used": true
},
{
"url": "https://skillbox.ru/media/code/dlya_chego_nuzhen_python/",
"title": "Python: что это за язык, для чего нужен и где используется / Skillbox Media",
"used": true
}
],
"answerRejected": false
}
With Compare with the previous run, organic results look like this (illustrative values; the fields are real):
{ "searchQuery": "купить ноутбук", "region": "Moscow", "type": "organic", "position": 4, "url": "https://www.citilink.ru/catalog/noutbuki/", "domain": "citilink.ru", "previousPosition": 7, "positionChange": 3, "isNew": false, "previousRunAt": "2026-10-01T16:16:08.854Z" }
and a "One row per search term" row (shortened, illustrative values):
{
"searchQuery": "купить ноутбук", "region": "Moscow", "organicCount": 20, "previousRunAt": "2026-10-01T16:16:08.854Z",
"trackedDomains": [
{ "domain": "citilink.ru", "position": 4, "url": "https://www.citilink.ru/catalog/noutbuki/", "previousPosition": 7, "positionChange": 3 },
{ "domain": "dns-shop.ru", "position": 6, "url": "https://www.dns-shop.ru/catalog/17a892f816404e77/noutbuki/", "previousPosition": 6, "positionChange": 0 }
]
}
With Only results that moved at least N places, a daily run stores only the results whose position changed by N or more, plus new ones.
With Output format "One row per search term", one row holds all results of a search term: organicResults, ads, blocks, aiAnswer, organicCount, adsCount, totalResults, totalResultsText, correctedQuery, trackedDomains (each tracked domain with its position or null, plus previousPosition and positionChange when comparing with the previous run), noNewResults (true when “Only new results” found nothing new for the term; the row then has organicCount 0) and htmlUrls (links to the saved page HTML with “Save the page HTML”).
Related searches come as one extra row per search term with type: "related-searches" and relatedSearches (full results page; in "One row per search term" output they are the relatedSearches field).
Run summary, the RUN_SUMMARY record of the run's key value store (also linked in the Output tab):
- Counts:
searchTermsRequested,searchTermsCompleted,searchTermsWithoutResults,searchTermsWithoutNewResults,searchTermsFailed,searchTermsPartial(a later results page failed: only the delivered part is charged),searchTermsSkippedByLimit,searchTermsInvalid,searchTermsDuplicate,pagesCharged,rowsDelivered(result rows stored, not counting AI answer and related searches rows; 1 per term with One row per search term),organicResultsChecked,organicResultsDelivered(stored, after filters),adsDelivered,aiOverviewsFound,relatedSearchesFound,aiAnswersDelivered,trackedDomainHits,backupRequests,historyReadFailures,historyWriteFailures. - State:
searchDomain,region,resultType,stoppedAtSpendingLimit,runError(only when the run stopped early),finishedAt,problems(the first 100 search terms that had a problem, with the reason in plain words) andtermsWithoutNewResults(the first 100 terms with nothing new in Only new results, kept apart from real problems).
Example RUN_SUMMARY excerpt (shape of a real run with a no results term and a declined AI answer):
{
"searchTermsRequested": 3, "searchTermsCompleted": 2, "searchTermsWithoutResults": 1, "searchTermsFailed": 0,
"pagesCharged": 2, "organicResultsDelivered": 20, "aiAnswersDelivered": 1, "stoppedAtSpendingLimit": false,
"problems": [
{ "searchQuery": "zxqv wlkj", "reason": "Yandex returned no results for this search term (charged the no-results fee, $0.0012)." },
{ "searchQuery": "declined", "reason": "Yandex declined to write an AI answer for this search term (the AI answer request is still charged)." }
]
}
Dataset views (Output tab, or …/datasets/<id>/items?view=<name> in the API): overview (Results, every row type, including ads and blocks of the full results page), rankTracking (positions, changes and tracked flags), searches (one row per search term), ads (full page: ads and blocks), aiAnswers and changes (position changes and new results, with Compare with the previous run).
How much does Yandex SERP Scraper cost?
You pay per event, through your Apify account. Main price: $6.00 per 1,000 result pages on the Apify Free plan and $4.00 on Gold. Every event and plan:
| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| Results page (20 organic results)Per started group of 20 delivered organic results of one search term (e.g. 20 results = 1 page, 100 results = 5 pages, 3 results = 1 page). No start fee. | $0.006 | $0.0055 | $0.005 | $0.004 |
| Full results page (10 organic results with ads and result blocks)Result type “Full results page”: per started group of 10 delivered organic results of one search term, including every ad and result block shown between them (and the saved HTML when requested). | $0.008 | $0.007 | $0.006 | $0.005 |
| Search without resultsPer search term that Yandex processed but that gave nothing to deliver (no results, or the search could not be completed after it was processed). With “Only new results”, when nothing is new: per processed request. Invalid search terms and searches that were never processed are free. | $0.0012 | $0.0012 | $0.0012 | $0.0012 |
| AI answerOption “AI answer”: one AI answer written by Yandex search for a search term, with its cited sources (Russian, Kazakh or Uzbek). Charged when Yandex processed the request, also when it declined to answer. | $0.06 | $0.06 | $0.06 | $0.06 |
How do I call Yandex SERP Scraper API from code?
Every run is one HTTP request to the Apify API with your Apify token; the input below is the actor's own example. The synchronous endpoint returns the rows in the response for runs up to 300 seconds; for longer runs start a run and fetch its dataset.
curl -X POST "https://api.apify.com/v2/acts/cheapapi~yandex-serp-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
-d '{"queries":["купить ноутбук","погода москва","купить диван | Kazan"],"searchDomain":"yandex.ru","region":"Moscow","maxResults":20}'With the JavaScript client:
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cheapapi/yandex-serp-scraper').call({
"queries": [
"купить ноутбук",
"погода москва",
"купить диван | Kazan"
],
"searchDomain": "yandex.ru",
"region": "Moscow",
"maxResults": 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();How does Yandex SERP Scraper compare with alternatives?
Typical run: 1,000 search terms × 10 organic results (10,000 result rows; AI answers not included). Actor fees of public Apify Store listings (Free plan / Gold plan), checked October 2026.
| Option | 1,000 search terms × 10 results | Search terms per run | Notes |
|---|---|---|---|
| Most used Yandex Store Actor (~2,200 users) | $130 / $74 | 1 (setup fee $0.08 / $0.05 on every run) | $0.05 / $0.024 per results page |
| Second most used (~270 users) | $70 / $40 | 1 | $0.007 / $0.004 per result |
| Same developer's per result listing (~85 users) | $130 / $74 | 1 | same fees as the first row |
| Per item Actor (~60 users) | $50 / $10 | many | $0.005 / $0.001 per result row + $0.005 per run |
| Flat per result Actor (~40 users) | $34 / $34 | many | $0.0034 per result |
| Per result Actor (~23 users) | $40 / $32 | many | $0.004 / $0.0032 per result |
| Budget per result Actor (~13 users) | $20 / $14 | many | $0.002 / $0.0014 per result + the same per run |
| Per call Actor (~2 users) | $2 / $1.60 | many | $0.002 / $0.0016 per results page ("standard call") |
| This Actor | $6 / $4 | many (up to 10,000) | no start fee |
Plainly: against the two most used Yandex Actors we are 95% / 95% cheaper (Free / Gold) than the first and 91% / 90% than the second, and cheaper than every listed alternative except one very new per call listing (~2 users), which costs about a third (Free) to 40% (Gold) of our price for plain results pages; you get regions, exact positions up to 250, the full page with ads, rank changes and AI answers here. Small per row or per run fees of other Actors ($0.00001 per row up to $0.005 per run) are left out of the table, negligible when 1,000 terms run in one run. Apify platform usage is billed separately for this Actor (see Pricing); the table compares Actor fees only. Competitor prices are a snapshot from their public listings (October 2026) and may change. Our price stays the same with 20 results per term, while per result Actors double (the second one: $140 / $80).
Per plan, 1,000 search terms × 10 results (most used Actor, one run per search term, vs. this Actor). Apify lets us set Free, Bronze, Silver and Gold prices; Platinum and Diamond pay our Gold price.
| Apify plan | Most used Actor | This Actor | Difference |
|---|---|---|---|
| Free | $130 | $6.00 | 95% cheaper |
| Bronze | $105 | $5.50 | 95% cheaper |
| Silver | $85 | $5.00 | 94% cheaper |
| Gold, Platinum, Diamond | $74 | $4.00 | 95% cheaper |
What is it used for?
- Rank tracking for Russian, Turkish and CIS markets: schedule daily runs with Compare with the previous run and get
positionChangefor every result and tracked domain, per city. - Local SEO: see how rankings differ between Moscow, Saint Petersburg, Kazan or Novosibirsk, list them in Several regions to compare all cities in one run.
- Competitor and ad research: with Full results page, see which advertisers bid on your keywords and where product carousels appear.
- Content gap analysis: collect the top 100 to 250 results for a topic and analyse titles, snippets and domains.
- Brand monitoring and reputation: track which pages rank for your brand name, including
site:and exact phrase searches. - Datasets for AI and research: clean, deduplicated SERP data with consistent
ids.
What is not included?
- Search volume / Wordstat keyword frequencies, keyword ideas, not provided.
- Yandex Maps places and reviews, Yandex Market products, Yandex Images and News verticals, this Actor covers Yandex web search.
- Ad landing URLs, ads (and their sitelinks) link through Yandex's ad redirect, so ads come with the advertiser's displayed domain, title, text, rating and sitelink titles, but
urlisnull. - Content of the ranking pages, only what the results page shows.
- Other Yandex domains and interface languages, the six Yandex searches in this Actor (yandex.ru, .com.tr, .com, .kz, .by, .uz) and six interface languages (plus automatic) are what Yandex offers for automated search; some scrapers list more domains or languages.
What are the limits?
- Results are not personalized (no Yandex account or search history), so positions can differ slightly from a signed in browser.
- Positions above 100 come from separate result pages, which Yandex may reorder slightly between requests.
- AI answers are not region specific, are written in Russian, Kazakh or Uzbek, and Yandex sometimes declines to answer (the request is still charged).
- The full results page reflects Yandex's layout; if Yandex redesigns the page, ads and blocks may be classified less precisely until we update the Actor (organic results mode is not affected).
- The AI overview (Alice AI quick answer), knowledge panel and related searches are returned when Yandex includes them in the results page it serves; Yandex shows them only for some search terms, and some are added later by the browser and then not included.
modifiedDateis the date Yandex reports for the page, which is often older than the last edit.- Region selection works for yandex.ru and yandex.com.tr; for other domains use Location by IP address.
- Now and then Yandex answers a full results page request with a verification page instead of results. The Actor sends it once more; if that fails too, the search term is reported in
RUN_SUMMARYand charged only the $0.0012 no results fee. - Raising Results per search term later: the added positions get
isNew: null(unknown) in the first comparison, because the previous run did not look that deep. To start the history from scratch, delete the history key value store in your account (Storage → Key value stores; default nameyandex-serp-rank-history, or your History store name). It keeps one small record per search term and settings; for Only new results it remembers at most the latest 10,000 URLs per term, so older URLs beyond that could be delivered again as new. - Compare with the previous run compares runs with the same search term and the same settings (domain, region, language, device, period, sort, safe search, typo fixing, results per website, location IP, result type).
- A region outside the domain's country (e.g. Moscow on yandex.com.tr) is allowed, it shows that domain as seen from the region, and the log says so.
Questions about Yandex SERP Scraper
Is it legal, and does the output contain personal data?
The Actor collects publicly visible search results: titles, URLs and snippets of web pages (which may mention people, e.g. on news or profile pages). No account, cookie or user data is collected, and nothing about you is sent to Yandex except your search terms and options. Make sure your use of the data complies with the laws of your country and the rights of the content owners.
How fresh is the data, and is it the same as in my browser?
Every search is made live when you run the Actor; nothing is served from an old cache. You get the not personalized results Yandex shows to a signed out user in the chosen region and device; your own browser can differ slightly because of your search history, account and exact location.
How fast and reliable is it?
Each search term usually takes 2 to 10 seconds, and many run in parallel: 1,000 search terms take about 6 minutes (measured: 136 terms in 51 seconds). In our live load tests 276 of 276 search terms were completed without a failure; in a separate timing test of 60 searches the median was 3 seconds and 2 searches waited about 95 seconds in Yandex's queue, the Actor now sends one backup request after 15 seconds for such cases (counted in RUN_SUMMARY.backupRequests).
Why did I get fewer results than I asked for?
Yandex shows at most 250 results per search term, and for rare terms far fewer. For deep results (above 100), Yandex can reorder results between its result pages; a URL that appears twice is delivered once, so a few positions may be missing. You are charged only for delivered results.
Why was I charged for a search with no results, or for a declined AI answer?
Yandex processed the search but found nothing (or it could not be completed after processing), which costs a small no results fee of $0.0012. Likewise, when Yandex declines to write an AI answer, it still bills that request, so the $0.06 AI answer fee applies (answerRejected: true). Search terms rejected before processing (e.g. longer than 400 characters) are free. If a later results page of a term fails, the delivered part is kept and only those pages are charged (Only part of the results could be collected in problems).
Which region should I use, and can I use search operators?
Rankings on yandex.ru depend strongly on the city: use the city your customers search from ("Moscow", "Saint Petersburg", "Novosibirsk"); without a region you get results for the whole country (Russia or Turkey). Russian names and region IDs work too, and an unknown name gets suggestions. Yandex operators such as site:, "exact phrase", -word and !word work in search terms. term | City sets a region for one term only when the part after | is a known place; if you need Yandex's OR operator | followed by a place name, put the region in the Region field instead.
Is there a limit on the Apify Free plan?
Yes: up to $0.25 of results per Actor per month (about 40 searches of up to 20 results). The run then ends with a clear message; any paid Apify plan removes the limit. Apify platform usage is billed separately for all plans.
How do I track rankings or get only new results?
Schedule the Actor (e.g. daily) and turn on Compare with the previous run, every organic result gets previousPosition, positionChange (positive = moved up) and isNew, and each tracked domain its position change, or Only new results, which delivers only organic results whose URL is new for that search term (you pay only for those; if nothing is new, $0.0012 per processed request applies). Both options can be combined: you get only the new results, while tracked domain position and the rank history still cover every result found this run. The history stays in your account.
Why is url null for ads?
Ads link through Yandex's click tracking redirect, which is not the advertiser's page. You get the advertiser's displayed domain, title, text and rating instead.
Run Yandex SERP Scraper on Apify
The form opens with a working example. Free Apify accounts get a small monthly allowance.