YouTube Search Results & Rank Tracker Scraper avatar

YouTube Search Results & Rank Tracker Scraper

Pricing

from $0.18 / 1,000 results

Go to Apify Store
YouTube Search Results & Rank Tracker Scraper

YouTube Search Results & Rank Tracker Scraper

Give it keywords and get YouTube search results with rank, title, channel, views and duration. Rank tracker mode compares keyword rankings with the last run: rank change, new and dropped results, target videos or channels flagged, several countries per run. $0.24 per 1,000 results, failures free.

Pricing

from $0.18 / 1,000 results

Rating

0.0

(0)

Developer

Gautham Krishna

Gautham Krishna

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 hours ago

Last modified

Share

Get YouTube search results as clean rows with rank, title, channel and views, for SEO teams tracking keyword rankings and marketers looking for creators.

Use cases, each with a ready-to-run example:

Each result also has the duration, upload age, thumbnail and snippet. Add video URLs to get full details for specific videos too: description, tags, likes, category and upload date. Rank tracker mode compares each result with the last run, flags your own or competitors' videos and channels, and covers several countries in one run. Channel discovery finds YouTube channels on a topic within a subscriber range, such as small creators with 1,000 to 100,000 subscribers for outreach.

You pay $0.24 per 1,000 results ($0.00024 each), and less on Apify Store discount tiers (Bronze, Silver, Gold), down to $0.18 per 1,000 on Gold. Failed queries, unavailable videos, invalid input, dropped rows and channels left out by a subscriber range are never charged. In the final test run, 56 queries in 15 languages all returned results, and all 50 real videos in the lookup returned full details.

What you get per result

FieldWhat it holds
query, rankThe search it came from and its position, starting at 1
typevideo, short, channel, playlist or movie
id, urlVideo, channel or playlist ID and its link
title, thumbnailAs shown in the results
channelName, channelId, channelUrl, channelVerifiedThe uploader. Joint uploads also list every channel in collaborators
viewCount, viewCountTextViews as a number and as YouTube shows them
duration, durationSecondsLength, such as 1:00:06 and 3606
publishedTimeTextUpload age as shown, such as 6 years ago
descriptionSnippetThe description excerpt shown under the result
badgesLabels such as 4K, CC, New or LIVE
isLive, watchingCountLive streams show viewers watching now instead of views
subscriberCountText, channelHandleOn channel results
subscriberCountOn channel results, the subscriber count as a number, such as 90600 for 90.6K subscribers. It is as rounded as YouTube shows it, and null when the channel hides its count. It is always the last field of a channel row
videoCountTextOn playlist and channel results
statusok, no_results, unavailable, invalid_input, error, or dropped (rank tracker only)

Rows from the video lookup add:

FieldWhat it holds
descriptionThe full description
keywordsThe uploader's tags
likeCountLikes, when the uploader shows them
categorySuch as Education or Music
publishDate, uploadDateExact dates with time zone
isLive, isLiveContent, liveStartTime, liveEndTimeLive status and stream times
isShort, isFamilySafe, isUnlistedFlags from YouTube

Rows from the rank tracker options add:

FieldWhenWhat it holds
countrycountries is setThe country this result was searched from
isTargettargets is settrue when the result is one of your target videos, or comes from one of your target channels
previousRankcompareWithLastRun is onIts rank in the last run, or null if it was not in it
rankChangecompareWithLastRun is onpreviousRank minus rank, so 3 means it moved up three places
isNewcompareWithLastRun is ontrue when it was not in the last run's results. All three fields are null on the first run

Input

{
"queries": ["python tutorial for beginners", "receta de paella valenciana"],
"maxResultsPerQuery": 40,
"type": "video",
"uploadDate": "month",
"duration": "long",
"sortBy": "viewCount",
"videos": ["https://www.youtube.com/watch?v=jNQXAC9IVRw", "dQw4w9WgXcQ"]
}
OptionValues
typeall, video, shorts, channel, playlist, movie
uploadDateany, hour, today, week, month, year
durationany, short (under 4 min), medium (4 to 20 min), long (over 20 min)
sortByrelevance, viewCount
featureslive, 4k, hd, subtitles, creativeCommons, 360, vr180, hdr
language, countryInterface language such as en and two-letter country such as US. Results are localised for that country
includeShortsShelvesAlso return the Shorts that YouTube shows in shelves between results
countriesSeveral two-letter countries, such as ["US", "IN", "DE"]. Every query runs once per country
compareWithLastRunRank tracker mode, see below
targetsVideos (URL or ID) and channels (@handle, channel URL or UC... ID) to flag with isTarget
minSubscribers, maxSubscribersKeep only channels in this subscriber range, see below

You can send only queries, only videos, or both. The video lookup accepts watch, youtu.be, Shorts, embed and live links, plus bare 11-character IDs.

Output example

These are real rows from a test run. A search result:

{
"query": "python tutorial for beginners",
"rank": 1,
"type": "video",
"id": "kqtD5dpn9C8",
"url": "https://www.youtube.com/watch?v=kqtD5dpn9C8",
"title": "Python for Beginners - Learn Coding with Python in 1 Hour",
"channelName": "Programming with Mosh",
"channelId": "UCWv7vMbMWH4-V0ZXdmDpPBA",
"channelUrl": "https://www.youtube.com/@programmingwithmosh",
"viewCount": 25573529,
"viewCountText": "25,573,529 views",
"duration": "1:00:06",
"durationSeconds": 3606,
"publishedTimeText": "6 years ago",
"thumbnail": "https://i.ytimg.com/vi/kqtD5dpn9C8/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAlOSbnBnoUI-N9v2_o-DYUecBN7A",
"descriptionSnippet": "Learn Python basics in just 1 hour! Perfect for beginners interested in AI and coding. ⚡ Plus, get 6 months of PyCharm FREE with ...",
"badges": [],
"isLive": false,
"channelVerified": true,
"collaborators": [],
"watchingCount": null,
"status": "ok"
}

A video lookup, with the search-only fields that are null on these rows (query, rank, viewCountText and so on) left out:

{
"type": "video",
"id": "jNQXAC9IVRw",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"title": "Me at the zoo",
"channelName": "jawed",
"channelId": "UC4QobU6STFB0P71PMvOGN5A",
"channelUrl": "https://www.youtube.com/@jawed",
"viewCount": 441938487,
"duration": "0:19",
"durationSeconds": 19,
"thumbnail": "https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg?sqp=-oaymwEmCOADEOgC8quKqQMa8AEB-AG-AoAC8AGKAgwIABABGFUgWShlMA8=&rs=AOn4CLA9eLBatYv9WbkD4BbZ2Im-biSPTw",
"isLive": false,
"input": "https://www.youtube.com/watch?v=jNQXAC9IVRw&t=10",
"status": "ok",
"description": "Microplastics are accumulating in human brains at an alarming rate\nhttps://www.youtube.com/watch?v=0PT5c1z3LL8\n\n“Nanoplastics and Human Health” with Matthew J Campen, PhD, MSPH\nhttps://www.youtube.com/watch?v=RRBN_4L09Mg\n\n00:00 Intro\n00:05 The cool thing\n00:17 End",
"keywords": ["me at the zoo", "jawed karim", "first youtube video"],
"likeCount": 20034803,
"category": "Film & Animation",
"publishDate": "2005-04-23T20:31:52-07:00",
"uploadDate": "2005-04-23T20:31:52-07:00",
"isLiveContent": false,
"liveStartTime": null,
"liveEndTime": null,
"isShort": false,
"isFamilySafe": true,
"isUnlisted": false
}

A video that does not exist comes back as "status": "unavailable", "message": "Video unavailable" and costs nothing.

Find channels by subscriber count

Set minSubscribers, maxSubscribers or both to get channels on a topic within a subscriber range.

{
"queries": ["sourdough baking", "watercolor painting", "home espresso"],
"type": "channel",
"maxResultsPerQuery": 50,
"minSubscribers": 1000,
"maxSubscribers": 100000
}

A kept channel from the test run, with the empty fields left out:

{
"query": "sourdough baking",
"rank": 4,
"type": "channel",
"id": "UCym_8JHA4htlFLIHGpNZGrQ",
"url": "https://www.youtube.com/@FullProofBaking",
"title": "Full Proof Baking",
"channelName": "Full Proof Baking",
"channelId": "UCym_8JHA4htlFLIHGpNZGrQ",
"channelUrl": "https://www.youtube.com/@FullProofBaking",
"thumbnail": "https://yt3.googleusercontent.com/ytc/AIdro_ndWmzk7nuUIL6cUYxx64d_L0Vjq4foburvGQ33-j5GHw=s176-c-k-c0x00ffffff-no-rj-mo",
"descriptionSnippet": "Sourdough-obsessed home baker from Chicago.",
"channelVerified": false,
"channelHandle": "@FullProofBaking",
"subscriberCountText": "90.6K subscribers",
"status": "ok",
"subscriberCount": 90600
}

A range always searches channels. With type set to all, the search switches to channels, since mixed results hold too few channels to fill a list. With type set to video, shorts, playlist or movie, the run returns one free row that explains the mismatch.

rank stays the channel's position in YouTube's channel results, so ranks skip the channels left out. In the search above, ranks 2 and 3 were outside the range.

maxResultsPerQuery counts the channels kept. The scraper reads more pages to fill it while at least about a third of the channels read so far are in range, then stops, so a narrow range can return fewer. Channels outside the range, and channels that hide their count, are left out and cost nothing. The status message says how many were left out.

The count comes from the text YouTube shows in your language, such as 1.2M, 51,5 K, 124.000, 22.2 लाख or 12.4万. A channel near a limit can fall either side of it as its rounded count changes. The dataset's Channels view shows rank, channel, handle, subscribers and link side by side.

The output has public channel details only, with no emails or other contact data.

Rank tracker mode

Turn on compareWithLastRun and schedule the same input daily or weekly. Each run compares every query in every country with the last complete run of it in your account.

{
"queries": ["python tutorial for beginners", "receta de paella valenciana"],
"maxResultsPerQuery": 20,
"countries": ["US", "IN", "DE"],
"compareWithLastRun": true,
"targets": ["@programmingwithmosh", "UC8butISFwT-Wl7EV0hUK0BQ", "https://youtu.be/kqtD5dpn9C8"]
}

A result from the second run of a test, with some search fields left out:

{
"query": "python tutorial for beginners",
"rank": 2,
"type": "video",
"id": "kqtD5dpn9C8",
"url": "https://www.youtube.com/watch?v=kqtD5dpn9C8",
"title": "Python for Beginners - Learn Coding with Python in 1 Hour",
"channelName": "Programming with Mosh",
"channelId": "UCWv7vMbMWH4-V0ZXdmDpPBA",
"viewCount": 25639490,
"isTarget": true,
"previousRank": 1,
"rankChange": -1,
"isNew": false,
"country": "US",
"status": "ok"
}

A result that was in the last run and is gone now comes back as a free dropped row, with its last rank and the details it had then. This one is from the same run, with the empty fields left out:

{
"query": "python tutorial for beginners",
"rank": null,
"type": "video",
"id": "qwAFL1597eM",
"url": "https://www.youtube.com/watch?v=qwAFL1597eM",
"title": "Python Tutorial for Beginners (with mini-projects)",
"channelName": "freeCodeCamp.org",
"channelId": "UC8butISFwT-Wl7EV0hUK0BQ",
"previousRank": 18,
"rankChange": null,
"isNew": false,
"status": "dropped",
"message": "Ranked 18 in the last run on 2026-10-16, missing from this run's 20 results",
"isTarget": true,
"country": "US"
}

Each query, country, language, filter set and max results value has its own history. Change any of them and the next run starts a new history, because a deeper or differently filtered list is not comparable. A query that failed, returned nothing or stopped at your maximum charge keeps the previous history, so the next run still compares with the last complete run. The history lives in a key-value store named youtube-search-scraper-monitor in your own Apify account. Delete it to start over.

The dataset's Rank tracker view shows country, rank, last run rank, change, new and target side by side.

With a subscriber range on, the range is part of the history too. A channel from the last run counts as dropped only when this run read past its old rank and did not find it. A channel this run found outside the range, or one past where this run stopped reading, is not a dropped row.

Targets given as @handle, /c/ or /user/ links are looked up once per run to find the channel ID, so they also match results whose channel link has no handle. A target YouTube does not know comes back as a free invalid_input row.

Run it on a schedule

A daily or weekly run of the rank tracker shows how your videos and channels move for the searches you care about. We tracked 60 channel searches on 17 Oct and ran them again on 20 Oct. Of the 1,423 channels returned, 338 were new to their search, 973 had moved and 112 held their rank, and 280 free dropped rows named the channels that fell out.

  1. Set your input with compareWithLastRun: true and click Save as a new task.
  2. On the task page, click Actions, then Schedule, and pick how often it runs. Apify's schedules guide covers cron times and time zones.
  3. On the task's Integrations tab, choose where each run's results go.
IntegrationWhat it does
SlackPosts a message to your channel when a run finishes
Google DriveSaves each run's results as a file in your Drive
WebhookSends the finished run, with its dataset ID, to your own URL
Make, Zapier, n8nAdds each new row to a Google Sheet, a CRM or a database

Each row has a stable id, the video or channel ID, so a sheet can chart one result's rank across runs.

How well it works

In the test run, 56 search queries in 15 languages (English, Spanish, Hindi, Tamil, Japanese, Korean, Arabic, Russian, Portuguese, German, French, Chinese, Turkish, Indonesian and Vietnamese) all returned results, 40 per query for most. All 50 real videos in the lookup returned full details. The Shorts, channel, playlist, movie, upload date, duration, sort and feature filters were each checked in separate runs.

In the rank tracker test, 56 queries in 3 countries (US, IN and DE) ran twice, 5 minutes apart. All 168 query and country pairs returned results both times. A script checked every previousRank, rankChange, isNew and dropped row of the second run against the first run's ranks, and found no mismatch. Every result from the 4 target channels and the target video was flagged, and no other result was.

In the channel discovery test, 60 channel searches in English with a 1,000 to 100,000 subscriber range all returned channels in range, 2,096 in all, while 3,022 channels outside it were left out for free. 20 of the kept channels were checked against their channel pages, and all 20 counts matched. Runs in Japanese, Hindi, Spanish and German returned channels in range for all 20 of their searches. The count reader was also checked on the same searches in 83 interface languages, and all 2,067 counts it could compare matched the English count. In a rank tracker test with the range on, the same 60 searches ran twice, and a script found no mismatch in the second run's previousRank, rankChange, isNew and 253 dropped rows.

Use it from AI agents

The scraper works as a tool through the Apify MCP server in Claude, Cursor, VS Code and other MCP clients. An agent can search YouTube for a topic and get back ranked rows it can filter, summarise or pass to a transcript tool.

You can also call it through the Apify API or the Python and JavaScript clients, and schedule it or connect it to Make, Zapier and n8n.

Pricing

Prices are per 1,000 results.

EventNo discountBronzeSilverGold
Result returned (a search row or a looked-up video)$0.24$0.22$0.20$0.18
Query with no results, unavailable video, invalid input, failed request, dropped row or channel outside the subscriber rangeFreeFreeFreeFree

Bronze, Silver and Gold are Apify Store discount tiers, and Apify's Pricing tab shows them as Starter, Scale and Business. Apify decides which tier an account is on. Set a maximum cost per run in the run options. The scraper stops once that limit is reached.

More from heyitsgautham

Other actors from the same account.

FAQ

Why did a query return fewer results than I asked for? YouTube decides how deep a search goes. With result type All, YouTube often runs out of regular results after 30 to 60 and fills the rest of the feed with Shorts shelves. Set type to video for longer lists, or turn on includeShortsShelves to get those Shorts as rows. A narrow filter such as uploadDate: today on a niche query can return only a handful of results, because that is all YouTube shows.

Why did a subscriber range return fewer channels than I asked for? YouTube's channel results for a topic mix sizes, and big channels tend to come first. The scraper keeps reading while at least about a third of the channels read are in your range, so a narrow range such as 1,000 to 10,000, or a high floor such as 1,000,000, can end with fewer channels. Try a wider range, or several related queries.

Can I sort by upload date? YouTube removed that sort option from search in 2025. Use the uploadDate filter instead.

Why do Shorts rows have no publishedTimeText? YouTube shows Shorts in shelves without a channel or date. The scraper fills channel, exact views, duration and publishDate with one extra small request per Short, so you get the exact date instead of text like "2 days ago".

Why do ranks move between two runs a few minutes apart? YouTube does not show every logged-out visitor the same order, and each run reaches YouTube from different residential IPs in the country. In the rank tracker test, the second run, 5 minutes after the first, had 1,673 top-10 results. 759 of them were at most one place from their last rank, 406 sat at the same rank, and 260 were new. Read single moves of one or two places as noise, and look at trends over several runs.

Does it use the official YouTube Data API? No. It reads the same public data the YouTube website shows to a logged-out visitor, so you need no API key and have no daily quota.

Are view counts exact? Yes for videos. Live streams have viewCount: null and the number of people watching in watchingCount.

Limitations

  • Results depend on the country and language you pick, and on YouTube's own ranking, which changes over time.
  • Mixes (auto-generated playlists) have no single channel, so their channel fields are empty.
  • Like counts are missing when the uploader hides them.
  • Subscriber counts are the rounded figures YouTube shows, such as 90.6K. YouTube does not show exact counts to visitors.
  • YouTube can change its site at any time. If something breaks, open an issue on the Issues tab.