# YouTube Scraper (`vortex_data/youtube-scraper`) Actor

⚡ Every YouTube field in one Actor — videos, channels, playlists, search, Shorts, comments, subtitles, hashtags — at 200+ videos/sec. Chrome TLS fingerprint, rotating residential IPs, full channel metadata on every row. Zero blocks, zero CAPTCHAs.

- **URL**: https://apify.com/vortex_data/youtube-scraper.md
- **Developed by:** [VortexData](https://apify.com/vortex_data) (community)
- **Categories:** Videos, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 24 total users, 4 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 video (listing only)s

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?

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 Data Collector

Paste a YouTube video, channel, playlist, search URL, hashtag, video ID, channel ID, playlist ID, @handle, or keyword. Choose the result package you want and a size. The Actor detects every input automatically and separates the output into clean datasets.

### 🚀 Quick Start

1. Paste one or more items into **📥 Paste what you have**.
2. Keep **🎯 Choose result package** on **🧲 Complete** if you simply want everything from each input.
3. Pick **📦 Choose size**.
4. Run the Actor.

Most users only need those three fields. You never need to choose video, channel, playlist, or search manually: source detection is automatic.

### 🎯 Result Packages

| Package | Use when | Collects |
|---|---|---|
| **🧲 Complete** | You want the full dataset from whatever you pasted | Videos, channels, playlists, Shorts, streams, posts, transcripts, comments, replies, contacts, insights, media, diagnostics |
| **⚡ Quick** | You want a fast clean table first | Lightweight metadata only, without comments, transcripts, media expansion, or contact crawling |
| **🧠 Research** | You compare topics, keywords, and engagement | Search across videos, channels, and playlists with content insights and enrichment |
| **💬 Comments** | You monitor audience feedback | Flat comments and replies, newest/top sorting, continuation tokens, dedupe across scheduled runs |
| **📧 Leads** | You build creator prospect lists | Public emails, websites, social links, contact links, external-page enrichment, and validation |
| **📝 Transcripts** | You build AI/RAG datasets | Transcript text, timestamped segments, language fallback, match terms, and compact transcript output |
| **🎞️ Media** | You audit technical/video extras | Media formats, chapters, SponsorBlock segments, related videos, live chat/replay when public |

### 📥 Accepted Inputs

You can mix input types in the same run.

| Input | Example |
|---|---|
| Video URL | `https://www.youtube.com/watch?v=wwSzpaTHyS8` |
| Shorts URL | `https://www.youtube.com/shorts/...` |
| Video ID | `dQw4w9WgXcQ` |
| Channel handle | `@NASA` |
| Channel ID | `UC...` |
| Playlist URL | `https://www.youtube.com/playlist?list=...` |
| Search URL | `https://www.youtube.com/results?search_query=...` |
| Hashtag | `https://www.youtube.com/hashtag/apify` |
| Keyword | `web scraping tutorial` |

### 📦 Size Presets

| Size | Best for | Default limits |
|---|---|---|
| `test` | Fast validation | Tiny sample, minimal comments and replies |
| `small` | First real run | Recommended first production run |
| `medium` | Research dataset | More items, comments, replies, and enrichment |
| `large` | Big export | Large but capped export |
| `unlimited` | Maximum collection | No global result-row cap |

Advanced API users can still override exact limits with hidden fields such as `maxResults`, `maxItems`, `maxComments`, and `maxRepliesPerComment`.

### 📤 Output

The Actor writes separate datasets so the Apify Output tab stays readable. The first output is **Videos**, not a mixed table, so channel, playlist, post, comment, and diagnostic rows do not appear as odd rows inside a video table.

| Dataset | Contains |
|---|---|
| **Videos** | Video, Shorts, stream, and movie rows only |
| **Channels** | Channel profiles from channel inputs and channel search results |
| **Playlists / search** | Playlist, show, and other non-video search entity rows |
| **Posts** | Community post rows from channel Community/Posts tabs |
| **Transcripts** | Rows with transcript text, subtitle status, or transcript keyword matches |
| **Contacts** | Rows with public emails, websites, socials, or contact links |
| **Media** | Rows with media formats, SponsorBlock, chapters, live chat, or related videos |
| **Comments** | One flat row per comment or reply |
| **Diagnostics** | Invalid inputs, unavailable videos, empty sources, and source failures |
| **All records** | Compatibility dataset with every non-comment, non-diagnostic main row |

The same clean row can appear in more than one focused dataset. For example, a video with transcript and media data appears in **Videos**, **Transcripts**, and **Media**; it is still one billed main result.

### 🧾 Canonical Fields

| Meaning | Field |
|---|---|
| Video/channel/search URL | `url` |
| Source page that produced the item | `sourceUrl` |
| Views | `views` |
| Likes | `likes` |
| Subscribers | `subscribers` |
| Video description | `description` |
| Comment text | `text` in the Comments dataset |
| Transcript text | `transcriptText` |
| Creator emails | `emails` |

Legacy raw aliases can still be returned with the hidden `includeRawFields` API option.

### 🧩 Example Inputs

#### Complete mixed run

```json
{
  "targets": [
    "https://www.youtube.com/watch?v=wwSzpaTHyS8",
    "@NASA",
    "web scraping tutorial"
  ],
  "scenario": "complete",
  "runSize": "test"
}
```

#### Everything from a video

```json
{
  "targets": ["https://www.youtube.com/watch?v=wwSzpaTHyS8"],
  "scenario": "complete",
  "runSize": "small"
}
```

#### Everything from a channel

```json
{
  "targets": ["@NASA"],
  "scenario": "complete",
  "runSize": "small"
}
```

#### Fast metadata only

```json
{
  "targets": ["@NASA", "web scraping tutorial"],
  "scenario": "quick_metadata",
  "runSize": "small"
}
```

#### Research keywords and engagement

```json
{
  "targets": ["web scraping tutorial"],
  "scenario": "research_insights",
  "runSize": "small"
}
```

#### Comment monitoring

```json
{
  "targets": ["https://www.youtube.com/watch?v=wwSzpaTHyS8"],
  "scenario": "comments_monitoring",
  "runSize": "small",
  "stateKey": "my-video-comments"
}
```

#### AI transcripts

```json
{
  "targets": ["https://www.youtube.com/watch?v=wwSzpaTHyS8"],
  "scenario": "transcripts_for_ai",
  "runSize": "small",
  "subtitlesLanguages": ["en", "any"],
  "subtitlesFormat": "plaintext"
}
```

#### Creator leads

```json
{
  "targets": ["@NASA", "ai automation agency"],
  "scenario": "creator_leads",
  "runSize": "small",
  "emailValidation": "syntax"
}
```

#### Media audit

```json
{
  "targets": ["https://www.youtube.com/watch?v=wwSzpaTHyS8"],
  "scenario": "media_audit",
  "runSize": "small"
}
```

### 🧠 Feature Coverage

| Feature | Status |
|---|---|
| Video metadata | Included |
| Channel about data | Included |
| Channel profile output | Included |
| Playlists | Included |
| Search results | Included |
| Shorts | Included |
| Streams | Included |
| Community posts | Included |
| Comments and replies | Included |
| Continuation tokens | Included |
| Dedupe across scheduled runs | Included |
| Transcripts and captions | Included |
| Language fallback | Included |
| Transcript search | Included |
| SponsorBlock segments | Included |
| Related videos | Included |
| Chapters | Included |
| Most-replayed heatmap | Included |
| Music credits | Included |
| Creator contacts | Included |
| Content insights | Included |
| Live chat and replay chat | Best effort when YouTube exposes public continuation |
| Media format summaries | Included |
| Entity-separated output datasets | Included |
| Large payload KVS fallback | Included |
| Diagnostics dataset | Included |

### 🛠️ API Compatibility

The old `jobPreset` field and legacy scenario values such as `auto`, `video_full`, `channel_full`, `playlist_full`, and `search_full` are still accepted for existing integrations. New Console runs should use the visible result packages in `scenario`.

Legacy inputs such as `startUrls`, `searchQueries`, `youtubeHandles`, `videoIds`, `channelIds`, `playlistIds`, and `extraData` still work.

### ✅ Reliability

The Actor uses Chrome-like TLS requests through `curl_cffi`, Apify Residential Proxy on Apify Cloud, per-request proxy sessions, retry handling for transient YouTube responses, KVS fallback for large payloads, and separate diagnostics output for invalid or unavailable sources.

### 💾 Export

Download Videos, Channels, Playlists / search, Posts, Transcripts, Contacts, Media, Comments, Diagnostics, or All records from Apify in JSON, CSV, Excel, XML, RSS, or HTML, or consume them through Dataset API endpoints.

# Actor input Schema

## `targets` (type: `array`):

One item per line: video URLs, Shorts URLs, @handles, channel IDs, playlist IDs, video IDs, search result URLs, hashtags, or plain keywords.

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

Inputs are auto-detected. Leave Complete selected to collect everything from videos, channels, playlists, search URLs, IDs, handles, hashtags, and keywords.

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

One size controls breadth and depth: items per source, comments per video, replies, related videos, live chat, and lead-enrichment depth.

## `extraData` (type: `array`):

Hidden API compatibility field. Console users should choose a result package instead.

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

Exact override for run size. Leave empty unless you need a precise per-channel, per-playlist, or per-keyword cap.

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

Exact override for run size. 0 means no global cap. Leave empty to use the selected run size.

## `downloadSubtitles` (type: `boolean`):

Fetch public captions/transcripts for each video. AI transcript workflows enable this automatically.

## `downloadComments` (type: `boolean`):

Fetch comments for each video.

## `includeCommentReplies` (type: `boolean`):

Open reply threads under comments. Useful for analysis, but it adds extra requests.

## `extractContacts` (type: `boolean`):

Extract public emails, websites, social links, and contact links from videos and channels.

## `enableContentInsights` (type: `boolean`):

Add lightweight insights: keywords, topics, sentiment, and detected language.

## `includeShorts` (type: `boolean`):

Also collect Shorts when scraping channels. If Shorts per channel is 0, the main Items per source limit will be used.

## `downloadCommunityPosts` (type: `boolean`):

Also collect public community posts when scraping channels.

## `downloadRecommendations` (type: `boolean`):

Extract recommended/related videos from each public watch page.

## `downloadSponsorSegments` (type: `boolean`):

Fetch sponsor, intro, outro, self-promo, and other segments from SponsorBlock when available.

## `includeDownloadFormats` (type: `boolean`):

Add compact video/audio format metadata: quality, codec, bitrate, best audio, and best video.

## `downloadLiveChat` (type: `boolean`):

Best-effort live chat or replay chat scraping when YouTube exposes a public continuation token.

## `maxComments` (type: `integer`):

Exact override for the selected size. Leave empty so Test/Small/Medium/Large/Maximum controls this automatically.

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

How comments should be sorted before scraping.

## `maxRepliesPerComment` (type: `integer`):

Exact override for the selected size. Leave empty so Test/Small/Medium/Large/Maximum controls this automatically.

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

Flat means one row per comment. Nested means comments stay inside the video row. Both returns both shapes.

## `dedupeAcrossRuns` (type: `boolean`):

For monitoring: store seen IDs and return only new items in later runs.

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

Optional. Use the same key for repeated monitoring runs. If empty, the key is derived from sources and settings.

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

Caption language to try first. Use any to accept the first available public caption track.

## `subtitlesLanguages` (type: `array`):

Fallback language order, for example: en, es, any.

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

Transcript format in the dataset or key-value store.

## `includeTranscriptSegments` (type: `boolean`):

Return transcript segments with start, end, duration, and text. Useful for RAG, quotes, and clip analysis.

## `saveSubsToKVS` (type: `boolean`):

Keep the dataset compact by writing large transcript payloads to the key-value store and returning a key.

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

Optional YouTube timedtext translation target language. Empty means no translation.

## `preferAutoGeneratedSubtitles` (type: `boolean`):

Choose YouTube ASR captions before manual captions when both are available.

## `transcriptSearchTerms` (type: `array`):

Words or phrases to search inside transcript text. Matching segments are returned with timestamps.

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

Match any term or require all terms.

## `onlyMatchedTranscripts` (type: `boolean`):

Skip videos whose transcript does not contain the requested terms.

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

Applies only to search keywords and YouTube /results URLs.

## `searchResultTypes` (type: `array`):

Run each keyword as separate searches for the selected types. For Search intelligence, videos + channels + playlists is usually best.

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

Restrict search results by upload date.

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

Restrict search results by video duration.

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

Hidden legacy search type. Use Search result types instead.

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

Search filter: only HD videos.

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

Search filter: only 4K videos.

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

Search filter: only HDR videos.

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

Search filter: live videos or streams.

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

Search filter: videos with subtitles or captions.

## `maxResultsShorts` (type: `integer`):

Maximum Shorts to collect from each channel. 0 means skip Shorts unless a preset enables them.

## `maxResultStreams` (type: `integer`):

Maximum streams or live replays to collect from each channel.

## `maxCommunityPosts` (type: `integer`):

Maximum community posts to collect from each channel.

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

Sorting for channel tabs: Videos, Shorts, and Streams.

## `maxRecommendations` (type: `integer`):

Exact override for the selected size. Leave empty so Test/Small/Medium/Large/Maximum controls this automatically.

## `maxInsightKeywords` (type: `integer`):

Maximum keyword terms to return in contentInsights.keywords.

## `crawlExternalLinks` (type: `boolean`):

Visit external websites found in descriptions or about links to discover more emails, socials, and contact links.

## `maxExternalPagesPerChannel` (type: `integer`):

Exact override for the selected size when creator lead enrichment crawls linked public websites.

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

Validate extracted emails. Domain DNS checks are slower but more useful for lead lists.

## `sponsorBlockCategories` (type: `array`):

SponsorBlock categories to request.

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

Optional Apify URL editor for CSV, Google Sheets, or bulk imports. For manual runs, use the Targets field above.

## `getTrending` (type: `boolean`):

Best effort. YouTube often hides /feed/trending without login. For reliable trend research, use Search intelligence with sort by views and upload date today.

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

Exact date filter for watch records, format YYYY-MM-DD. Forces per-video fetch on listings.

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

Exact date filter for watch records, format YYYY-MM-DD. Forces per-video fetch on listings.

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

Two-letter country code such as us, gb, de, or jp. Affects YouTube results and residential proxy country.

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

Two-letter interface language such as en, es, de, ja, or ru.

## `concurrency` (type: `integer`):

How many HTTP requests run in parallel. Higher is faster, but may produce more proxy or YouTube retries.

## `maxLiveChatMessages` (type: `integer`):

Exact override for the selected size. Leave empty so Test/Small/Medium/Large/Maximum controls this automatically.

## `includeStreamingData` (type: `boolean`):

Attach raw playerResponse.streamingData. Usually not needed because it can make dataset rows much larger.

## `includeFormatUrls` (type: `boolean`):

Include direct format URLs when YouTube exposes them. Some formats still require signature deciphering.

## `includeContinuationTokens` (type: `boolean`):

Return commentsNextContinuation so a client can continue comment paging later.

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

Advanced: continue comments from a token returned by a previous run.

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

Named key-value store used for dedupe state across runs.

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

Hidden compatibility field for API callers. In Console, use Targets or search keywords.

## `youtubeHandles` (type: `array`):

Hidden compatibility field for API callers. In Console, use Targets or search keywords.

## `videoIds` (type: `array`):

Hidden compatibility field for API callers. In Console, use Targets or search keywords.

## `channelIds` (type: `array`):

Hidden compatibility field for API callers. In Console, use Targets or search keywords.

## `playlistIds` (type: `array`):

Hidden compatibility field for API callers. In Console, use Targets or search keywords.

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

Hidden compatibility field for API callers. Console users should choose a result package.

## `includeRunMetadata` (type: `boolean`):

Hidden default: attach scrapedAt, runId, sourceType, sourceUrl, and source indexes.

## `includeRawFields` (type: `boolean`):

Hidden compatibility option for API users. Leave disabled for a clean Output tab without duplicate aliases.

## `pushErrorItems` (type: `boolean`):

Hidden default: failed direct inputs create diagnostic dataset rows.

## `maxStateItems` (type: `integer`):

Hidden default: maximum seen IDs retained for monitoring dedupe state.

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

Hidden rare YouTube search filter: stereoscopic 3D videos.

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

Hidden rare YouTube search filter: 360-degree videos.

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

Hidden rare YouTube search filter: VR180 videos.

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

Hidden rare YouTube search filter: Creative Commons videos.

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

Hidden rare YouTube search filter: videos with a public location tag.

## `isBought` (type: `boolean`):

Hidden compatibility search filter for purchased videos.

## Actor input object example

```json
{
  "targets": [
    "https://www.youtube.com/watch?v=wwSzpaTHyS8",
    "@NASA",
    "web scraping tutorial"
  ],
  "scenario": "complete",
  "runSize": "small",
  "extraData": [],
  "downloadSubtitles": false,
  "downloadComments": false,
  "includeCommentReplies": false,
  "extractContacts": false,
  "enableContentInsights": false,
  "includeShorts": false,
  "downloadCommunityPosts": false,
  "downloadRecommendations": false,
  "downloadSponsorSegments": false,
  "includeDownloadFormats": false,
  "downloadLiveChat": false,
  "commentsSortBy": "top",
  "commentsOutput": "auto",
  "dedupeAcrossRuns": false,
  "stateKey": "",
  "subtitlesLanguage": "en",
  "subtitlesLanguages": [],
  "subtitlesFormat": "srt",
  "includeTranscriptSegments": true,
  "saveSubsToKVS": false,
  "translateSubtitlesTo": "",
  "preferAutoGeneratedSubtitles": false,
  "transcriptSearchTerms": [
    "pricing",
    "agent"
  ],
  "transcriptSearchMode": "any",
  "onlyMatchedTranscripts": false,
  "searchResultTypes": [
    "video",
    "channel",
    "playlist"
  ],
  "isHD": false,
  "is4K": false,
  "isHDR": false,
  "isLive": false,
  "hasSubtitles": false,
  "maxResultsShorts": 0,
  "maxResultStreams": 0,
  "maxCommunityPosts": 0,
  "sortVideosBy": "NEWEST",
  "maxInsightKeywords": 20,
  "crawlExternalLinks": false,
  "emailValidation": "none",
  "sponsorBlockCategories": [
    "sponsor",
    "selfpromo",
    "interaction",
    "intro",
    "outro"
  ],
  "startUrls": [],
  "getTrending": false,
  "gl": "us",
  "hl": "en",
  "concurrency": 5,
  "includeStreamingData": false,
  "includeFormatUrls": false,
  "includeContinuationTokens": false,
  "commentsContinuationToken": "",
  "stateStoreName": "youtube-scraper-state",
  "searchQueries": [],
  "youtubeHandles": [],
  "videoIds": [],
  "channelIds": [],
  "playlistIds": [],
  "scrapeMode": "metadata",
  "includeRunMetadata": true,
  "includeRawFields": false,
  "pushErrorItems": true,
  "maxStateItems": 200000,
  "is3D": false,
  "is360": false,
  "isVR180": false,
  "hasCC": false,
  "hasLocation": false,
  "isBought": false
}
```

# Actor output Schema

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

Video, Shorts, stream, and movie rows only.

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

Channel profiles and channel search results only.

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

Playlist, show, and non-video search entity rows.

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

Community post rows only.

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

Rows with transcript text, subtitle status, or transcript matches.

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

Rows with emails, websites, socials, or contact links.

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

Rows with media formats, SponsorBlock, chapters, live chat, or related videos.

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

Flat comment and reply rows.

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

Invalid inputs, unavailable videos, empty channels, and source failures.

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

Compatibility dataset with every non-comment, non-diagnostic main row.

# 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 = {
    "targets": [
        "https://www.youtube.com/watch?v=wwSzpaTHyS8",
        "@NASA",
        "https://www.youtube.com/playlist?list=PLObrtcm1Kw6PmbXg8bmfJN-o2Hgx8sidf",
        "web scraping tutorial",
        "dQw4w9WgXcQ"
    ],
    "scenario": "complete",
    "runSize": "test",
    "transcriptSearchTerms": [
        "pricing",
        "agent"
    ],
    "searchResultTypes": [
        "video",
        "channel",
        "playlist"
    ],
    "sponsorBlockCategories": [
        "sponsor",
        "selfpromo",
        "interaction",
        "intro",
        "outro"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vortex_data/youtube-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 = {
    "targets": [
        "https://www.youtube.com/watch?v=wwSzpaTHyS8",
        "@NASA",
        "https://www.youtube.com/playlist?list=PLObrtcm1Kw6PmbXg8bmfJN-o2Hgx8sidf",
        "web scraping tutorial",
        "dQw4w9WgXcQ",
    ],
    "scenario": "complete",
    "runSize": "test",
    "transcriptSearchTerms": [
        "pricing",
        "agent",
    ],
    "searchResultTypes": [
        "video",
        "channel",
        "playlist",
    ],
    "sponsorBlockCategories": [
        "sponsor",
        "selfpromo",
        "interaction",
        "intro",
        "outro",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("vortex_data/youtube-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 '{
  "targets": [
    "https://www.youtube.com/watch?v=wwSzpaTHyS8",
    "@NASA",
    "https://www.youtube.com/playlist?list=PLObrtcm1Kw6PmbXg8bmfJN-o2Hgx8sidf",
    "web scraping tutorial",
    "dQw4w9WgXcQ"
  ],
  "scenario": "complete",
  "runSize": "test",
  "transcriptSearchTerms": [
    "pricing",
    "agent"
  ],
  "searchResultTypes": [
    "video",
    "channel",
    "playlist"
  ],
  "sponsorBlockCategories": [
    "sponsor",
    "selfpromo",
    "interaction",
    "intro",
    "outro"
  ]
}' |
apify call vortex_data/youtube-scraper --silent --output-dataset

```

## MCP server setup

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