YouTube Search Scraper - Keyword to Videos & Shorts
Pricing
from $0.80 / 1,000 videos
YouTube Search Scraper - Keyword to Videos & Shorts
Search YouTube by keyword and get videos and Shorts as rows: title, channel, URL, views, publish date, duration, search term. Sort by relevance or views, or filter by upload date. No login. $1 per 1,000 results; no results and blocked searches are free.
What does YouTube Search Scraper do?
Type keywords, get YouTube's results as rows: title, channel, URL, views, publish date, duration and the search term, for $1 per 1,000 results, with no start fee. Keywords with no results, searches YouTube refuses and duplicates are free.
- 🔎 Several keywords in one run, in any language, each with its own cap (up to 500 results per keyword).
- 🎬 Videos and Shorts in YouTube's order, with
isShorton every row. Choose Videos only or Shorts only. - ↕️ Sort by relevance or view count, or filter by upload date: last hour, today, this week, this month or this year.
- 🗓️ Date filter and monitoring: only videos after a date, or only results your earlier scheduled runs have not returned.
- 💸 $1 per 1,000 results. No login, no cookies, no browser, no proxy needed.
Use cases
- Content and SEO research: which titles and channels rank for your keywords, and how many views they have.
- Trend and competitor watch: schedule a run with Upload date "This week" and monitoring on, and get only the new videos for a topic.
- Creator discovery: find the channels that publish on a topic, then read them with YouTube Channel Scraper.
- Data for AI agents and dashboards: one clean JSON row per video, ready for Sheets, BigQuery or an LLM.
How much does it cost?
It uses the same events and prices as YouTube Channel Scraper:
| Event | Price | When |
|---|---|---|
| Video | $1.00 / 1,000 results ($0.001 each) | one result video or Short from the results page |
| Video with full details | $2.00 / 1,000 results ($0.002 each) | charged instead of "Video" when "Full video details" is on and the video's page was read |
Free: keywords with no results, searches YouTube refuses, a video already returned for another keyword in the same run, videos older than your date filter or upload date, results returned by an earlier run in monitoring mode, and invalid inputs. No start fee. Larger Apify plans get the usual volume discount (Silver 10%, Gold and above 20%).
Example: 5 keywords with 100 results each: 500 x $0.001 = $0.50.
You stay in control: maxResultsPerKeyword caps each keyword and maxResults the run. Before reading, the run logs its worst-case plan; when the next row could pass your maximum charge per run, it stops with SUMMARY.status LIMIT_REACHED.
How to use it
- Search keywords: one search per line, as you would type it in YouTube's search box.
- Results per keyword: 20 by default, up to 500.
- Optional: Sort by, Upload date, Results to return, Full video details, Only videos published after, monitoring.
- Click Start. The Search results view shows the key columns, All fields everything (CSV, Excel, JSON).
Input example
{"keywords": ["n8n tutorial", "教學 n8n"],"maxResultsPerKeyword": 20,"searchSort": "relevance","searchUploadDate": "any","searchType": "all"}
Output example
One row, shortened. The values show the shape of a row and are not from a live run:
{"type": "video","detailLevel": "list","searchQuery": "n8n tutorial","position": 1,"videoId": "a0000000001","url": "https://www.youtube.com/watch?v=a0000000001","title": "Example video title","channel": "Example Channel","publishedAt": "2026-10-11T08:00:00.000Z","publishedText": "3 weeks ago","duration": "10:47","durationSeconds": 647,"viewCount": 1234,"viewCountText": "1,234 views","isShort": false,"contentType": "video","channelId": "UC0000000000000000000000","channelHandle": "@example","thumbnailUrl": "https://i.ytimg.com/vi/a0000000001/hqdefault.jpg","source": "search","input": "n8n tutorial","success": true,"charged": true}
A keyword without results:
{ "type": "search", "input": "zzz nothing", "searchQuery": "zzz nothing", "success": false, "charged": false, "errorType": "no_results", "error": "YouTube has no results for \"zzz nothing\" (not charged)" }
What the fields mean
- searchQuery: the keyword that found this row. A video found by two keywords is returned once, under the first.
- position: the result's rank for that keyword, counting videos and Shorts. Parallel reading can change the order of rows in the Dataset, so sort by this field.
- channel: the channel's name (the same value as
channelName). - publishedAt: an estimate from the age YouTube shows ("3 weeks ago") on
detailLevel: "list"rows, the same value aspublishedAtApprox. It is exact on Shorts and other results whose page was read, and with full details on. - duration:
10:47or1:02:03;durationSecondsis the same in seconds. - isShort:
truefor a YouTube Short (contentType: "short").contentTypecan also bevideoorlive. - viewCount: from the results page;
viewCountIsApproximateistruewhen it comes from a rounded label like "5.1K views". - errorType on free rows:
no_results,blocked(YouTube refused the page, or a further result page),invalid_input,parse_error,http_error,network, andcharge_limitormax_resultsfor a keyword the run did not reach because it stopped at your maximum charge ormaxResults. - SUMMARY (key-value store):
search.perKeywordgives rows, Shorts and result pages read per keyword.
Next step: the spoken words
Send the url values to YouTube Transcript Scraper by TidyTools (tidytools/youtube-transcript) to get captions with timestamps for the videos you found. Full channel statistics come from YouTube Channel Scraper (tidytools/youtube-channel-scraper), comments from YouTube Comments Scraper (tidytools/youtube-comments).
Use it from code
curl -X POST "https://api.apify.com/v2/acts/tidytools~youtube-search-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"keywords":["n8n tutorial"],"maxResultsPerKeyword":20}'
Limitations
- No "newest first" order. YouTube ignores that sort (tested 1 November 2026), so we do not offer it: use Upload date for recent videos. YouTube does not combine an upload date with the view-count sort either: the upload date is used and
SUMMARY.inputNotessays so; sort the rows byviewCountyourself. - Not guaranteed to return every result. YouTube decides how many results a search has and may end the list early, so a keyword can return fewer rows than your cap (this is not an error).
- Further result pages need Apify's network or your proxy. If YouTube refuses them, you keep and pay for the rows so far and get one free
blockedrow for that keyword. WithhttpVia: "backend"only the first result page of each keyword is read (about 20 results). - Three refused searches in a row pause the run's other keywords: they get free
blockedrows, so try them again later, or add a proxy. - Dates and views on list rows are what YouTube shows. Turn on full details for exact values. A Short whose page cannot be read keeps its row at the list price, with an empty channel, date or duration.
- Members-only, private and age-restricted videos are not read (no login).
Responsible use
The Actor reads only public pages, with an honest user agent (TidyToolsYouTube). It does not log in, use cookies, solve CAPTCHAs or bypass bot checks: a page YouTube refuses is reported, not forced. Note that youtube.com/robots.txt disallows search pages for crawlers: this Actor reads them anyway, so decide whether that fits your own policy. Follow YouTube's Terms of Service and the laws that apply to you.
FAQ
Why did I get fewer rows than my cap? YouTube's results for that keyword ended, some results were duplicates of an earlier keyword, older than your date filter or returned by an earlier monitoring run. SUMMARY.search.perKeyword shows the count per keyword; only delivered rows are charged.
Can I search and read channels in one run? This form is for keywords. urls from YouTube Channel Scraper is also accepted through the API.
What happens with a mistake in the input? A value that is not text, a search link without search words or more than 200 characters gives a free invalid_input row and the run ends normally. An unknown sort or type value falls back to the default and is listed in SUMMARY.inputNotes.
Does the Actor collect usage data? The Actor sends one anonymous usage counter per run (input type, item count range, outcome) to improve the tool; no URLs, content or account data.
Support
Open an issue in the Issues tab with your input and the run link. Issues are checked regularly.