# YouTube Data Scraper Pro (`mfttt11/youtube-data-scraper-pro`) Actor

Extract, filter, analyze, and monitor publicly accessible YouTube videos, Shorts, channels, playlists, search results, and trending data.

- **URL**: https://apify.com/mfttt11/youtube-data-scraper-pro.md
- **Developed by:** [umut A.](https://apify.com/mfttt11) (community)
- **Stats:** 2 total users, 1 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 Data Scraper Pro

Collect structured public YouTube data from videos, Shorts, search results, channels, handles, playlists, and regional popular feeds. The Actor is HTTP-first, streams results to an Apify Dataset, applies strict global limits, and is designed for scheduled monitoring and automation.

Use one direct video URL or combine several source types in the same run. Every accepted row keeps its source context, uses a stable ID, and can flow into spreadsheets, databases, dashboards, webhooks, or scheduled monitoring without a custom scraper.

### What it does

- Accepts one source or a mixed list of video, `youtu.be`, Shorts, search, channel, handle, `/videos`, `/shorts`, playlist, and live URLs.
- Runs native YouTube search filters for upload date, duration, feature, sort, country, and language.
- Enriches accepted videos with public metadata, optional caption/transcript data, derived engagement metrics, normalized contacts, and temporary streaming metadata.
- Deduplicates by stable video ID across every source and enforces `maxItems` exactly under concurrency.
- Supports incremental runs, safe field selection/mapping, JSON/CSV-friendly flat output, optional global sorting, adaptive retries, and isolated error storage.

### What you get

Every primary Dataset row has a stable `resultId`, canonical URL, source attribution, video/channel metadata, normalized numbers and dates, `complete` or `partial` status, and a data-quality block. Channel and playlist rows can be enabled through `resultTypes`. The Key-value store contains `RUN_SUMMARY`, `WORKLOAD_ESTIMATE`, and optional incremental state.

Viral Score is a derived heuristic, not an official YouTube metric. Streaming URLs and caption-track URLs may expire. Only information already exposed publicly by YouTube is processed.

### How to start

1. Enter a search keyword, YouTube URL, or channel handle.
2. Set **Maximum number of results**.
3. Press **Start**. Advanced filters are optional.

Minimal input:

```json
{
  "keywords": ["open source robotics"],
  "maxItems": 20
}
```

Example output:

```json
{
  "type": "video",
  "resultId": "youtube:video:dQw4w9WgXcQ",
  "title": "Example public video",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "views": 1250000,
  "publishDate": "2025-01-15T00:00:00.000Z",
  "channel": {
    "name": "Example Creator",
    "url": "https://www.youtube.com/@examplecreator"
  },
  "source": { "type": "direct_video" },
  "resultStatus": "complete"
}
```

### Why this Actor?

- Direct single-video analysis is a first-class input.
- Search, channels, handles, channel Shorts, playlists, and direct URLs can share one run.
- Native search filters and consistent post-filters are kept separate and transparent.
- The accepted-result cap is exact under concurrency, and duplicates are not counted twice.
- Source attribution, monitoring state, Dataset views, and API-friendly fields are built in.
- Analytics are optional and labeled as derived values rather than official YouTube metrics.

Mixed-source input:

```json
{
  "startUrls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
    { "url": "https://www.youtube.com/@GoogleDevelopers/shorts" },
    { "url": "https://www.youtube.com/playlist?list=PL590L5WQmH8fJ54F369BLDSqIwcs-TCfs" }
  ],
  "keywords": ["web performance"],
  "maxItems": 25,
  "distributionMode": "balanced"
}
```

### Supported sources

| Source   | Examples                                                                                                             |
| -------- | -------------------------------------------------------------------------------------------------------------------- |
| Video    | `youtube.com/watch?v=…`, `youtu.be/…`, `/embed/…`, `/live/…`                                                         |
| Shorts   | `youtube.com/shorts/…`, channel `/shorts` tab                                                                        |
| Search   | Keywords, `searchQueries`, and YouTube search-result URLs                                                            |
| Channel  | `/channel/…`, `/@handle`, `/@handle/videos`, legacy `/user/…` and `/c/…`                                             |
| Playlist | `/playlist?list=…` and watch URLs containing a playlist ID                                                           |
| Popular  | Region-aware home/popular fallback, explicitly labeled `popular_fallback` when a stable Trending feed is unavailable |

Unsupported hosts are rejected; this Actor is not a general-purpose URL crawler.

### Common input examples

Single video:

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],
  "maxItems": 1
}
```

Channel or handle:

```json
{
  "youtubeHandles": ["@GoogleDevelopers"],
  "maxItems": 20,
  "resultTypes": ["video", "short", "channel"]
}
```

Channel Shorts:

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/@GoogleDevelopers/shorts" }],
  "shortsMode": "only",
  "maxItems": 20
}
```

Playlist:

```json
{
  "startUrls": [
    { "url": "https://www.youtube.com/playlist?list=PL590L5WQmH8fJ54F369BLDSqIwcs-TCfs" }
  ],
  "maxItems": 20
}
```

Filtered search:

```json
{
  "keywords": ["robotics"],
  "gl": "US",
  "hl": "en",
  "uploadDate": "month",
  "duration": "long",
  "sort": "view_count",
  "minViews": 10000,
  "maxItems": 25
}
```

Monitoring:

```json
{
  "youtubeHandles": ["@GoogleDevelopers"],
  "maxItems": 20,
  "incrementalMode": true,
  "incrementalStateKey": "google-developers-weekly",
  "stopWhenKnownItemFound": true
}
```

Advanced output selection:

```json
{
  "keywords": ["web performance"],
  "maxItems": 20,
  "outputFormat": "flat",
  "fields": ["resultId", "title", "url", "views", "channel.name"]
}
```

### Important input behavior

- `maxItems` is a strict global count of accepted video and Short records. Filtered, failed, duplicate, channel, and playlist rows do not consume the cap.
- `maxItemsPerQuery`, `maxVideosPerChannel`, and `maxVideosPerPlaylist` are source caps; the global cap always wins.
- `distributionMode: "balanced"` rotates across sources. `"sequential"` completes sources in supplied order.
- `maxConcurrency: "auto"` backs off after rate limits and increases cautiously during stable batches. A number from 1 to 32 pins the ceiling.
- Native filters affect search discovery. Exact numeric/date/keyword filters are applied to normalized results from every source.
- `outputSort: "none"` streams with constant result memory. A sort mode buffers at most `maxItems` accepted rows.
- `customMapFunction` is intentionally disabled. Use `fields` or declarative `outputMapping`; arbitrary user code is never evaluated.

### Output contract

Primary records use `type: "video" | "short"` and `resultId: "youtube:video:<id>"`. Missing public metrics are `null`, not fabricated. When detail extraction fails but trustworthy discovery metadata exists, the Actor emits a labeled partial record instead of silently losing it.

Useful Dataset views:

- **Overview** for routine exports
- **Videos** for normalized video analytics
- **Channels** for public channel identity and performance fields
- **Search results** for query and position context
- **Shorts** for short-form research
- **Compatibility** for migrations
- **Full / technical** for source, caption, quality, and run metadata

The default Dataset can be exported as JSON, CSV, Excel, XML, or RSS through Apify storage APIs.

### Search and post-processing filters

Native search filters: `gl`, `hl`, `uploadDate`, `duration`, `features`, and `sort`.

Cross-source filters: `shortsMode`, duration/view/like/subscriber ranges, exact publish-date bounds, required keywords, excluded keywords, and `missingMetricBehavior`.

`searchQueries` permits per-query overrides:

```json
{
  "searchQueries": [
    {
      "query": "AI agents",
      "maxItems": 50,
      "gl": "US",
      "hl": "en",
      "uploadDate": "week",
      "sort": "view_count"
    },
    { "query": "n8n automation", "maxItems": 50 }
  ],
  "maxItems": 75
}
```

### Captions, transcripts, and temporary formats

`includeCaptions` stores public caption-track metadata. `transcriptMode` can be `none`, `text`, or `segments`, with `maxTranscriptCharacters` enforcing a per-video safety cap. `includeStreamingData` stores public technical format metadata only; returned URLs are temporary and this Actor is not a media downloader.

### Monitoring

Enable `incrementalMode`, choose a stable `incrementalStateKey`, and schedule the Actor. Stable IDs are checkpointed every 50 accepted results and at run completion. `stopWhenKnownItemFound` is useful for newest-first channel monitoring.

Typical flows:

- Apify Dataset → n8n → Google Sheets
- Scheduled Actor → new video → webhook → Slack
- Actor API → Make or Zapier → database/CRM

### API examples

#### cURL / REST

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~youtube-data-scraper-pro/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords":["robotics"],"maxItems":10}'
```

After the run finishes, retrieve its Dataset:

```bash
curl "https://api.apify.com/v2/datasets/YOUR_DATASET_ID/items?clean=true&format=json&token=YOUR_APIFY_TOKEN"
```

#### JavaScript

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('YOUR_USERNAME/youtube-data-scraper-pro').call({
  youtubeHandles: ['@GoogleDevelopers'],
  maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems({ clean: true });
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("YOUR_USERNAME/youtube-data-scraper-pro").call(run_input={
    "startUrls": [{"url": "https://www.youtube.com/shorts/jNQXAC9IVRw"}],
    "maxItems": 1,
})
items = client.dataset(run["defaultDatasetId"]).list_items(clean=True).items
print(items)
```

Never commit a real Apify token or private browsing cookie.

### Billing behavior

The intended PPE event is `video-result`. It fires only when one unique, accepted primary video/Short is successfully pushed. Duplicates, filtered candidates, failures, and supporting rows do not trigger that event. The implementation uses one dataset-plus-PPE path, so there is no second manual charge.

Pricing must not be published from a guess. See [PRICING.md](./PRICING.md) for the measured-cost gate and safety formula.

### Reliability and privacy

- Retries are error-aware; rate limits reduce automatic concurrency.
- One failing source is isolated from other mixed inputs.
- Secrets are not logged, saved in Dataset rows, or included in summaries.
- Contact extraction is limited to addresses and links already visible in public text. No reveal endpoint, login bypass, CAPTCHA bypass, or guessing is used.
- No `eval`, dynamic function execution, browser extension, or arbitrary remote crawling is present.

### Limitations

- Public YouTube data only; private, deleted, login-only, age-restricted, and region-blocked access is not promised.
- Public field availability varies, so some values are correctly returned as `null`.
- YouTube response changes can temporarily affect parsers.
- Caption and streaming URLs, when requested, can expire.
- Regional popular/trending behavior varies and fallback results are explicitly labeled.

This independent product is not affiliated with or endorsed by YouTube. Use public data in accordance with applicable laws and platform terms.

### Troubleshooting and support

If a source fails, check its sanitized error Dataset and `RUN_SUMMARY`; other mixed sources continue where possible. When reporting a problem, provide the run ID, input type, affected public URL, expected result, actual result, and a short non-secret log excerpt. Never share tokens, passwords, cookies, or proxy credentials.

See [FAQ.md](./FAQ.md) for short answers about sources, filters, scheduling, API use, null fields, billing, and partial failures.

### Local development

```bash
npm ci
npm run typecheck
npm run lint
npm test
npm run build
npm run validate:schemas
```

Live tests are opt-in:

```bash
LIVE_TESTS=true npm run test:actor
```

See [DEPLOYMENT.md](./DEPLOYMENT.md), [SECURITY.md](./SECURITY.md), [COMPATIBILITY.md](./COMPATIBILITY.md), and [CHANGELOG.md](./CHANGELOG.md).

# Changelog

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

# Actor input Schema

## `keywords` (type: `array`):

Keywords to search on YouTube. Works with the native country, language, upload date, duration, feature, and sort settings below.

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

Optional per-query settings. Each object requires query and may override maxItems, gl, hl, uploadDate, duration, features, and sort.

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

Two-letter country code used by YouTube search and the popular feed, for example US, TR, or DE.

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

YouTube interface/result language code, for example en, tr, de, pt-BR, or zh-CN.

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

Native search filter. Applies to keyword and search-URL discovery.

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

Native search duration filter. Exact seconds filters are available under Advanced filters.

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

Native search feature. It does not filter direct video URLs. CC maps to public subtitle/caption filtering.

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

Native YouTube search ordering.

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

Strict global cap for accepted video/Short results. Channel metadata, errors, and the run summary do not consume this cap.

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

Public video, youtu.be, Shorts, search, channel, channel /videos, channel /shorts, playlist, or live URLs. API clients may send URL strings or URL objects.

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

Channel handles such as @GoogleDevelopers or GoogleDevelopers.

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

Request YouTube's current public popular feed for the selected country. When no stable Trending feed is exposed, output is explicitly labeled popular\_fallback.

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

Auto recognizes every supplied source. A specific mode limits processing to that source family.

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

Legacy compatibility alias. Explicit Shorts mode below takes precedence.

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

Post-processing filter across all discovered video sources.

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

Post-processing filter for all videos.

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

Post-processing filter for all videos.

## `minLikes` (type: `integer`):

Post-processing filter; hidden like counts follow Missing metric behavior.

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

Post-processing filter when public subscriber count is available.

## `maxSubscribers` (type: `integer`):

Post-processing filter when public subscriber count is available.

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

Exact post-processing duration filter.

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

Exact post-processing duration filter.

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

Exact ISO date lower bound when publish date is available.

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

Exact ISO date upper bound when publish date is available.

## `mustContainKeywords` (type: `array`):

Every value must occur in title or description (case-insensitive).

## `mustNotContainKeywords` (type: `array`):

Reject results containing any value in title or description.

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

Keep results with unavailable public metrics, or skip them when a corresponding numeric filter is active.

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

Basic is lean; Standard includes normal metadata; Full enables extended structures when requested.

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

Choose primary video/Short records and optional supporting channel/playlist records.

## `includeDescription` (type: `boolean`):

Include public video descriptions.

## `includeChannelInfo` (type: `boolean`):

Include public channel identity and subscriber information when available.

## `includeCaptions` (type: `boolean`):

Include public caption track metadata; does not automatically fetch transcript text.

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

Optional transcript enrichment. Only publicly exposed transcripts are used; no access controls are bypassed.

## `maxTranscriptCharacters` (type: `integer`):

Safety cap per transcript; truncated outputs are labeled.

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

Optional temporary format metadata. URLs may expire and are not permanent download links.

## `includeThumbnails` (type: `boolean`):

Include public thumbnail variants and a best-thumbnail URL.

## `includeChapters` (type: `boolean`):

Include public video chapters in Full mode when available.

## `includeTags` (type: `boolean`):

Include public tags/keywords when available.

## `calculateViralScore` (type: `boolean`):

Adds a documented 0–100 derived heuristic; it is not an official YouTube metric.

## `channelAnalyticsSampleSize` (type: `integer`):

Maximum recent-video sample size for channel performance fields when public data permits calculation.

## `detectLanguage` (type: `boolean`):

Use lightweight script/keyword detection without a heavy model.

## `extractExternalLinks` (type: `boolean`):

Normalize and deduplicate URLs explicitly present in public text.

## `extractPublicContacts` (type: `boolean`):

Extract only emails and social/website URLs explicitly present in public text. No email reveal, guessing, login, or CAPTCHA bypass.

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

Nested JSON or flat dot-path fields for CSV, Sheets, and Airtable.

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

Reference keeps public contract aliases such as duration while retaining this product's original extended fields.

## `fields` (type: `array`):

Optional safe field picker using names such as title, url, views, or channel.name. Leave empty for all fields.

## `outputMapping` (type: `object`):

Optional declarative mapping, for example channelName to $.channel.name. Only safe dot paths are accepted; no code executes.

## `incrementalMode` (type: `boolean`):

Remember stored video IDs under the chosen state key and emit only new primary results.

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

Namespace that isolates state between Tasks or monitoring jobs.

## `stopWhenKnownItemFound` (type: `boolean`):

Useful for newest-first channel monitoring.

## `maxVideosPerChannel` (type: `integer`):

Per-channel discovery cap; global maxItems still wins.

## `maxVideosPerPlaylist` (type: `integer`):

Per-playlist discovery cap; global maxItems still wins.

## `maxItemsPerQuery` (type: `integer`):

Per-search cap; global maxItems still wins.

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

Balanced rotates between sources; sequential completes sources in their supplied order.

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

Merge preserves discovered source attribution when possible; duplicates are never billed twice.

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

Optional global sort. None streams results with constant memory; other choices buffer only the accepted maxItems records.

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

Use auto for adaptive concurrency (reduces after rate limits and cautiously increases while stable), or enter 1–32. Strict maxItems is serialized.

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

Optional Apify Proxy configuration. Credentials are never logged.

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

Optional encrypted public-browsing cookie. It is never logged and must not be used to bypass private, age, login, or other access controls.

## `saveErrors` (type: `boolean`):

Store sanitized per-source failures in a separate named Dataset.

## `debug` (type: `boolean`):

Log filter reasons without secrets or credentials.

## `dryRun` (type: `boolean`):

Discover and process without publishing or billing results. Experimental diagnostic option.

## `enableExperimentalFeatures` (type: `boolean`):

Reserved feature flag. Disabled by default and never changes core behavior unless explicitly enabled.

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

Disabled by design: arbitrary JavaScript is unsafe. Use Output fields or Safe output mapping.

## Actor input object example

```json
{
  "keywords": [
    "pixel art"
  ],
  "gl": "US",
  "hl": "en",
  "uploadDate": "all",
  "duration": "all",
  "features": "all",
  "sort": "relevance",
  "maxItems": 20,
  "getTrending": false,
  "mode": "auto",
  "includeShorts": true,
  "shortsMode": "include",
  "missingMetricBehavior": "keep",
  "detailLevel": "standard",
  "resultTypes": [
    "video",
    "short"
  ],
  "includeDescription": true,
  "includeChannelInfo": true,
  "includeCaptions": false,
  "transcriptMode": "none",
  "maxTranscriptCharacters": 100000,
  "includeStreamingData": false,
  "includeThumbnails": true,
  "includeChapters": true,
  "includeTags": true,
  "calculateViralScore": false,
  "channelAnalyticsSampleSize": 10,
  "detectLanguage": false,
  "extractExternalLinks": false,
  "extractPublicContacts": false,
  "outputFormat": "nested",
  "compatibilityMode": "none",
  "incrementalMode": false,
  "incrementalStateKey": "default",
  "stopWhenKnownItemFound": false,
  "distributionMode": "balanced",
  "duplicateStrategy": "merge",
  "outputSort": "none",
  "maxConcurrency": "auto",
  "saveErrors": true,
  "debug": false,
  "dryRun": false,
  "enableExperimentalFeatures": false
}
```

# Actor output Schema

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

Accepted public YouTube results in the default Dataset.

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

Counts, source statistics, performance, warnings, and billing observability.

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

Requested workload and optional enrichments without an unreliable up-front price promise.

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

Run output and optional incremental state records.

# 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 = {
    "keywords": [
        "pixel art"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mfttt11/youtube-data-scraper-pro").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 = { "keywords": ["pixel art"] }

# Run the Actor and wait for it to finish
run = client.actor("mfttt11/youtube-data-scraper-pro").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 '{
  "keywords": [
    "pixel art"
  ]
}' |
apify call mfttt11/youtube-data-scraper-pro --silent --output-dataset

```

## MCP server setup

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

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/Bifadww2T5KBgJzsM/builds/VzmTBfs6Aai0sEaxJ/openapi.json
