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

Scrape YouTube search results by keyword, hashtag, channel or search URL: videos, Shorts, channels, playlists and movies with exact views, likes, publish dates, tags and channel stats. Every YouTube filter, exact date ranges and deep search. No login, no API key.

- **URL**: https://apify.com/eiv/youtube-search-scraper.md
- **Developed by:** [Eimantas V](https://apify.com/eiv) (community)
- **Stats:** 7 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 result scrapeds

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** turns YouTube search results into data: videos, Shorts, channels, playlists and movies for any keyword, with exact views, likes, publish dates, tags, chapters and channel subscribers. Enter search terms, or paste YouTube search links, hashtags, playlists or a search inside a channel. No login, no API key, no browser, from **$0.30 per 1,000 results**.

```json
{
  "type": "video",
  "id": "YrVRx2c72ig",
  "url": "https://www.youtube.com/watch?v=YrVRx2c72ig",
  "title": "Python Web Scraping Tutorial: Complete Guide 2026",
  "channelName": "Oxylabs",
  "channelHandle": "@oxylabs",
  "channelSubscriberCount": 14800,
  "viewCount": 8247,
  "likeCount": 555,
  "commentCount": 3,
  "publishedAt": "2026-02-20T17:01:02.000Z",
  "durationSeconds": 481,
  "position": 7,
  "input": "web scraping tutorial",
  "keywords": ["web scraping in python", "python web scraping", "web scraping python", "oxylabs"],
  "category": "Science & Technology",
  "hashtags": ["#WebScraping", "#Python", "#BeautifulSoup"],
  "chapters": [{ "title": "Intro", "startSeconds": 0 }, { "title": "Environment & tools setup", "startSeconds": 35 }],
  "viewsPerDay": 37,
  "likesPerThousandViews": 67.3
}
```

**Measured on Apify: 100 videos with full details in 10 seconds; 150 results for three search terms in 24 seconds.**

### What does YouTube Search Scraper do?

It runs YouTube's own search, the way the search bar and its Filters menu do, and turns every result into a row, in YouTube's order. Then it checks YouTube's work: results that slip through a filter, repeats across pages and anything outside your own filters are dropped before you pay for them.

- **Every YouTube filter.** Type (videos, Shorts, channels, playlists, movies), upload date, length, live, 4K, HD, subtitles, Creative Commons, 360°, VR180, 3D, HDR and location, plus YouTube's "last hour" and older length options that still work. Hashtag, channel-search and playlist feeds take no YouTube filters; upload date and length are applied to their rows by the Actor.
- **Filters YouTube does not have.** Exact date ranges, view and length ranges, excluded words (YouTube ignores "-word"), excluded channels, minimum subscribers and a cap per channel.
- **Sorts that work.** YouTube removed sorting by upload date. This Actor sorts newest first and by exact views itself.
- **More than YouTube shows.** YouTube ends every search after roughly 200-500 results. Deep search repeats a search in date windows to go further: 3,000 unique videos for one keyword in our test.
- **Complete rows.** Exact views, likes, publish date, tags, category, full description with links, hashtags, chapters and the channel's subscribers, on every video and Short. Optional exact comment counts and channel details (country, total views, joined date, links, business-email flag).
- **More ways in.** Hashtag feeds, playlists, a search inside one channel, and single video links, in the same run.
- **Only pay for results.** Repeats within a search, filtered-out results and searches with no results are never charged. Turn on Remove duplicates across searches to pay once per result across search terms.
- **Built for automation.** Run it on a schedule, call it from the API, or connect it to Make, Zapier, n8n, Google Sheets or an AI agent through Apify's MCP server.

### Why it is fast and cheap

The Actor calls the same internal JSON endpoints youtube.com's own pages use. One request returns a page of about 20 results (25-50 KB); the details for a video are two small requests (its player data and its watch-page data). There is no browser and no HTML to render, so a run needs little memory and no proxy, and the savings are in the price.

### What data can you extract from YouTube?

| Field | Example | What it is |
|---|---|---|
| `type` | `video` | video, short, channel, playlist (also mixes, courses, albums), movie or post |
| `title`, `url`, `id` | `Python Full Course for Beginners` | The result itself, with a clean link |
| `viewCount`, `likeCount`, `commentCount` | `49216902`, `1293847`, `41862` | Exact views and likes; comments rounded by YouTube unless you ask for exact |
| `publishedAt` | `2019-02-18T15:00:08.000Z` | Exact publish time (see `publishedAtPrecision`) |
| `durationSeconds` | `22447` | Length, also for Shorts |
| `channelName`, `channelHandle`, `channelId` | `Programming with Mosh`, `@programmingwithmosh` | Who uploaded it |
| `channelSubscriberCount` | `4200000` | The channel's subscribers, as YouTube rounds them |
| `keywords`, `category`, `hashtags` | `["python", "tutorial"]`, `Education` | Tags the uploader set, YouTube category, hashtags |
| `description`, `descriptionLinks` | `Learn Python…`, `["https://…"]` | Full description and every link in it |
| `chapters` | `[{ "title": "Introduction", "startSeconds": 0 }]` | Chapters and their start times |
| `position` | `3` | Rank in YouTube's results for your search |
| `viewsPerDay`, `likesPerThousandViews` | `1203`, `26.3` | Ratios that compare videos of different ages and sizes |
| `badges`, `isLive`, `liveViewerCount` | `["4K", "CC"]`, `true`, `6924` | Badges, live streams and their concurrent viewers |
| `videoCount`, `playlistType` | `124`, `course` | Playlists and courses: exact number of videos |
| `aiSummary` | `Nick demonstrates…` | YouTube's own AI summary, when the results page shows one |
| `correctedQuery` | `python tutorial` | What YouTube searched instead, when it corrected your spelling |

The dataset has 67 fields in all; the **Overview**, **Video details**, **Channels** and **Playlists** views show the useful columns for each kind of result.

### How to scrape YouTube search results

1. Click **Try for free** and type your search terms into **Search terms**, one per line (or paste YouTube links into **YouTube URLs**).
2. Pick **Result types** and any filters. All are optional.
3. Set **Max results per search**. You pay per result, so this is also your cost cap.
4. Click **Start**. A search of 100 videos with full details takes about 10 seconds. Download the results as JSON, CSV, Excel or HTML from the **Output** tab.

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

You pay per result returned, and the price drops on higher Apify plans:

| Apify plan | Per 1,000 results |
|---|---|
| Free | $0.50 |
| Starter | $0.40 |
| Scale | $0.35 |
| Business and Enterprise | $0.30 |

- 1,000 videos with views, likes, dates, tags and subscribers: **$0.40** on Starter.
- 50 search terms with 100 videos each (5,000 rows): **$2.00** on Starter, **$1.50** on Business.
- Exact comment counts, channel details and deep search are included in the same price per result.
- A run also costs **$0.00005** to start. Searches that find nothing, repeats within a search and filtered-out results cost nothing.
- The Free plan's $5 monthly credit covers about **10,000 results**.

### Input

```json
{
    "searchQueries": ["web scraping tutorial", "best budget smartphone 2026"],
    "resultTypes": ["video", "short"],
    "maxResults": 100,
    "dateFilter": "month",
    "sortBy": "newest",
    "minViews": 1000,
    "excludeKeywords": ["sponsored"]
}
```

| Field | Default | Notes |
|---|---|---|
| Search terms (`searchQueries`) | | What you would type into YouTube's search bar. Quoted phrases work |
| YouTube URLs (`startUrls`) | | Search results pages (keeping their filters), hashtag pages, `/@channel/search?query=…`, playlists, videos |
| Hashtags (`hashtags`) | | Hashtag feeds: `cooking`, `#travel` |
| Search inside channels (`searchInChannels`) | | Handles or channel URLs: each search term is searched inside each channel |
| Result types (`resultTypes`) | Videos | Videos, Shorts, Channels, Playlists, Movies, or Everything as YouTube mixes it |
| Max results per search (`maxResults`) | 100 | Per search term and result type |
| Max results in total (`maxItems`) | 10,000 | Stops the whole run |
| Sort by (`sortBy`) | Relevance | Relevance, Popularity, Newest first, Most viewed |
| Upload date, Length, Features | any | YouTube's own filters (`dateFilter`, `lengthFilter`, `isLive`, `is4K`, `isHD`, `hasSubtitles`, `hasCC`, `is360`, `isVR180`, `is3D`, `isHDR`, `hasLocation`) |
| Exact search (`exactQuery`) | off | Stops YouTube from correcting your spelling |
| Language, Location (`language`, `country`) | English, United States | YouTube's interface language and location: they change the ranking |
| Restricted Mode (`restrictedMode`) | off | YouTube's safe search |
| Uploaded after / before | | Exact date range: a date (2024-01-31) or a period (30 days) |
| Min / Max views, Min / Max length, Min channel subscribers | | Ranges YouTube cannot filter by |
| Exclude words, Exclude channels, Max results per channel | | Clean up the list |
| Video details (`includeVideoDetails`) | on | Exact date, likes, tags, category, description, subscribers |
| Comment count, Channel details | off | Exact comment count; the channel's About data on every row |
| Deep search (`deepSearch`) | off | Beyond YouTube's ~500 results per search |
| Shelf results, Remove duplicates across searches | off | YouTube's extra shelves; one row per result across search terms |
| Proxy | none | Not needed. If YouTube refuses the run's address, Apify datacenter proxy is used automatically |

### Output

Each result is one row in the dataset. A search that finds nothing, or a link this Actor does not read, becomes a row with `"recordType": "error"` and an `errorCode` instead of failing the whole run:

| `errorCode` | Meaning |
|---|---|
| `NO_RESULTS` | YouTube found nothing for this search, hashtag or channel search |
| `NOT_FOUND` / `CHANNEL_NOT_FOUND` | The playlist, video or channel does not exist or is private |
| `UNSUPPORTED_URL` | A YouTube page this Actor does not read (for example a channel page) |
| `INVALID_INPUT` | Something the input cannot do, e.g. Search inside channels without search terms |
| `BLOCKED` / `RATE_LIMITED` / `NETWORK_ERROR` | YouTube refused or did not answer the request; run again or enable a proxy |
| `PARSE_FAILED` | YouTube changed its page layout; please report it |

Error rows are never charged. The **Run summary** record lists every search with YouTube's result estimate, pages read, results filtered out per reason and why each search stopped.

### YouTube's search filters in 2026

YouTube changed its Filters menu in 2026, and many scrapers still send the old values:

- **Sorting by upload date and rating is gone.** YouTube accepts the old values and silently returns relevance order. This Actor's **Newest first** collects what YouTube returns and sorts it by date itself (and its **Most viewed** sorts by exact view count).
- **Length buckets changed** to under 3 minutes, 3-20 minutes and over 20 minutes. The old under 4 and 4-20 still work and are offered.
- **"Last hour" left the menu** but still works.
- **YouTube's filters leak.** Under "Today", videos 5 days and 4 years old came back in our tests. Every result is checked against the filter you chose, and the ones that slip through are not delivered or charged.
- **The minus operator is ignored** ("iphone -case" still returns cases). Use **Exclude words**; "-word" in a search term is applied automatically.

### Coming from another YouTube scraper?

Paste your saved input. The field names of the most popular YouTube scraper (`searchQueries`, `maxResults`, `maxResultsShorts`, `sortingOrder`, `dateFilter`, `videoType`, `lengthFilter`, `isHD`, `oldestPostDate` and the rest) and of other search Actors (`query`, `keywords`, `uploadDate`, `duration`, `features`, `gl`, `hl` and more) are understood, and the run log says how each one was read.

### Tips and limits

- **About 200-500 results per search.** That is where YouTube stops. Use Deep search, or several related search terms, for more.
- **Results change between runs and by location.** YouTube's ranking is not fixed: two identical searches minutes apart share only part of their first page. Location and language change it too.
- **Language.** With English, YouTube translates foreign titles on its results page. Video details restore the original title and keep YouTube's version in `translatedTitle`.
- **Rounded numbers.** Channel subscribers are rounded by YouTube everywhere. Comment counts are rounded unless you turn on Comment count. Shorts' views are exact with video details on.
- **Tags and category** come from YouTube Music's player data, which YouTube does not give for every video. When it is missing, the row has likes, exact views and the publish day from the watch page instead (`publishedAtPrecision` is then `day`).
- **Not available without a login:** the Purchased filter, members-only and paid-promotion flags, channel email addresses (only whether a business email exists), and subtitles. For transcripts use [YouTube Transcript Scraper](https://apify.com/eiv/youtube-transcript-probe).
- **Hit your spending limit?** The run stops cleanly at your maximum cost per run and keeps everything it collected. Raise the limit in the run options to get more.

### FAQ

#### Is it legal to scrape YouTube?

This Actor collects only data YouTube shows publicly, without logging in. Results can still contain personal data, which laws such as the GDPR protect. Scrape personal data only for a legitimate purpose, and ask a lawyer if you are unsure. YouTube is a trademark of Google; this Actor is not affiliated with or endorsed by YouTube or Google.

#### Can I use it through the API or with Make, Zapier and n8n?

Yes. Every run can be started through the [Apify API](https://docs.apify.com/api/v2) and returns the dataset as JSON, CSV or Excel. Schedules, webhooks and integrations for Make, Zapier, n8n and Google Sheets are on the **Integrations** tab.

#### Can AI agents use it?

Yes. Agents connected to [Apify's MCP server](https://mcp.apify.com) can find and run this Actor as a tool, with the same per-result pricing. An empty call runs an example search instead of failing.

#### Why did I get fewer results than I asked for?

YouTube ended the search (it stops after roughly 200-500 results), your filters removed some results, or the run reached your maximum cost or its timeout. The run summary says which, per search, and nothing collected before that is lost.

#### Can I get more than 500 videos for one keyword?

Yes: turn on **Deep search** and raise **Max results per search**. It searches again in date windows, newest first, and removes repeats; it also works inside an Upload date or date range. One test search returned 3,000 unique videos.

#### Does it need a proxy?

No. YouTube's search answers Apify's servers directly. If YouTube ever refuses a run's address, the Actor switches to Apify's datacenter proxy by itself.

### Related scrapers

- [YouTube Channel Scraper](https://apify.com/eiv/youtube-channel-scraper): every video of a channel, with subscriber counts and upload rhythm.
- [YouTube Comments Scraper](https://apify.com/eiv/youtube-comments-scraper): the comments and replies of any video.
- [YouTube Transcript Scraper](https://apify.com/eiv/youtube-transcript-probe): the transcript of any video or Short as text.
- [YouTube Shorts Scraper](https://apify.com/eiv/youtube-shorts-scraper): every Short of a channel.

### Support

Missing a field, or found a search that does not work? Open an issue on the **Issues** tab with the input you used, and it will be looked at quickly.

# Actor input Schema

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

What you would type into YouTube's search bar, one per line. Quoted phrases work ("iphone 17"); YouTube ignores -word, so this Actor removes those results for you. Each term runs once per result type. YouTube links pasted here are read like the URLs below.

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

Search results pages (youtube.com/results?search_query=…, keeping their filters), hashtag pages (/hashtag/…), searches inside a channel (/@handle/search?query=…), playlists (playlist?list=…) and single videos. Channel pages are listed by YouTube Channel Scraper instead.

## `hashtags` (type: `array`):

Hashtag feeds, with or without #: cooking, #travel. Returns the videos and Shorts YouTube shows on /hashtag/<tag> (only Shorts when Result types is Shorts alone).

## `searchInChannels` (type: `array`):

Channel handles, URLs or IDs (@mkbhd, youtube.com/@mkbhd, UC…). When set, every search term is searched inside each of these channels instead of all of YouTube.

## `resultTypes` (type: `array`):

What to search for. Each search term runs once per type, with its own limit. Videos leaves out Shorts; Everything is the mixed page YouTube shows (videos, Shorts, playlists, channels, movies).

## `maxResults` (type: `integer`):

Per search term and result type. YouTube itself ends a search after roughly 200-500 results; turn on Deep search to go further. You pay per result, so this also caps the cost.

## `maxItems` (type: `integer`):

Stops the whole run after this many results, across all searches.

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

Relevance and Popularity are YouTube's own rankings. YouTube removed its upload-date sort, so Newest first and Most viewed are sorted by this Actor, over every result YouTube returns for the search.

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

Only results uploaded in this period. Last hour is gone from YouTube's menu but still works.

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

YouTube's length buckets. The two older ones (under 4 minutes, 4-20 minutes) still work. For exact bounds use Min and Max length below.

## `isLive` (type: `boolean`):

Only streams that are live right now.

## `is4K` (type: `boolean`):

Only videos available in 4K.

## `isHD` (type: `boolean`):

Only HD videos.

## `hasSubtitles` (type: `boolean`):

Only videos with creator-provided subtitles.

## `hasCC` (type: `boolean`):

Only videos under a Creative Commons licence (reuse allowed).

## `is360` (type: `boolean`):

Only 360° videos.

## `isVR180` (type: `boolean`):

Only VR180 videos.

## `is3D` (type: `boolean`):

Only 3D videos.

## `isHDR` (type: `boolean`):

Only HDR videos.

## `hasLocation` (type: `boolean`):

Only videos with a location set. YouTube rarely returns results for this filter.

## `exactQuery` (type: `boolean`):

Search exactly what you typed. Without it YouTube silently searches a corrected spelling, and returns unrelated videos for terms it does not know; the correctedQuery field shows when that happened.

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

YouTube's interface language: which languages rank higher and the language of the text YouTube adds. With English, YouTube translates foreign titles; video details restore the original (translatedTitle keeps YouTube's translation).

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

Ranks results for this country, like YouTube's location setting.

## `restrictedMode` (type: `boolean`):

YouTube's Restricted Mode (safe search): leaves out potentially mature videos.

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

A date (2024-01-31) or a period back from now (30 days). Also sent to YouTube as a date operator, so the search itself is narrowed, not just its first pages.

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

A date (2024-12-31, inclusive) or a period back from now (7 days).

## `minViews` (type: `integer`):

Only videos and Shorts with at least this many views.

## `maxViews` (type: `integer`):

Only videos and Shorts with at most this many views, e.g. to find small creators.

## `minDurationSeconds` (type: `integer`):

Only videos at least this long, in seconds (600 = 10 minutes).

## `maxDurationSeconds` (type: `integer`):

Only videos at most this long, in seconds.

## `minSubscribers` (type: `integer`):

Only results from channels with at least this many subscribers (YouTube rounds the counts). For video rows this switches on Channel details.

## `excludeKeywords` (type: `array`):

Drop results whose title or description contains any of these. Whole words: "case" does not drop "showcase". Phrases work too.

## `excludeChannels` (type: `array`):

Drop results from these channels: handles (@mkbhd), channel IDs, channel URLs or names.

## `maxResultsPerChannel` (type: `integer`):

At most this many results from any one channel across the run (0 = no limit), for a list of distinct creators.

## `includeVideoDetails` (type: `boolean`):

Exact publish time, likes, tags, category, full description with links and hashtags, chapters, the channel's subscribers and a comment count. Completes Shorts (channel, date, length, exact views). Two small requests per video (player data and the watch page), included in the price.

## `includeCommentCount` (type: `boolean`):

The exact number of comments and whether comments are turned off. One extra request per video (about 30 KB).

## `includeChannelDetails` (type: `boolean`):

The channel's subscribers, total views, video count, country, joined date, links, business-email flag and description, on every row. One request per channel.

## `deepSearch` (type: `boolean`):

YouTube ends each search after roughly 200-500 results. Deep search repeats a video search in date windows, newest first, to reach results the plain search never shows. Slower. Works for Videos, Movies and Everything (not Shorts), also inside an Upload date or date range.

## `includeShelves` (type: `boolean`):

Also return items from YouTube's extra shelves: "Latest from <channel>", "Channels new to you", "Popular in <city>", "From health sources", artist cards and community posts. Off: only the search results themselves.

## `deduplicateResults` (type: `boolean`):

A result found by several search terms or types is returned, and charged, once. Off: each search returns its own full list (repeats within one search are always removed).

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

Not needed: YouTube's own API answers without one. If YouTube refuses the run's address, the Actor switches to Apify datacenter proxy by itself. Residential proxy is never used.

## `maxConcurrency` (type: `integer`):

How many searches run at the same time.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one response before giving up on it.

## `maxRetries` (type: `integer`):

Retries for blocked, rate-limited or failed connections. Timeouts are not retried.

## Actor input object example

```json
{
  "searchQueries": [
    "web scraping tutorial"
  ],
  "resultTypes": [
    "video"
  ],
  "maxResults": 100,
  "maxItems": 10000,
  "sortBy": "relevance",
  "exactQuery": false,
  "language": "en",
  "country": "US",
  "restrictedMode": false,
  "maxResultsPerChannel": 0,
  "includeVideoDetails": true,
  "includeCommentCount": false,
  "includeChannelDetails": false,
  "deepSearch": false,
  "includeShelves": false,
  "deduplicateResults": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxConcurrency": 5,
  "requestTimeoutSecs": 30,
  "maxRetries": 2
}
```

# Actor output Schema

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

Every result (recordType "result"), with uncharged rows for searches that found nothing or URLs that could not be read (recordType "error").

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

The same rows with views, likes, comments, engagement ratios, tags and category side by side.

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

Totals for the run and per search: YouTube's result estimate, pages read, results filtered out per reason, results delivered and why each search stopped.

# 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": [
        "web scraping tutorial"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("eiv/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": ["web scraping tutorial"] }

# Run the Actor and wait for it to finish
run = client.actor("eiv/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": [
    "web scraping tutorial"
  ]
}' |
apify call eiv/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

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