# YouTube Search Scraper (`cirkit/youtube-search-scraper`) Actor

Fast YouTube search scraper. Pass any query (or list) and extract every matching video with full metadata. Filters: upload date, duration, sort, type, features (HD/4K/CC/Live). Optional channel scoping. Direct InnerTube API, no browser. PPE pricing.

- **URL**: https://apify.com/cirkit/youtube-search-scraper.md
- **Developed by:** [Crikit](https://apify.com/cirkit) (community)
- **Categories:** Social media
- **Features:** Limited permissions
- **Stats:** 28 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

**Scrape YouTube search results** for any query or list of queries. This **YouTube search scraper** returns every matching video with title, description, channel name and handle, view count, duration, publish date, thumbnails, and badges — with filters for upload date, duration, result type, and features like HD, 4K, subtitles, and live.

No YouTube API key, no login, and no headless browser. Results land in a structured dataset you can export to JSON, CSV, Excel, or XML, or pull straight from the Apify API.

### What is YouTube Search Scraper?

YouTube Search Scraper is an [Apify Actor](https://apify.com/actors) that extracts search results with full video metadata from [YouTube](https://www.youtube.com) and returns them as clean, structured records. It calls YouTube's InnerTube API directly, the same interface the site itself uses, so there is no browser to run, no API quota to exhaust, and no Google Cloud project to configure.

### What data can this YouTube search scraper extract?

Every run writes one row per video. The full schema carries **33 fields**; the most-used ones are below.

| Field | Type | Description |
| --- | --- | --- |
| `type` | string | video, channel, playlist, or warning (emitted when a query legitimately returned zero results). |
| `query` | string | Free-text query that produced this row. |
| `resultRank` | integer | 1-based rank within the search results for this query (post-filter). |
| `videoId` | string | 11-character YouTube video ID. Present for type=video. |
| `url` | string | Canonical https://www.youtube.com/watch?v=... URL. |
| `title` | string | Title of the video, channel, or playlist. |
| `titleAccessibility` | string | Accessibility label, often combining title and duration. |
| `description` | string | Short description preview as shown on the search results page (about 150 characters). Full description requires a... |
| `channelTitle` | string | Display name of the uploader's channel. |
| `channelId` | string | Canonical UC... channel ID of the uploader (or the channel itself for type=channel). |
| `channelHandle` | string | Canonical @handle of the uploader's channel. |
| `channelUrl` | string | Full URL of the uploader's channel. |
| `channelIsVerified` | boolean | True if the uploader's channel carries a verified badge. |
| `collaboratorChannelIds` | array | For collab videos with two or more uploaders, the full list of collaborator UC... channel IDs. channelId points at... |
| `channelBadges` | array | All channel-level badges (Verified, Artist, etc.) as plain strings. |
| `channelAvatar` | array | Channel avatar image at multiple sizes. |
| `viewCount` | integer | Exact integer view count. May be null for live streams and premieres. |
| `viewCountText` | string | Raw exact view count text as rendered, for example "6,806,504 views". |
| `shortViewCountText` | string | Abbreviated view count, for example "6.8M views". |
| `publishedTimeText` | string | Relative timestamp as YouTube renders it, for example "2 years ago". |
| `publishedDateApprox` | string | Best-effort absolute date computed from the relative timestamp and the run time. Day-level precision at best. |
| `lengthText` | string | Duration as shown, for example "13:51". Absent for live streams. |

See the **Output** tab in Apify Console for all 33 fields.

### How to scrape YouTube search results

1. Open [YouTube Search Scraper](https://apify.com/cirkit/youtube-search-scraper) and click **Try for free**.
2. Add one or more queries to `searchQueries`.
3. Filter with `uploadDate`, `duration`, `type`, and `features`.
4. Set `sortBy` to control ranking, and `channelId` to scope results to one channel.
5. Set `maxResultsPerQuery` to bound the run.
6. Click **Start** and watch rows appear live in the **Output** tab.
7. Export the dataset as JSON, CSV, Excel, or XML — or fetch it from the [Apify API](https://docs.apify.com/api/v2) once the run finishes.

### YouTube Search Scraper input options

| Input | Type | What it does | Default |
| --- | --- | --- | --- |
| `searchQueries` | array | One or more free-text search queries. YouTube search operators work in the query itself, for example "iphone 15"... | **yes** |
| `maxResultsPerQuery` | integer | Hard cap on results returned per query. YouTube itself tops out around 600 to 1000 results per query, so values... | `100` |
| `sortBy` | string | Result order. "relevance" is YouTube's default ranking. "date" returns newest first, "views" returns most viewed... | `"relevance"` |
| `uploadDate` | string | Restrict to videos uploaded within this window. Ignored unless type is "video" or "any". | `"any"` |
| `duration` | string | short = under 4 minutes, medium = 4 to 20 minutes, long = over 20 minutes. Ignored unless type is "video" or "any". | `"any"` |
| `type` | string | Restrict results to a single type. "any" lets YouTube return a mix of videos, channels, and playlists. Note:... | `"any"` |
| `features` | array | Restrict to videos with one or more of these flags. Selecting any flag forces type to "video". |  |
| `channelId` | string | Restrict results to a single channel's uploads. Accepts a channel ID (UC...), a /channel/UC... URL, a /@handle URL,... |  |

Proxy is configured through the standard `proxyConfiguration` object; the defaults shipped with this Actor are already tuned for the target site.

### Example output

```json
{
  "type": "...",
  "query": "...",
  "resultRank": 42,
  "videoId": "a1b2c3d4",
  "url": "https://example.com/item/12345",
  "title": "Example title",
  "titleAccessibility": "Example title",
  "description": "Example text ...",
  "channelTitle": "Example title",
  "channelId": "a1b2c3d4",
  "channelHandle": "...",
  "channelUrl": "https://example.com/item/12345",
  "channelIsVerified": true,
  "collaboratorChannelIds": [
    "..."
  ],
  "channelBadges": [
    "..."
  ],
  "channelAvatar": [
    "..."
  ],
  "viewCount": 1483,
  "viewCountText": "Example text ..."
}
```

### How much does it cost to scrape YouTube?

This Actor bills through Apify platform usage (compute units and proxy traffic) rather than a per-result fee. Runs are HTTP-based and lightweight, which keeps compute low. Every Apify account includes free monthly usage credit to trial it.

### What can you build with YouTube data?

#### Research what ranks for a keyword

Result rank alongside view count and publish date shows what YouTube's algorithm currently rewards for a term — the foundation of any video SEO strategy.

#### Track competitor video performance

Run the queries your audience searches and watch which channels own those results over time.

#### Find creators for influencer outreach

Channel handles, subscriber counts, and verification badges let you build a shortlist filtered by real reach.

#### Monitor brand mentions on YouTube

Schedule searches for your brand and get alerted to new videos as they are published.

#### Build video datasets for research or ML

Titles, descriptions, durations, and view counts across thousands of videos form a clean corpus, with no API quota ceiling to work around.

### YouTube scraping tips and limits

- The official YouTube Data API charges quota units per call and cuts you off daily. This Actor has no such quota, which is the main reason to use it for volume work.
- `uploadDate` is the cheapest filter for recurring runs — restrict to the last day and you only pay for new videos.
- View counts on recently published videos move fast. Timestamp your rows if you are building a time series.
- `channelId` scoping turns a keyword search into a within-channel search, which is useful for auditing a competitor's coverage of a topic.

### Integrations and automation

Run YouTube Search Scraper on a [schedule](https://docs.apify.com/platform/schedules) to keep a YouTube dataset fresh, or trigger it from your own stack through the [Apify API](https://docs.apify.com/api/v2) and the official [JavaScript](https://docs.apify.com/sdk/js) and [Python](https://docs.apify.com/sdk/python) clients. Native [integrations](https://docs.apify.com/platform/integrations) push results into Google Sheets, Slack, Airtable, Zapier, Make, GitHub, or any webhook endpoint. The Actor also works as an [MCP](https://docs.apify.com/platform/integrations/mcp) tool, so an AI agent can call it directly.

### Related scrapers

| Actor | What it does |
| --- | --- |
| [YouTube Channel Scraper](https://apify.com/cirkit/youtube-channel-scraper) | Channel profile plus the complete video list. |
| [YouTube Comments Scraper](https://apify.com/cirkit/youtube-comments-scraper) | Every comment and reply thread on any video. |
| [Google Trends Scraper](https://apify.com/cirkit/google-trends-scraper) | Search demand behind the topics you are targeting. |
| [Twitch Search & Streams Scraper](https://apify.com/cirkit/twitch-search-scraper) | The same audience research on Twitch. |

### Frequently asked questions

#### Do I need a YouTube API key?

No. This Actor uses YouTube's internal InnerTube interface, so there is no API key, no Google Cloud project, and no daily quota to manage.

#### How many results can I get per query?

Set `maxResultsPerQuery` to whatever you need. YouTube's own search pagination eventually stops returning new results, so very deep pulls are better split across several related queries.

#### Do I need a YouTube API key?

No. YouTube Search Scraper reads publicly available YouTube pages and endpoints directly, so there is no key to obtain, no OAuth app to register, and no account to connect.

#### Can I export YouTube data to CSV, Excel, or Google Sheets?

Yes. Every run stores results in an Apify dataset that exports to JSON, JSONL, CSV, Excel, XML, or HTML with one click, and the Google Sheets integration writes rows straight into a spreadsheet.

#### Can I run YouTube Search Scraper on a schedule?

Yes. Apify schedules run the Actor hourly, daily, weekly, or on any cron expression, and webhooks can notify your systems the moment a run finishes.

#### Is it legal to scrape YouTube?

Scraping publicly available data is broadly lawful in the US and EU, but the answer depends on what you collect and how you use it. This Actor is built to gather public video metadata YouTube publishes publicly, including channel names. Personal data carries extra obligations under GDPR and CCPA. Read Apify's guide on [whether web scraping is legal](https://blog.apify.com/is-web-scraping-legal/) and take your own legal advice for your use case.

### Support and feedback

Found a bug, a missing field, or a YouTube page shape this Actor does not handle yet? Open an issue from the **Issues** tab on the Actor page. Feature requests and custom-scraper enquiries are welcome there too.

# Actor input Schema

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

One or more free-text search queries. YouTube search operators work in the query itself, for example "iphone 15" -plus or before:2024.

## `maxResultsPerQuery` (type: `integer`):

Hard cap on results returned per query. YouTube itself tops out around 600 to 1000 results per query, so values above 1000 are silently clipped.

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

Result order. "relevance" is YouTube's default ranking. "date" returns newest first, "views" returns most viewed first, "rating" returns highest rated.

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

Restrict to videos uploaded within this window. Ignored unless type is "video" or "any".

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

short = under 4 minutes, medium = 4 to 20 minutes, long = over 20 minutes. Ignored unless type is "video" or "any".

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

Restrict results to a single type. "any" lets YouTube return a mix of videos, channels, and playlists. Note: applying upload date, duration, or feature filters forces type to "video".

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

Restrict to videos with one or more of these flags. Selecting any flag forces type to "video".

## `channelId` (type: `string`):

Restrict results to a single channel's uploads. Accepts a channel ID (UC...), a /channel/UC... URL, a /@handle URL, or just an @handle. Free-text filters above are ignored when a channel is set.

## `proxyConfiguration` (type: `object`):

Apify datacenter proxy is sufficient for routine search volume. Switch to Residential if you hit throttling at very high volume or from blocked geographies.

## Actor input object example

```json
{
  "searchQueries": [
    "iphone 15 review"
  ],
  "maxResultsPerQuery": 100,
  "sortBy": "relevance",
  "uploadDate": "any",
  "duration": "any",
  "type": "any",
  "features": [],
  "channelId": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

All search results extracted in the latest run.

## `itemsCsv` (type: `string`):

All search results in CSV format.

## `itemsJson` (type: `string`):

All search results in JSON format.

## `consoleRun` (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 = {
    "searchQueries": [
        "iphone 15 review"
    ],
    "maxResultsPerQuery": 100,
    "sortBy": "relevance",
    "uploadDate": "any",
    "duration": "any",
    "type": "any",
    "channelId": "",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/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": ["iphone 15 review"],
    "maxResultsPerQuery": 100,
    "sortBy": "relevance",
    "uploadDate": "any",
    "duration": "any",
    "type": "any",
    "channelId": "",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/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": [
    "iphone 15 review"
  ],
  "maxResultsPerQuery": 100,
  "sortBy": "relevance",
  "uploadDate": "any",
  "duration": "any",
  "type": "any",
  "channelId": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call cirkit/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cirkit/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/s87eMc2lTc7LX08ie/builds/DW58J4qJBQr07u7Gx/openapi.json
