apihq/youtube-search-scraper · YouTube

YouTube Search Scraper

Search YouTube by keyword and export one JSON row per result — video, channel, or playlist. No YouTube Data API key or quota.

$0.0002/result · failed items $0.0000 — on your existing Apify account, a one-item first run costs under a cent.

What does YouTube Search Scraper do?

Search YouTube and export results to JSON by keyword. No YouTube Data API key or quota. One record per result (video, channel, or playlist) with title, views, and channel. Filter by type, date, and duration. Queries that return nothing are free. $0.20 per 1,000 results.

Best for

Turning a keyword into a dataset: competitor and market research, trend discovery, tracking who ranks for a term, and collecting video IDs to feed transcript or comment jobs.

Use something else when

YouTube sets the search depth, not you. Results stop when relevance runs out — usually in the low hundreds per query. maxResults is a ceiling, not a guarantee.

Price
$0.20 per 1,000 results · failed items $0

Example run

input
{
  "queries": ["lofi hip hop", "synthwave"],
  "type": "video",
  "sortBy": "views",
  "uploadDate": "month",
  "maxResults": 5
}

outcome

  • Up to 5 success: true video rows per query — the most-viewed long-form lofi and synthwave videos of the month — billed
  • Each row carries the video, its channel, views, and thumbnail
  • Run status: SUCCEEDED
  • Charged: up to 10 results = $0.002

Good input returns billed rows. Bad input returns free error rows in the same dataset, and the run still succeeds.


Why pipelines pick it

No YouTube Data API key or quota

The actor reads YouTube's public search directly. No key to provision, no daily quota to ration, and it returns as many results as YouTube serves for the query.

You pay only for results

Billing fires on an explicit per-result event, not on dataset writes. A query that returns nothing sits in your dataset for free, and there is no per-run start fee.

A bad filter never breaks the batch

An unusable filter value or a query that finds nothing returns a success: false record with a stable code (NO_RESULTS, VALIDATION_FAILED, SEARCH_TIMEOUT, DEADLINE_EXCEEDED). Branch on the code, not on English.

One search feeds the other actors

Search collects video IDs and channels for a keyword; the transcript, comments, and channel actors go deep on each hit.

Best for: Turning a keyword into a dataset: competitor and market research, trend discovery, tracking who ranks for a term, and collecting video IDs to feed transcript or comment jobs.


Input & output

input example
{
  "queries": ["lofi hip hop", "synthwave", "jazz for studying"],
  "type": "video",
  "maxResults": 200,
  "sortBy": "views",
  "uploadDate": "month"
}
output — success (billed)
{
  "success": true,
  "result_type": "video",
  "search_query": "lofi hip hop",
  "video_id": "n61ULEU7CO0",
  "title": "Best of lofi hip hop 2021",
  "url": "https://www.youtube.com/watch?v=n61ULEU7CO0",
  "view_count": "55,765,840 views",
  "duration": 22258,
  "channel_name": "Lofi Girl",
  "channel_id": "UCSJ4gkVC6NrvII8umztf0Ow"
}
output — failure (free, same dataset)
{
  "success": false,
  "search_query": "asdkjfhqwiuerypoxzcv",
  "code": "NO_RESULTS",
  "error": "Search returned no results for query: asdkjfhqwiuerypoxzcv",
  "request_id": "req_911f37d2e55644ff",
  "status_code": 404
}

Branch on the success field to split hits from misses. Quote the request_id in any support issue and we can trace the exact request.

output fields

fieldtypewhat it is
successbooleantrue for a result (billed), false for a query that returned nothing (not billed).
result_typestringvideo, channel, playlist, or shorts.
search_querystringThe search term that produced this row; every row stands alone.
titlestringVideo or playlist title, or the channel name.
urlstringCanonical URL of the result (watch, shorts, channel, or playlist).
video_idstringThe 11-character video ID (video and shorts rows).
view_countstringView count as a display string. May be empty.
durationintegerVideo length in whole seconds. Absent for live streams.
channel_namestringUploader or owner name (video and playlist rows).
channel_idstringThe UC… channel ID, where available.
subscriber_textstringSubscriber count as a display string (channel rows).
playlist_idstringThe playlist ID (playlist rows).

Error codes, stable across releases

Every failure record carries one of these machine-readable codes. None of them are ever charged.

codebilledmeaning
NO_RESULTS$0.0000The query returned no results. The row is retained, unbilled.
VALIDATION_FAILED$0.0000The input was not a usable query or filter value.
SEARCH_TIMEOUT$0.0000The search request itself timed out.
DEADLINE_EXCEEDED$0.0000The 30-second per-page deadline was hit. Returned as an unbilled row with status_code 504.

Every error code across the eight APIs, in one reference →


What a run costs

per result$0.0002
per 1,000 results$0.20
per failed item$0.0000
per-run start fee$0.0000

The charge fires only when a result is delivered, and platform compute is included in the per-result price. To cap the spend of a run, set a limit in Apify's Run Limits panel. The actor stops at the cap and reports how far it got.

How pay-per-result billing works →


What this actor doesn't do

  • YouTube sets the search depth, not you. Results stop when relevance runs out — usually in the low hundreds per query. maxResults is a ceiling, not a guarantee.
  • type: video is the default and returns only videos. Set channel, playlist, or all for the rest; Shorts appear under all.
  • One row per result, with what search exposes: title, channel, views, thumbnail. Full descriptions, like counts, and tags require opening each video and are out of scope.
  • Public results only — the search returns what a signed-out visitor sees.

Frequently asked questions

Do I need a YouTube Data API key?
No. The actor reads YouTube's public search directly and does not consume Google API quota.
How many results can I get per query?
As many as YouTube serves for that term, capped by maxResults. YouTube stops paging when relevance runs out — for most queries that is in the low hundreds. There is no fixed 500-result ceiling like the official Data API, but depth is finite and set by YouTube.
Can I search for channels or playlists, not just videos?
Yes. Set type to channel or playlist. all returns a mix of videos, channels, playlists, and Shorts. The default, video, returns only videos.
Why did I get fewer results than maxResults?
YouTube ran out of results for that query first. maxResults is a ceiling, not a guarantee, and the video filter is shallower than an unfiltered all search.
How does billing know a query returned nothing?
Billing fires on an explicit per-result charge event, not on dataset writes. success: false records sit in your dataset for free, with a code and a request_id for support.
Can I also get transcripts, comments, or a channel's uploads?
Yes — search collects the video IDs, and the sibling actors go deep: YouTube Transcript Scraper for captions, YouTube Comments Scraper for comments, YouTube Channel Scraper for a channel's videos.

Automation templates


Pairs with

Run it on the Apify account you already have

Paste one input into the actor's console and check the dataset it returns. A one-item first run costs under a cent — no new subscription, pay only for delivered results.

Search one keyword