# YouTube Search Scraper: Videos, Shorts & Channels (`luzivanlt/youtube-search-scraper`) Actor

YouTube search results in YouTube's own order: videos, Shorts, channels, playlists, movies. $0.50 per 1,000 results. Each typed, with YouTube's search filters.

- **URL**: https://apify.com/luzivanlt/youtube-search-scraper.md
- **Developed by:** [Luzi](https://apify.com/luzivanlt) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Search Scraper: Videos, Shorts & Channels

Get YouTube search results for any words, in the order YouTube shows them:
videos, Shorts, channels, playlists and movies in one list, each marked with
its type and its place. Set the same filters as on YouTube's search page.
No YouTube account, login or cookies needed.

Tested daily. Latest checks: three searches read to their end, 815 results
in under 4 minutes; 180 results filtered to 4K videos from this month, by
popularity, in German; and 40 of 40 for each type: Shorts, movies, channels
and playlists.

### What does this Actor do?

You give it searches (the words you would type in YouTube's search box) or
links to YouTube search results. For each search it reads the results page
after page, as you would by scrolling, and saves one row per result until it
reaches your limit or the end of the results.

Each row comes with:

- its type (`video`, `short`, `channel`, `playlist` or `movie`) and its place
  in the results (1 = the top result)
- the id, link, title, description snippet and thumbnail, with every size of
  the thumbnail YouTube offers and the moving preview when there is one
- for a video: views (exact, as a number), when it was posted ("3 days ago"),
  duration, badges such as "4K" or "New", whether it is live now (and how many
  are watching) or an upcoming premiere (and when it starts), its chapters,
  and the short summary YouTube shows under some results
- the channel behind it: id, name, `@` handle, link, picture, verified or
  official-artist mark, and the other channels of a collaboration
- for a channel: its subscribers
- for a playlist: its kind (playlist, mix or podcast), its video count and
  the first videos it lists
- for a movie: the facts and credits the results show
- the search it came from, the corrected search when YouTube fixed a typo,
  and YouTube's estimate of how many results the search has

### Why use it?

- **Everything a search shows, in one list.** Videos, Shorts, channels,
  playlists and movies come together in YouTube's order, each typed, so the
  dataset matches what a person sees on the results page.
- **YouTube's filters.** Type, upload date, duration, sort order and the features
  (4K, HD, subtitles, live, Creative Commons, 360°, VR180, 3D, HDR, location,
  purchased), or paste a results link with the filters you already picked.
- **Another language and country.** Search YouTube as it appears in another
  country and language (English works best; see *Good to know*).
- **More per row.** Exact view counts, chapters, YouTube's summary of the
  video, collaborations, and the channel's verified mark, at no extra cost.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Type one or more searches into **Searches** (or paste YouTube search
   results links into **Search links**).
2. Optionally, set **Max results per search** and the filters.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   results or download them.

Run it with no input to see a sample: up to 50 results each for "space
documentary" and "lofi beats", charged as usual.

### Input

| Field                                              | What it does                                                                                                     | Default     |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------- |
| **Searches** (`searchQueries`)                     | Words to search for, one search each                                                                             | —           |
| **Search links** (`startUrls`)                     | YouTube search results links; each keeps its own filters                                                         | —           |
| **Max results per search** (`maxResultsPerSearch`) | Stop each search after this many results (1 to 1,000)                                                            | 100         |
| **Type** (`resultType`)                            | `all`, `video`, `short`, `channel`, `playlist` or `movie`                                                        | `all`       |
| **Upload date** (`uploadDate`)                     | `any`, `today`, `week`, `month` or `year`                                                                        | `any`       |
| **Duration** (`duration`)                          | `any`, `under3`, `3to20` or `over20` (minutes)                                                                   | `any`       |
| **Sort by** (`sortBy`)                             | `relevance` or `popularity`                                                                                      | `relevance` |
| **Features** (`features`)                          | Any of `live`, `4k`, `hd`, `subtitles`, `creative_commons`, `360`, `vr180`, `3d`, `hdr`, `location`, `purchased` | none        |
| **Language** (`language`)                          | The language YouTube answers in ("en", "de", "pt-BR")                                                            | `en`        |
| **Country** (`country`)                            | The country YouTube searches for ("US", "DE", "VN")                                                              | `US`        |

Give at least one search or one link. Example input:

```json
{
  "searchQueries": ["space documentary", "lofi beats"],
  "maxResultsPerSearch": 200,
  "resultType": "video",
  "uploadDate": "month",
  "features": ["4k"]
}
```

### Output

One row per result. An example, with made-up values:

```json
{
  "id": "AbCdEfGhIjK",
  "result_type": "video",
  "position": 1,
  "url": "https://www.youtube.com/watch?v=AbCdEfGhIjK",
  "title": "A video title",
  "description_snippet": "The first words of the description …",
  "view_count": 1677620,
  "view_count_text": "1,677,620 views",
  "concurrent_viewers": null,
  "published_time_text": "3 months ago",
  "is_live": false,
  "scheduled_start_at": null,
  "duration_text": "1:02:15",
  "duration_seconds": 3735,
  "badges": ["4K"],
  "thumbnail_url": "https://i.ytimg.com/vi/AbCdEfGhIjK/hq720.jpg?…",
  "thumbnails": [
    { "url": "https://i.ytimg.com/vi/AbCdEfGhIjK/hq720.jpg?…", "width": 720, "height": 404 }
  ],
  "animated_thumbnail_url": "https://i.ytimg.com/an_webp/AbCdEfGhIjK/mqdefault_6s.webp?…",
  "ai_summary": "A short summary of the video.",
  "chapters": [
    {
      "title": "Intro",
      "time_text": "0:00",
      "start_seconds": 0,
      "thumbnail_url": "https://i.ytimg.com/…"
    }
  ],
  "channel_id": "UC1111111111111111111111",
  "channel_name": "A Channel",
  "channel_handle": "@achannel",
  "channel_url": "https://www.youtube.com/channel/UC1111111111111111111111",
  "channel_avatar_url": "https://yt3.ggpht.com/…",
  "channel_verified": true,
  "channel_is_artist": false,
  "collaborators": [],
  "subscriber_count": null,
  "subscribers_text": null,
  "video_count": null,
  "video_count_text": null,
  "playlist_kind": null,
  "playlist_updated_text": null,
  "playlist_videos": [],
  "movie_info": null,
  "movie_credits": [],
  "shelf_title": null,
  "search_query": "space documentary",
  "search_corrected_query": null,
  "search_url": "https://www.youtube.com/results?search_query=space+documentary&hl=en&gl=US",
  "search_total_estimate": 69222317
}
```

| Field                    | What it holds                                                                                    |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| `id`                     | The video, channel or playlist id                                                                |
| `result_type`            | `video`, `short`, `channel`, `playlist` or `movie`                                               |
| `position`               | Its place in the search's results, 1 = the top result                                            |
| `url`                    | A link to it (a `/shorts/` link for a Short)                                                     |
| `title`                  | The title, or the channel's name                                                                 |
| `description_snippet`    | The description's first words, as the results show them                                          |
| `view_count`             | Views as a number (exact for videos; rounded as YouTube rounds it for Shorts)                    |
| `view_count_text`        | Views as YouTube shows them                                                                      |
| `concurrent_viewers`     | For a video live now: people watching                                                            |
| `published_time_text`    | When it was posted, as YouTube shows it ("3 months ago")                                         |
| `is_live`                | Whether it is live now                                                                           |
| `scheduled_start_at`     | For an upcoming premiere or stream: when it starts (ISO date and time)                           |
| `duration_text`          | The duration as shown ("1:02:15")                                                                |
| `duration_seconds`       | The same in seconds                                                                              |
| `badges`                 | Badges shown on the result, such as "4K", "New" or "CC"                                          |
| `thumbnail_url`          | The largest thumbnail shown                                                                      |
| `thumbnails`             | Every size of the thumbnail shown, each with `url`, `width` and `height`                         |
| `animated_thumbnail_url` | The moving preview, when YouTube has one                                                         |
| `ai_summary`             | The short summary YouTube shows under some results                                               |
| `chapters`               | The video's chapters shown in the results (title, start time, thumbnail)                         |
| `channel_id`             | The channel's id                                                                                 |
| `channel_name`           | The channel's name                                                                               |
| `channel_handle`         | The channel's `@` handle                                                                         |
| `channel_url`            | A link to the channel                                                                            |
| `channel_avatar_url`     | The channel's picture                                                                            |
| `channel_verified`       | Whether the channel has the verified mark                                                        |
| `channel_is_artist`      | Whether it is an official artist channel                                                         |
| `collaborators`          | A collaboration's other channels (name, handle, id, link, subscribers, picture); empty otherwise |
| `subscriber_count`       | For a channel: subscribers as a number (rounded as YouTube rounds it)                            |
| `subscribers_text`       | For a channel: subscribers as shown                                                              |
| `video_count`            | For a playlist: its number of videos                                                             |
| `video_count_text`       | The same as shown                                                                                |
| `playlist_kind`          | For a playlist: `playlist`, `mix` or `podcast`                                                   |
| `playlist_updated_text`  | For a playlist: when it was last updated, as shown                                               |
| `playlist_videos`        | For a playlist: the first videos it lists (id, title, duration)                                  |
| `movie_info`             | For a movie: the line of facts shown (such as its year and genre)                                |
| `movie_credits`          | For a movie: the credit lines shown (actors, director)                                           |
| `shelf_title`            | When the result came in a titled group of results (such as a row of Shorts): that group's title  |
| `search_query`           | The search it came from                                                                          |
| `search_corrected_query` | The search YouTube ran instead, when it corrected a typo                                         |
| `search_url`             | The YouTube results link for the search                                                          |
| `search_total_estimate`  | YouTube's estimate of how many results the search has                                            |

Not included: an exact upload date (results show only "3 months ago"), likes,
comment counts, full descriptions and tags. Shorts shown in a row of Shorts
carry no channel.

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

You pay for what you get:

- **$0.50 per 1,000 results** ($0.0005 a result). Videos, Shorts, channels, playlists and movies cost the same. Each is charged once per run.
- No start fee, and nothing per search.

So 1,000 results cost $0.50. If you set a maximum cost for a run, the Actor stops when it reaches it and keeps every result saved so far.

### How long does a run take?

About 10 seconds for the first 50 results of two searches, and about 3
to 4 minutes for three searches read to their end (815 results).

### Good to know

- **A search ends where YouTube ends it.** YouTube stops showing more
  results after a few hundred for most searches, so a search may end below
  your maximum.
- **A result found by two searches is saved and charged once**, under the
  search that reached it first, so two searches can save fewer rows than
  their two maximums.
- **English gives the fullest rows.** With another language, a video's views
  are still read when YouTube writes them in full ("1.677.620 Aufrufe"), but
  rounded counts ("1,2 Mio."), a channel's subscribers and a playlist's
  update date are left empty.
- **A pasted link keeps its own settings.** Its filters, and its language and
  country when it names them, win over the fields below it.
- **Check your links first.** A link that is not a YouTube search results link
  stops the run before anything is read, and the message names it.
- **One search that cannot be read does not stop the run.** The others carry
  on, and the run's status lists the searches that could not be read.
- **A search with no results is not an error.** It saves nothing.

### More Actors from us

- [YouTube Channel Scraper: Every Video & Short](https://apify.com/luzivanlt/youtube-channel-videos-scraper): Every upload of a YouTube channel, newest first: videos, Shorts and live streams in one list.
- [YouTube Comments Scraper: With Replies](https://apify.com/luzivanlt/youtube-comments-scraper): YouTube video comments with their replies, threaded, plus the video's title, views and likes.
- [YouTube Transcript Scraper: Channels, Playlists & SRT](https://apify.com/luzivanlt/youtube-transcripts-scraper): YouTube transcripts with timestamps from videos, whole channels or playlists, in the languages you pick.
- [AliExpress Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/aliexpress-products-scraper): Every product of an AliExpress search to its last page, with exact sold counts and ratings.
- [Amazon Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/amazon-products-scraper): Every product on Amazon's search pages to the last page, sponsored marked, with monthly sales.
- [App Store Reviews Scraper: All Reviews, Not 500](https://apify.com/luzivanlt/app-store-reviews-scraper): Every written App Store review of an app, not just the newest 500.
- [Woolworths Coles ALDI Scraper: AU Grocery Prices](https://apify.com/luzivanlt/au-supermarkets-scraper): Woolworths, Coles and ALDI products for any search in one run, every results page to the end.
- [Bilibili Video Scraper: Search & Channel Videos](https://apify.com/luzivanlt/bilibili-videos-scraper): Bilibili videos from searches or whole channels, each with its full detail page's data.
- [Career Site Jobs Scraper: Workday, Greenhouse, Lever](https://apify.com/luzivanlt/career-site-jobs-scraper): Every job on Greenhouse, Lever, Ashby, SmartRecruiters and Workday boards, checked against each board's count.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~youtube-search-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "searchQueries": ["space documentary", "lofi beats"],
  "maxResultsPerSearch": 50,
  "resultType": "all",
  "uploadDate": "any",
  "duration": "any",
  "sortBy": "relevance",
  "language": "en",
  "country": "US"
}
```

Its inputs, in the order of the input form:

| Input                                          | What it takes                                                                                                                          | Default       |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `searchQueries` (Searches)                     | Words to search YouTube for, one search per line, as you would type them in YouTube's search box, up to 200 characters each.           | —             |
| `startUrls` (Search links)                     | YouTube search results links (https://www.youtube.com/results?search_query=…), with any filters you picked on YouTube.                 | —             |
| `maxResultsPerSearch` (Max results per search) | Stop each search after this many results, in YouTube's order.                                                                          | `100`         |
| `resultType` (Type)                            | Keep only results of this type.                                                                                                        | `"all"`       |
| `uploadDate` (Upload date)                     | Keep only videos posted in this period: any time, today, this week, this month or this year.                                           | `"any"`       |
| `duration` (Duration)                          | Keep only videos of this length: any, under 3 minutes, 3–20 minutes or over 20 minutes.                                                | `"any"`       |
| `sortBy` (Sort by)                             | The order YouTube lists the results in: relevance or popularity.                                                                       | `"relevance"` |
| `features` (Features)                          | Keep only videos with every feature picked: Live, 4K, HD, Subtitles/CC, Creative Commons, 360°, VR180, 3D, HDR, Location or Purchased. | —             |
| `language` (Language)                          | The language YouTube answers in, as a code such as "en", "de" or "pt-BR".                                                              | `"en"`        |
| `country` (Country)                            | The country YouTube searches for, as a two-letter code such as "US", "DE" or "VN".                                                     | `"US"`        |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/youtube-search-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=luzivanlt/youtube-search-scraper"
    }
  }
}
```

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per result delivered; the sample input above costs at most $0.05.

### FAQ

**Do I need a YouTube account or cookies?**
No. The Actor reads what anyone can see on YouTube's search page.

**Can I get only videos, or only channels?**
Yes. Set **Type**. With `all`, every result is kept and typed, so you can
filter the dataset later.

**Can I run it from my own code, on a schedule, or with other apps?**
Yes. Like any Apify Actor, you can start it through the Apify API, run it on a
schedule, and connect it to other apps with Apify's integrations and webhooks.

### Is it legal to scrape YouTube?

This Actor reads only what anyone can see on YouTube's search page without
logging in. Check YouTube's terms and the laws that apply to you before you
use the data, and only collect personal data when you have a legitimate
reason to. If you are unsure, ask a lawyer.

### Support

Found a problem or missing a feature? Open an issue on the **Issues** tab and
include the run's link.

***

This Actor is not affiliated with, endorsed by or sponsored by YouTube or
Google.

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/youtube-search-scraper/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Words to search YouTube for, one search per line, as you would type them in YouTube's search box, up to 200 characters each. The filters below apply to these searches. A link is refused here: paste it under Search links. Give at least one search or one link. Example: space documentary

## `startUrls` (type: `array`):

YouTube search results links (https://www.youtube.com/results?search_query=…), with any filters you picked on YouTube. A link keeps its own filters; the filters below apply to the searches above. A link's own language and country (hl=, gl=) win over the fields below. Example: https://www.youtube.com/results?search_query=lofi+beats

## `maxResultsPerSearch` (type: `integer`):

Stop each search after this many results, in YouTube's order. A search usually ends on its own after a few hundred results. Default 100, from 1 to 1,000. It caps what you pay: each result saved costs $0.0005 ($0.50 per 1,000), so 100 per search costs at most $0.05. A result found by two searches is charged once.

## `resultType` (type: `string`):

Keep only results of this type. "All" keeps everything YouTube shows, in its order. Choose All, Videos, Shorts, Channels, Playlists (mixes and podcasts included) or Movies; default All. A pasted search link keeps every result it lists. Example: "video" for videos only.

## `uploadDate` (type: `string`):

Keep only videos posted in this period: any time, today, this week, this month or this year. Default any time. Applies to the searches above; a pasted search link keeps its own filters. Example: "month" for videos posted this month.

## `duration` (type: `string`):

Keep only videos of this length: any, under 3 minutes, 3–20 minutes or over 20 minutes. Default any. Applies to the searches above; a pasted search link keeps its own filters. Example: "under3" for videos under 3 minutes.

## `sortBy` (type: `string`):

The order YouTube lists the results in: relevance or popularity. Default relevance. With Max results per search set, it decides which results you get. Applies to the searches above; a pasted search link keeps its own. Example: "popularity" for the most popular first.

## `features` (type: `array`):

Keep only videos with every feature picked: Live, 4K, HD, Subtitles/CC, Creative Commons, 360°, VR180, 3D, HDR, Location or Purchased. None by default. Applies to the searches above; a pasted search link keeps its own filters. Example: \["4k", "subtitles"] for 4K videos with subtitles.

## `language` (type: `string`):

The language YouTube answers in, as a code such as "en", "de" or "pt-BR". English gives the fullest rows: in other languages some counts are left empty. Default en. A pasted search link that names its own language (hl=) keeps it. Example: de for German.

## `country` (type: `string`):

The country YouTube searches for, as a two-letter code such as "US", "DE" or "VN". Default US. A pasted search link that names its own country (gl=) keeps it. Example: DE to search YouTube as it appears in Germany.

## Actor input object example

```json
{
  "searchQueries": [
    "space documentary",
    "lofi beats"
  ],
  "maxResultsPerSearch": 50,
  "resultType": "all",
  "uploadDate": "any",
  "duration": "any",
  "sortBy": "relevance",
  "language": "en",
  "country": "US"
}
```

# Actor output Schema

## `results` (type: `string`):

Every search result the run saved, one row each.

## `allFields` (type: `string`):

The same rows with every field.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "space documentary",
        "lofi beats"
    ],
    "maxResultsPerSearch": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/youtube-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": [
        "space documentary",
        "lofi beats",
    ],
    "maxResultsPerSearch": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/youtube-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "space documentary",
    "lofi beats"
  ],
  "maxResultsPerSearch": 50
}' |
apify call luzivanlt/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luzivanlt/youtube-search-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eOSQqedJbGGnThsfw/builds/hwQ9UjkJrZm9H32rg/openapi.json
