# Youtube Transcript Scraper - $0.7 per 1k (`supreme_coder/youtube-transcript-scraper`) Actor

Scrape youtube videos and transcripts in bulk from channels, youtube search, playlists, etc. Provides videos details and transcript in different formats

- **URL**: https://apify.com/supreme_coder/youtube-transcript-scraper.md
- **Developed by:** [Supreme Coder](https://apify.com/supreme_coder) (community)
- **Categories:** AI, Agents, Videos
- **Features:** Limited permissions
- **Stats:** 4,387 total users, 1,554 monthly users, 96.7% runs succeeded, 32 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.70 / 1,000 transcript 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

The most reliable YouTube transcript extractor on Apify. Extract transcripts, subtitles, and captions from YouTube videos in seconds — with built-in proxy rotation, multi-language support, and multiple output formats. Works with regular videos, Shorts, and auto-generated captions.

Feed it individual videos, an entire **channel**, a **playlist**, or just a **search keyword** — the actor finds the videos and returns their transcripts in one run.

### Features

There are 20+ YouTube transcript scrapers on Apify. Here's why this one stands out:

- **Scrape entire channels, playlists, and searches** — Don't have a list of video URLs? Just paste a channel or playlist URL, or type a search keyword. The actor finds the matching videos for you and returns their transcripts — no separate video scraper needed
- **Doesn't break when YouTube changes** — Most transcript actors broke for days or even weeks during YouTube's backend changes in Dec 2025 and Jan 2026. This actor is built for resilience with fast recovery
- **Clear errors, not empty results** — Other actors silently return null/empty when something goes wrong. This actor tells you exactly what happened: no captions available, video age-restricted, IP blocked, or video removed, Also scrapes 100% of transcripts from video urls when available publicly
- **Built-in proxy management** — Many actors fail on free-tier because they use bad proxies that YouTube blocks instantly. This actor selects and rotates through best proxies automatically — no configuration needed
- **4 output formats** — Most actors only output JSON. This one supports JSON (with timestamps), plain text (for AI/LLM pipelines), SRT (for video editors), and WebVTT (for web players)
- **Actual multi-language support** — Several competing actors claim language support but default to English only or have broken language parameters. This actor supports priority-based language fallback and YouTube's built-in translation
- **Rich metadata included** — Many actors return only the transcript. This one includes title, description, keywords, channel name, view count, duration, thumbnails, and more — no need for a separate metadata scraper
- **Handles all URL formats** — Other actors choke on `youtu.be` short links or `/shorts/` URLs. This actor handles all standard YouTube URL formats
- **State persistence for large batches** — Long-running jobs survive Apify platform migrations without losing progress. Other actors often timeout or OOM on large batches

### Input Configuration

Provide at least one source: a list of `urls` (videos, Shorts, channels, or playlists) and/or one or more `searchKeywords`.

#### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `urls` | Array | — | Any mix of YouTube URLs. Video and Shorts URLs are scraped directly; channel and playlist URLs are expanded into their videos automatically |
| `searchKeywords` | Array | — | One or more search terms. The actor scrapes transcripts from the top matching videos for each keyword |
| `maxPagesPerUrl` | Integer | *unlimited* | How many pages of results to fetch from each channel, playlist, or search URL. Each page is a batch of videos, so a higher number scrapes more videos per URL. Leave empty for unlimited (fetch every page). Only pages that contain videos count toward this limit. Does not affect direct video/Shorts URLs (those are always scraped) |
| `scrapeShorts` | Boolean | `false` | When expanding channels, playlists, or searches, also include Shorts. When off, only regular videos are scraped |
| `outputFormat` | String | `json` | Output format: `json`, `text`, `srt`, or `vtt` |
| `languages` | Array | `["en"]` | Language codes in priority order (e.g., `["es", "en", "fr"]`). The actor tries each language in order and uses the first available transcript |
| `translateTo` | String | — | Translate the transcript to this language code (e.g., `"es"` for Spanish). Uses YouTube's built-in translation |
| `preserveFormatting` | Boolean | `false` | Keep HTML formatting tags (bold, italic, etc.) in transcript text |

#### Supported URL Formats

| Format | Example | Behavior |
|--------|---------|----------|
| Standard watch URL | `https://www.youtube.com/watch?v=VIDEO_ID` | Scraped directly |
| Short URL | `https://youtu.be/VIDEO_ID` | Scraped directly |
| Shorts | `https://www.youtube.com/shorts/VIDEO_ID` | Scraped directly |
| Channel | `https://www.youtube.com/@HANDLE` | Expanded into the channel's videos |
| Channel (ID) | `https://www.youtube.com/channel/CHANNEL_ID` | Expanded into the channel's videos |
| Playlist | `https://www.youtube.com/playlist?list=PLAYLIST_ID` | Expanded into the playlist's videos |

### Usage Examples

#### Basic — Extract English Transcript

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

#### Plain Text Output (No Timestamps)

Perfect for feeding into AI/LLM pipelines, summarization tools, or text analysis:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
  ],
  "outputFormat": "text"
}
```

#### Multi-Language with Fallback

Request Spanish first, fall back to English, then French:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
  ],
  "languages": ["es", "en", "fr"]
}
```

#### Translate Transcript

Get the transcript translated to Japanese using YouTube's built-in translation:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
  ],
  "translateTo": "ja"
}
```

#### SRT Subtitles for Video Editing

Export transcripts in SRT format for use in video editors like Premiere Pro, DaVinci Resolve, or Final Cut:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
  ],
  "outputFormat": "srt"
}
```

#### Batch Processing — Multiple Videos

Process multiple videos in one run. The actor handles state persistence, so even large batches survive migrations:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=VIDEO1" },
    { "url": "https://www.youtube.com/watch?v=VIDEO2" },
    { "url": "https://youtu.be/VIDEO3" },
    { "url": "https://www.youtube.com/shorts/VIDEO4" }
  ],
  "outputFormat": "json",
  "languages": ["en"]
}
```

#### Scrape an Entire Channel

Paste a channel URL and the actor pulls transcripts from its videos. Use `maxPagesPerUrl` to fetch more pages of videos:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/@mkbhd" }
  ],
  "maxPagesPerUrl": 3
}
```

You can also use a channel ID URL (`https://www.youtube.com/channel/CHANNEL_ID`).

#### Scrape an Entire Playlist

Grab transcripts from the videos in a playlist. Raise `maxPagesPerUrl` to go deeper into long playlists:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/playlist?list=PLBkiWvdL-IJa8NvXNuJpKiUEwQ5UHHw8t" }
  ],
  "maxPagesPerUrl": 5
}
```

#### Scrape by Search Keyword

Type a keyword and the actor scrapes transcripts from the top matching videos. You can pass several keywords at once:

```json
{
  "searchKeywords": ["lo-fi hip hop", "morning routine"],
  "maxPagesPerUrl": 2
}
```

> **Tip:** You can also paste a full YouTube search URL (including its filters, e.g. `&sp=...` for "this month" or "videos only") directly into `urls` — the filters are respected.

#### Include Shorts

By default only regular videos are scraped. Turn on `scrapeShorts` to also include Shorts when expanding channels, playlists, and searches:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/@mkbhd" }
  ],
  "maxPagesPerUrl": 3,
  "scrapeShorts": true
}
```

#### Mix Everything in One Run

Combine direct videos, channels, playlists, and search keywords in a single run:

```json
{
  "urls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
    { "url": "https://www.youtube.com/@mkbhd" },
    { "url": "https://www.youtube.com/playlist?list=PLBkiWvdL-IJa8NvXNuJpKiUEwQ5UHHw8t" }
  ],
  "searchKeywords": ["productivity tips"],
  "maxPagesPerUrl": 2,
  "outputFormat": "text"
}
```

### Output

#### JSON Format (Default)

Each video produces a dataset item with transcript data and full video metadata:

```json
{
  "inputUrl": "https://www.youtube.com/watch?v=neabI31ofMc",
  "videoUrl": "https://www.youtube.com/watch?v=neabI31ofMc",
  "language": "English (auto-generated)",
  "languageCode": "en",
  "isGenerated": true,
  "transcript": [
    {
      "text": "today I'm going to show you all the",
      "start": 0.04,
      "duration": 3.359
    },
    {
      "text": "things that can help suppress your",
      "start": 1.36,
      "duration": 4.64
    }
  ],
  "snippetCount": 185,
  "videoDetails": {
    "videoId": "neabI31ofMc",
    "title": "BETTER Than Ozempic! STOP Your Cravings",
    "lengthSeconds": "412",
    "keywords": ["appetite suppressant", "natural appetite suppressants", "..."],
    "channelId": "UC3w193M5tYPJqF0Hi-7U-2g",
    "shortDescription": "Avoiding cravings is not up to sheer willpower...",
    "thumbnail": {
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi_webp/neabI31ofMc/sddefault.webp", "width": 640, "height": 480 }
      ]
    },
    "viewCount": "1088282",
    "author": "Dr. Eric Berg DC",
    "isLiveContent": false
  }
}
```

**`inputUrl` vs `videoUrl`:** `videoUrl` is always the actual video's watch URL. `inputUrl` is the source you provided — for a direct video URL these match, but for videos discovered from a **channel, playlist, or search**, `inputUrl` is the channel/playlist/search URL they came from, so you can always trace each transcript back to its source.

#### Text Format

Returns the full transcript as a single plain-text string — no timestamps, no JSON nesting. Ideal for AI processing.

#### SRT Format

Standard SubRip subtitle format, ready for video editors and subtitle players:

```
1
00:00:00,040 --> 00:00:03,399
today I'm going to show you all the

2
00:00:01,360 --> 00:00:06,000
things that can help suppress your
```

#### WebVTT Format

Web Video Text Tracks format for HTML5 video players and web applications:

```
WEBVTT

00:00:00.040 --> 00:00:03.399
today I'm going to show you all the

00:00:01.360 --> 00:00:06.000
things that can help suppress your
```

### Related YouTube Scrapers

For extracting video metadata including titles, descriptions, view counts, and engagement metrics, use the [YouTube Video Scraper](https://apify.com/supreme_coder/youtube-scraper). To collect comments from YouTube videos and shorts, the [YouTube Comment Scraper](https://apify.com/supreme_coder/youtube-comment-scraper) extracts complete comment details including author information, likes, and replies.

### Error Handling

The actor provides clear, specific error codes so you always know what happened:

| Error Code | Meaning | What to Do |
|------------|---------|------------|
| `TranscriptNotFound` | No captions/subtitles available for this video in the requested languages | Try different language codes, or check if the video has captions enabled |
| `URL_NOT_SUPPORTED` | The provided URL is not a valid YouTube video URL | Use a standard YouTube video URL format (see Supported URL Formats above) |
| `VIDEO_ID_NOT_FOUND` | Could not extract a video ID from the URL | Check that the URL contains a valid video ID |
| `AgeRestricted` | Video is age-restricted and requires authentication | Age-restricted videos cannot be scraped without login |
| `VideoUnavailable` | Video has been removed or is no longer available | The video no longer exists on YouTube |
| `IpBlocked` | YouTube is blocking requests from this IP | Usually temporary — retry later or the actor's proxy rotation will handle it |
| `NO_VIDEOS_FOUND` | A channel, playlist, or search keyword returned no videos | Check the channel/playlist URL or try a different keyword |
| `SOURCE_EXPANSION_FAILED` | The channel, playlist, or search could not be listed | Usually temporary — retry later; verify the URL is public and correct |

**Note:** When a video genuinely has no captions (common with music videos, some Shorts, and older content), the actor returns a clear `TranscriptNotFound` error rather than an empty result.

### Proxy Support

The actor includes built-in residential proxy rotation — no configuration needed. This handles YouTube's aggressive IP blocking automatically. You don't need to provide your own proxies.

### Language Codes

The actor supports any language code that YouTube supports. Common codes:

| Code | Language | Code | Language |
|------|----------|------|----------|
| `en` | English | `ko` | Korean |
| `es` | Spanish | `zh` | Chinese |
| `fr` | French | `ar` | Arabic |
| `de` | German | `hi` | Hindi |
| `it` | Italian | `ja` | Japanese |
| `pt` | Portuguese | `ru` | Russian |

**Tip:** Use the `languages` parameter with multiple codes to set up automatic fallback. The actor tries each language in order and uses the first transcript it finds.

### Integration Examples

#### n8n / Make.com

This actor works with Apify's official integrations for [n8n](https://docs.apify.com/platform/integrations/n8n) and [Make.com](https://www.make.com/en/register?pc=growthhack). Use the **Run Actor** module with the input schema above.

#### API

Access transcripts programmatically via the [YouTube Transcript Scraper API](https://apify.com/supreme_coder/youtube-transcript-scraper/api/endpoints). Results are stored in a dataset that you can export as JSON, CSV, XML, or other formats.

```bash
## Start a run via API
curl -X POST "https://api.apify.com/v2/acts/supreme_coder~youtube-transcript-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [{ "url": "https://www.youtube.com/watch?v=VIDEO_ID" }],
    "outputFormat": "text"
  }'
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("supreme_coder/youtube-transcript-scraper").call(
    run_input={
        "urls": [{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}],
        "outputFormat": "text",
        "languages": ["en"]
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["transcript"])
```

### Pricing

This scraper costs approximately **$0.30 per 1,000 YouTube transcripts**. With the Apify Starter plan, you can extract up to ~16,000 transcripts per month.

### Limitations

- Videos without captions/subtitles cannot be transcribed (the actor extracts existing captions, not audio)
- Age-restricted videos require authentication and are not currently supported
- Translation availability depends on what YouTube offers for each specific video
- Very long videos (3+ hours) may require higher memory allocation

### Is It Legal to Scrape YouTube?

Our scrapers are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our scrapers, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the [GDPR](https://docs.apify.com/academy/get-most-of-actors/actor-readme#:~:text=protected%20by%20the-,GDPR,-in%20the%20European) in the European Union and by other regulations around the world.

You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers. You can also read our blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Related Actors

- [YouTube Comment Scraper](https://apify.com/supreme_coder/youtube-comment-scraper) — Extract comments from YouTube videos

### Feedback

We're always working on improving the performance of our actors. If you've got any technical feedback or found a bug, please create an issue on the actor's [Issues](https://apify.com/supreme_coder/youtube-transcript-scraper/issues) tab in Apify Console.

# Changelog

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

# Actor input Schema

## `urls` (type: `array`):

Paste any mix of YouTube URLs. Video and Shorts URLs are scraped directly; Channel and Playlist URLs are expanded into their videos automatically (use "Max pages per URL" to fetch more).

## `searchKeywords` (type: `array`):

Search YouTube for each keyword and scrape transcripts from the top results. Use "Max pages per URL" to fetch more pages of results per keyword.

## `maxPagesPerUrl` (type: `integer`):

How many pages of results to fetch from each channel, playlist, or search URL. Each page is a batch of videos, so a higher number scrapes more videos per URL. Leave empty for unlimited (fetch every page until the listing runs out). Only pages that contain videos count toward this limit. Has no effect on direct video/Shorts URLs (those are always scraped).

## `scrapeShorts` (type: `boolean`):

When expanding channels, playlists, or search keywords, also include Shorts. When off, Shorts are skipped and only regular videos are scraped.

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

Output format for the transcripts

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.youtube.com/watch?v=5AdKqkNmJj4"
    },
    {
      "url": "https://www.youtube.com/watch?v=iTOAIP9DfYo"
    },
    {
      "url": "https://www.youtube.com/watch?v=pJ9xTMkGxXg"
    },
    {
      "url": "https://www.youtube.com/watch?v=bksYSwtJVM0"
    },
    {
      "url": "https://www.youtube.com/watch?v=Sn7T46fCjLE"
    },
    {
      "url": "https://www.youtube.com/watch?v=zW8Cu4vcReY"
    },
    {
      "url": "https://www.youtube.com/watch?v=K1whvDMDogU"
    },
    {
      "url": "https://www.youtube.com/watch?v=xEg9b3YPJj0"
    },
    {
      "url": "https://www.youtube.com/watch?v=23yNXtR-N1s"
    },
    {
      "url": "https://www.youtube.com/watch?v=CvBR-GoBvzk"
    }
  ],
  "searchKeywords": [],
  "scrapeShorts": false,
  "outputFormat": "json"
}
```

# 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 = {
    "urls": [
        {
            "url": "https://www.youtube.com/watch?v=5AdKqkNmJj4"
        },
        {
            "url": "https://www.youtube.com/watch?v=iTOAIP9DfYo"
        },
        {
            "url": "https://www.youtube.com/watch?v=pJ9xTMkGxXg"
        },
        {
            "url": "https://www.youtube.com/watch?v=bksYSwtJVM0"
        },
        {
            "url": "https://www.youtube.com/watch?v=Sn7T46fCjLE"
        },
        {
            "url": "https://www.youtube.com/watch?v=zW8Cu4vcReY"
        },
        {
            "url": "https://www.youtube.com/watch?v=K1whvDMDogU"
        },
        {
            "url": "https://www.youtube.com/watch?v=xEg9b3YPJj0"
        },
        {
            "url": "https://www.youtube.com/watch?v=23yNXtR-N1s"
        },
        {
            "url": "https://www.youtube.com/watch?v=CvBR-GoBvzk"
        }
    ],
    "searchKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("supreme_coder/youtube-transcript-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 = {
    "urls": [
        { "url": "https://www.youtube.com/watch?v=5AdKqkNmJj4" },
        { "url": "https://www.youtube.com/watch?v=iTOAIP9DfYo" },
        { "url": "https://www.youtube.com/watch?v=pJ9xTMkGxXg" },
        { "url": "https://www.youtube.com/watch?v=bksYSwtJVM0" },
        { "url": "https://www.youtube.com/watch?v=Sn7T46fCjLE" },
        { "url": "https://www.youtube.com/watch?v=zW8Cu4vcReY" },
        { "url": "https://www.youtube.com/watch?v=K1whvDMDogU" },
        { "url": "https://www.youtube.com/watch?v=xEg9b3YPJj0" },
        { "url": "https://www.youtube.com/watch?v=23yNXtR-N1s" },
        { "url": "https://www.youtube.com/watch?v=CvBR-GoBvzk" },
    ],
    "searchKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("supreme_coder/youtube-transcript-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 '{
  "urls": [
    {
      "url": "https://www.youtube.com/watch?v=5AdKqkNmJj4"
    },
    {
      "url": "https://www.youtube.com/watch?v=iTOAIP9DfYo"
    },
    {
      "url": "https://www.youtube.com/watch?v=pJ9xTMkGxXg"
    },
    {
      "url": "https://www.youtube.com/watch?v=bksYSwtJVM0"
    },
    {
      "url": "https://www.youtube.com/watch?v=Sn7T46fCjLE"
    },
    {
      "url": "https://www.youtube.com/watch?v=zW8Cu4vcReY"
    },
    {
      "url": "https://www.youtube.com/watch?v=K1whvDMDogU"
    },
    {
      "url": "https://www.youtube.com/watch?v=xEg9b3YPJj0"
    },
    {
      "url": "https://www.youtube.com/watch?v=23yNXtR-N1s"
    },
    {
      "url": "https://www.youtube.com/watch?v=CvBR-GoBvzk"
    }
  ],
  "searchKeywords": []
}' |
apify call supreme_coder/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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