# YouTube Search Scraper API (`shahidirfan/youtube-search-scraper-api`) Actor

Extract YouTube search results at scale with this fast, reliable scraper API. Collect video titles, URLs, channel details, descriptions, views, publish dates, thumbnails, and more from any keyword search. Ideal for SEO research, trends, analytics, and data workflows.

- **URL**: https://apify.com/shahidirfan/youtube-search-scraper-api.md
- **Developed by:** [Shahid Irfan](https://apify.com/shahidirfan) (community)
- **Categories:**
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does YouTube search Scraper API do?

YouTube search Scraper API searches YouTube for a keyword or phrase and returns structured results for videos, Shorts, channels, playlists, movies, or all supported result types. Enter a query such as `web scraping`, choose the result type and filters, set the result limit, and receive one clean dataset item per result.

Use the data for content research, creator discovery, competitor monitoring, keyword analysis, trend tracking, media catalogs, publishing research, and AI or RAG workflows. Each item keeps the search query and result position together with the public title, URL, channel information, engagement text, duration, thumbnails, and other available metadata.

### Why use YouTube search Scraper API?

- **Search-based collection** - Find public YouTube content without preparing channel URLs first.
- **Flexible result types** - Collect videos, Shorts, channels, playlists, movies, or a mixed result set.
- **Useful search filters** - Narrow results by relevance or popularity, upload date, duration, and YouTube features.
- **Creator context** - Keep channel name, handle, ID, URL, and thumbnail with video results when available.
- **Video research fields** - Capture titles, descriptions, publication text, view text, durations, thumbnails, live status, premiere status, and caption availability.
- **Optional enrichment** - Request public numeric views, likes, comments, tags, category, canonical URL, and additional video status fields.
- **Clean datasets** - Empty values and empty arrays are omitted instead of being saved as repeated `null` fields.
- **Duplicate protection** - Repeated results across continuation pages are saved only once.
- **Automation-ready** - Schedule repeat runs, connect webhooks, export datasets, or retrieve results through the Apify API.

### What data can you extract from YouTube search?

| Field                      | Type    | Description                                                        |
| -------------------------- | ------- | ------------------------------------------------------------------ |
| `result_type`              | String  | Result category such as `video`, `channel`, or `playlist`.         |
| `search_query`             | String  | Query used for the search.                                         |
| `result_rank`              | Number  | Position of the result in the collected search response.           |
| `title`                    | String  | Video, playlist, or other result title.                            |
| `url`                      | String  | Direct result URL.                                                 |
| `video_id`                 | String  | YouTube video identifier for video results.                        |
| `playlist_id`              | String  | YouTube playlist identifier for playlist results.                  |
| `channel_id`               | String  | Channel identifier when available.                                 |
| `channel_title`            | String  | Public channel name.                                               |
| `channel_handle`           | String  | Public channel handle when available.                              |
| `channel_url`              | String  | Direct channel URL.                                                |
| `channel_description`      | String  | Channel description or search snippet when available.              |
| `channel_subscriber_count` | String  | Subscriber count text when available.                              |
| `channel_video_count`      | String  | Channel video count text when available.                           |
| `channel_thumbnail_url`    | String  | Channel thumbnail URL.                                             |
| `description`              | String  | Video description snippet or enriched description.                 |
| `published_text`           | String  | Relative or localized publication text.                            |
| `view_count_text`          | String  | Localized view count text.                                         |
| `view_count`               | Number  | Numeric view count when video details are requested and available. |
| `duration_text`            | String  | Localized video duration.                                          |
| `duration_seconds`         | Number  | Video duration in seconds when available.                          |
| `playlist_video_count`     | String  | Playlist video count text when available.                          |
| `thumbnail_url`            | String  | Best available video, channel, or playlist thumbnail.              |
| `like_count`               | Number  | Public like count when video details are requested.                |
| `comment_count`            | Number  | Public comment count when available.                               |
| `tags`                     | Array   | Public video tags when video details are requested.                |
| `category`                 | String  | Video category when video details are requested.                   |
| `canonical_url`            | String  | Canonical video URL when available.                                |
| `is_live`                  | Boolean | Whether the result is marked as live.                              |
| `is_upcoming`              | Boolean | Whether the result is scheduled for the future.                    |
| `is_premiere`              | Boolean | Whether the result is marked as a premiere.                        |
| `has_captions`             | Boolean | Whether captions are available.                                    |
| `video_details_fetched`    | Boolean | Whether video detail enrichment completed.                         |

Fields that are not published for a result are left out of that dataset item.

### How to use YouTube search Scraper API

1. Enter a search phrase in `search_query`.
2. Select the result type, sort order, and optional YouTube filters.
3. Set `results_wanted` and `max_pages`.
4. Enable `fetch_video_details` if you need additional public video metadata.
5. Run the Actor and inspect the dataset preview.
6. Export the data or connect it to your workflow.

### Input Parameters

| Parameter             | Type    | Required | Default        | Description                                                                                   |
| --------------------- | ------- | -------- | -------------- | --------------------------------------------------------------------------------------------- |
| `search_query`        | String  | Yes      | `web scraping` | Words or phrase to search for on YouTube.                                                     |
| `result_type`         | String  | No       | `video`        | `video`, `shorts`, `channel`, `playlist`, `movie`, or `all`.                                  |
| `sort_by`             | String  | No       | `relevance`    | Return results by `relevance` or `popularity`.                                                |
| `upload_date`         | String  | No       | `all`          | Filter by `today`, `week`, `month`, `year`, or `all`.                                         |
| `duration`            | String  | No       | `all`          | Filter videos by `under_three_mins`, `three_to_twenty_mins`, `over_twenty_mins`, or `all`.    |
| `features`            | Array   | No       | `[]`           | Feature filters such as `hd`, `subtitles`, `live`, `4k`, `hdr`, `360`, or `creative_commons`. |
| `results_wanted`      | Integer | No       | `20`           | Maximum number of unique results to save.                                                     |
| `max_pages`           | Integer | No       | `5`            | Maximum number of search result batches to request.                                           |
| `fetch_video_details` | Boolean | No       | `false`        | Add public detail fields to video results.                                                    |

### Usage Examples

#### Search for recent videos

Collect the first 20 video results for a topic:

```json
{
    "search_query": "web scraping",
    "result_type": "video",
    "sort_by": "relevance",
    "results_wanted": 20
}
```

#### Find popular long-form content

Use popularity and a duration filter for competitive content research:

```json
{
    "search_query": "Python automation",
    "result_type": "video",
    "sort_by": "popularity",
    "duration": "over_twenty_mins",
    "results_wanted": 50,
    "max_pages": 5
}
```

#### Search for fresh videos with selected features

Limit the search to recently uploaded HD videos with captions and request enrichment:

```json
{
    "search_query": "AI tools for marketers",
    "result_type": "video",
    "upload_date": "month",
    "features": ["hd", "subtitles"],
    "fetch_video_details": true,
    "results_wanted": 20,
    "max_pages": 3
}
```

#### Collect channels or mixed results

Use `channel` to discover creators or `all` to collect supported result categories together:

```json
{
    "search_query": "web scraping tutorials",
    "result_type": "channel",
    "sort_by": "popularity",
    "results_wanted": 20
}
```

### Sample Output

```json
{
    "result_type": "video",
    "search_query": "web scraping",
    "result_rank": 1,
    "channel_id": "UCeVMnSShP_Iviwkknt83cww",
    "channel_title": "CodeWithHarry",
    "channel_url": "https://www.youtube.com/@CodeWithHarry",
    "channel_handle": "@CodeWithHarry",
    "video_id": "1227R6KY8Ts",
    "title": "Ultimate Web Scraping tutorial",
    "url": "https://www.youtube.com/watch?v=1227R6KY8Ts",
    "description": "A practical introduction to web scraping and browser automation.",
    "published_text": "1 year ago",
    "view_count_text": "250,951 views",
    "duration_text": "41:31",
    "duration_seconds": 2491,
    "thumbnail_url": "https://i.ytimg.com/vi/1227R6KY8Ts/maxresdefault.jpg",
    "is_live": false,
    "is_upcoming": false,
    "is_premiere": false,
    "has_captions": false
}
```

### Tips for Best Results

- Start with `result_type: "video"` when you want a predictable video catalog.
- Use `upload_date` with a specific time range for current trend and news research.
- Use `popularity` for high-engagement discovery and `relevance` for closer keyword matching.
- Combine `features` filters carefully because each additional filter can reduce the number of matching results.
- Start with `results_wanted: 20` and `max_pages: 3` while testing a new query.
- Enable `fetch_video_details` only when numeric engagement or extended metadata is needed.
- Use `video_id`, `channel_id`, and `playlist_id` as stable identifiers when comparing scheduled runs.
- YouTube may omit fields for individual results. The Actor leaves those fields out rather than inserting empty values.

### Integrations and Export Formats

- **Google Sheets** - Review titles, channels, publication timing, and engagement metrics.
- **Airtable** - Build searchable video, creator, or playlist catalogs.
- **Webhooks** - Notify downstream systems when a search run finishes.
- **Make or Zapier** - Send new results to alerts, reports, enrichment, or content workflows.
- **Apify API** - Start runs and retrieve dataset items programmatically.
- **Export formats** - Download JSON, CSV, Excel, XML, and other formats supported by Apify.

### Frequently Asked Questions

#### What can I search for?

You can search for any public YouTube keyword, phrase, topic, creator name, or content idea that YouTube accepts.

#### Can I search for channels and playlists?

Yes. Set `result_type` to `channel`, `playlist`, or `all`. The dataset uses the result-specific ID and fields when they are available.

#### What is the difference between `video` and `shorts`?

`video` searches regular video results, while `shorts` asks YouTube to limit the search to Shorts. Shorts may still use the standard video fields because they are video records.

#### Does detail enrichment collect full comments?

No. Detail enrichment collects public video metadata and counts when available. It does not download full comment threads or private information.

#### Why are some fields missing?

YouTube does not publish every field for every result, and some information is available only for video detail requests. Unavailable values are omitted to keep each item compact.

#### Can I collect more than 20 results?

Yes. Increase `results_wanted` and raise `max_pages` when the query has more matching results. The actual count depends on the results available for the selected filters.

#### Can I run this Actor on a schedule?

Yes. Create an Apify schedule to repeat a keyword search hourly, daily, weekly, or at a custom interval.

#### Is collecting YouTube data legal?

You are responsible for complying with YouTube's terms, applicable laws, copyright rules, and privacy requirements. Collect public information responsibly and only for legitimate purposes.

### Related Actors

- [Reddit Community Scraper](https://apify.com/shahidirfan/reddit-community-scraper) - Collect public community posts and comments for audience, topic, and trend research.
- [Apify Store Scraper](https://apify.com/shahidirfan/apify-store-scraper) - Build structured marketplace datasets for tool discovery and competitive research.

### Support

For issues, feature requests, or questions about the output, use the Issues tab on the Actor page or contact the developer through Apify.

### Legal Notice

This Actor is intended for legitimate collection of publicly available YouTube information. Users are responsible for complying with YouTube's terms of service, applicable laws, copyright obligations, and privacy rules.

# Actor input Schema

## `search_query` (type: `string`):

Words or phrase to search for on YouTube.

## `result_type` (type: `string`):

Limit results to videos, Shorts, channels, playlists, movies, or all result types.

## `sort_by` (type: `string`):

Order results by relevance or popularity.

## `upload_date` (type: `string`):

Limit results by when they were uploaded.

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

Limit video results by duration.

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

Optional YouTube feature filters. Multiple features can be selected.

## `results_wanted` (type: `integer`):

Maximum number of unique search results to save.

## `max_pages` (type: `integer`):

Maximum number of result batches requested from YouTube.

## `fetch_video_details` (type: `boolean`):

Fetch additional public details for video results, including numeric views, likes, comments, tags, category, and full description when available.

## Actor input object example

```json
{
  "search_query": "web scraping",
  "result_type": "video",
  "sort_by": "relevance",
  "upload_date": "all",
  "duration": "all",
  "features": [],
  "results_wanted": 20,
  "max_pages": 3,
  "fetch_video_details": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "search_query": "web scraping",
    "result_type": "video",
    "sort_by": "relevance",
    "upload_date": "all",
    "duration": "all",
    "features": [],
    "results_wanted": 20,
    "max_pages": 3,
    "fetch_video_details": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("shahidirfan/youtube-search-scraper-api").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 = {
    "search_query": "web scraping",
    "result_type": "video",
    "sort_by": "relevance",
    "upload_date": "all",
    "duration": "all",
    "features": [],
    "results_wanted": 20,
    "max_pages": 3,
    "fetch_video_details": False,
}

# Run the Actor and wait for it to finish
run = client.actor("shahidirfan/youtube-search-scraper-api").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 '{
  "search_query": "web scraping",
  "result_type": "video",
  "sort_by": "relevance",
  "upload_date": "all",
  "duration": "all",
  "features": [],
  "results_wanted": 20,
  "max_pages": 3,
  "fetch_video_details": false
}' |
apify call shahidirfan/youtube-search-scraper-api --silent --output-dataset

```

## MCP server setup

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

```

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/veBUiXvicuM8VScPL/builds/o4WTffcW1Fkxa1Uuy/openapi.json
