# YouTube Scraper (Videos, Comments, Transcripts) (`solidscrape/youtube-scraper`) Actor

Scrape YouTube without an API key: video metadata, comments, and transcripts/captions by video URL, video ID, or keyword search. Uses YouTube's InnerTube endpoints. Export JSON/CSV/Excel.

- **URL**: https://apify.com/solidscrape/youtube-scraper.md
- **Developed by:** [Shahryar](https://apify.com/solidscrape) (community)
- **Categories:** Videos, Social media
- **Stats:** 6 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Scraper – Videos, Comments & Transcripts (No API Key)

**YouTube Scraper** extracts structured data from **YouTube** without an API key or login: **video metadata**, **comments** (with replies), and **transcripts/captions** — by video URL, video ID, or keyword search. Export to **JSON, CSV, or Excel**.

This is a no-API-key **YouTube comments API**, **YouTube transcript scraper**, and video-metadata scraper in one Actor. Built for **content researchers, marketers, data teams, and creators** who need YouTube data at scale without the official Data API's quota limits.

### What it does

- 🎬 **Video metadata** – title, description, channel name/ID/URL, view count, approximate like count, publish/upload date, duration, category, tags/keywords, thumbnails, and the list of available caption languages.
- 💬 **Comments** – author, text, like count, reply count, relative published time, pinned/hearted flags, and an avatar URL. Optionally expand reply threads.
- 📝 **Transcripts** – full transcript text plus timestamped segments, for manual or auto-generated captions, in your preferred language. Best-effort (see FAQ).
- 🔎 **Keyword search** – run a YouTube video search and automatically enrich every matching video.
- 🌍 **Language control** – pick the caption language and prefer human captions over auto-generated ones.
- 📤 **Export anywhere** – download the dataset as **JSON, CSV, or Excel**, or pull it via the Apify API.

### Why this scraper

- **No API key, no login, no quota.** Uses YouTube's internal **InnerTube** endpoints (the same JSON APIs the website calls), reading the live client config from the watch page so the client version is never stale.
- **Honest transcripts.** Captions are gated by YouTube; this Actor uses the most reliable path available (InnerTube `get_transcript` via the iOS client, with a timedtext fallback) and is transparent about when a transcript can't be obtained.
- **Built for reliability.** Residential proxy by default, fresh proxy session per video, retries with jitter, and resumable state so a restarted run does not refetch finished videos.
- **One Actor, four data types.** Every record carries a `type` field (`video`, `comment`, `transcript`, `searchResult`) so you can split the dataset cleanly.
- **Pairs with our other scrapers** for social/video data (TikTok, Instagram, Reddit, and more) when you need cross-platform coverage.

### How it works (and why it's reliable)

1. **Seed** – fetches the watch page once per video and extracts the live `INNERTUBE` config plus the initial comments token.
2. **Metadata** – read straight from the player response (no extra request).
3. **Transcript** – resolves the caption track list (language + manual/auto) from the mobile `player` response, then fetches the text in two stages:

   - **Primary:** the InnerTube `get_transcript` (transcript-panel) endpoint, called with the **iOS** mobile client. The `params` is a base64-protobuf built from the video ID + chosen track; this endpoint still returns segment text where the plain caption URL does not.
   - **Fallback:** the timedtext caption `baseUrl` (`fmt=json3`). The desktop/web client returns empty caption bodies (`exp=xpe` / PoToken gate), so mobile clients are used on purpose, but even mobile caption URLs can be gated on some IPs.

   Transcripts are therefore **best-effort**: when both paths are gated for a given video/IP, no transcript item is emitted (the video and comments are unaffected). A **residential proxy** materially improves the hit rate.
4. **Comments** – paginates the InnerTube `next` endpoint, joining the thread structure with the `frameworkUpdates` entity payloads to recover the real text/author/likes.

> ⚠️ **Use a residential proxy.** YouTube rate-limits datacenter IPs quickly (HTTP 429s and empty responses), especially for comment pagination. The default proxy group is `RESIDENTIAL` for this reason — and residential bandwidth is the main cost driver of a run.

### Example input

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "searchQueries": ["lofi hip hop"],
  "maxResultsPerSearch": 25,
  "scrapeVideoMetadata": true,
  "scrapeTranscript": true,
  "scrapeComments": true,
  "maxComments": 100,
  "includeCommentReplies": false,
  "commentsSortBy": "top",
  "language": "en",
  "preferManualCaptions": true,
  "emitSearchResults": false,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Example output

Each item carries a `type` field so you can split the dataset by record type. A video that is private, members-only, age-restricted, region-blocked, or not playable is emitted as a `type: "skipped"` item (with a `reason`) instead of crashing the run.

**Video** (`type: "video"`)

```json
{
  "type": "video",
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
  "description": "The official video for \"Never Gonna Give You Up\" by Rick Astley...",
  "channelName": "Rick Astley",
  "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
  "viewCount": 1600000000,
  "likeCount": 17000000,
  "publishDate": "2009-10-25",
  "uploadDate": "2009-10-25",
  "durationSeconds": 212,
  "category": "Music",
  "keywords": ["rick astley", "never gonna give you up"],
  "isLiveContent": false,
  "isFamilySafe": true,
  "thumbnails": [{ "url": "https://i.ytimg.com/...", "width": 1280, "height": 720 }],
  "availableCaptionLanguages": [{ "languageCode": "en", "name": "English", "isAutoGenerated": false }],
  "commentCountApprox": 2200000,
  "foundViaQuery": null,
  "scrapedAt": "2026-06-26T10:00:00.000Z"
}
```

**Transcript** (`type: "transcript"`)

```json
{
  "type": "transcript",
  "videoId": "dQw4w9WgXcQ",
  "language": "en",
  "isAutoGenerated": false,
  "trackName": "English",
  "fullText": "We're no strangers to love ...",
  "segments": [{ "start": 18.5, "dur": 3.2, "text": "We're no strangers to love" }],
  "scrapedAt": "2026-06-26T10:00:00.000Z"
}
```

**Comment** (`type: "comment"`)

```json
{
  "type": "comment",
  "videoId": "dQw4w9WgXcQ",
  "commentId": "UgxKREWxIgDrw8w2e_Z4AaABAg",
  "text": "Still a banger in 2026.",
  "authorName": "@someuser",
  "authorChannelId": "UCabc...",
  "authorChannelUrl": "https://www.youtube.com/channel/UCabc...",
  "authorThumbnail": "https://yt3.ggpht.com/...",
  "likeCount": 1200,
  "replyCount": 8,
  "publishedTimeText": "3 weeks ago",
  "isPinned": false,
  "isHearted": false,
  "isReply": false,
  "parentCommentId": null,
  "scrapedAt": "2026-06-26T10:00:00.000Z"
}
```

**Search result** (`type: "searchResult"`, only when **Also emit raw search results** is enabled)

```json
{
  "type": "searchResult",
  "query": "lofi hip hop",
  "videoId": "jfKfPfyJRdk",
  "url": "https://www.youtube.com/watch?v=jfKfPfyJRdk",
  "title": "lofi hip hop radio",
  "channelName": "Lofi Girl",
  "channelId": "UCSJ4gkVC6NrvII8umztf0Ow",
  "viewCountText": "Streaming",
  "publishedTimeText": null,
  "lengthText": null,
  "thumbnails": [{ "url": "https://i.ytimg.com/...", "width": 360, "height": 202 }],
  "scrapedAt": "2026-06-26T10:00:00.000Z"
}
```

### Output fields

**Video** (`type: "video"`)

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `"video"`. |
| `videoId` | string | 11-character video ID. |
| `url` | string | Canonical watch URL. |
| `title` | string | Video title. |
| `description` | string | Full description text. |
| `channelName` | string | Channel (author) name. |
| `channelId` | string | Channel ID. |
| `channelUrl` | string | Channel URL. |
| `viewCount` | integer | Total views (nullable). |
| `likeCount` | integer | Approximate like count from the watch UI (nullable; YouTube does not expose an exact number). |
| `publishDate` | string | Publish date from microformat (nullable). |
| `uploadDate` | string | Upload date from microformat (nullable). |
| `durationSeconds` | integer | Duration in seconds (nullable). |
| `category` | string | Video category (nullable). |
| `keywords` | array | Tags array (may be empty). |
| `isLiveContent` | boolean | Whether the video is/was live (nullable). |
| `isFamilySafe` | boolean | Family-safe flag (nullable). |
| `thumbnails` | array | Array of `{ url, width, height }`. |
| `availableCaptionLanguages` | array | Array of `{ languageCode, name, isAutoGenerated }`. |
| `commentCountApprox` | integer | Approximate comment count from the header (nullable). |
| `foundViaQuery` | string | The search query that surfaced this video (only present for videos discovered via `searchQueries`). |
| `scrapedAt` | string | ISO 8601 timestamp. |

**Transcript** (`type: "transcript"`)

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `"transcript"`. |
| `videoId` | string | Video ID. |
| `language` | string | Caption language code (nullable). |
| `isAutoGenerated` | boolean | `true` for auto (ASR) captions. |
| `trackName` | string | Human-readable track name (nullable). |
| `fullText` | string | All segments joined into one string. |
| `segments` | array | Array of `{ start, dur, text }` (seconds as floats; `start`/`dur` may be null). |
| `scrapedAt` | string | ISO 8601 timestamp. |

**Comment** (`type: "comment"`)

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `"comment"`. |
| `videoId` | string | Video the comment belongs to. |
| `commentId` | string | Comment ID. |
| `text` | string | Comment body. |
| `authorName` | string | Author handle / display name. |
| `authorChannelId` | string | Author channel ID (nullable). |
| `authorChannelUrl` | string | Author channel URL (nullable). |
| `authorThumbnail` | string | Author avatar URL (nullable). |
| `likeCount` | integer | Like count (defaults to 0 when not shown). |
| `replyCount` | integer | Reply count (defaults to 0). |
| `publishedTimeText` | string | Relative time string (e.g. "3 weeks ago"); YouTube does not expose absolute comment dates. |
| `isPinned` | boolean | Whether the comment is pinned. |
| `isHearted` | boolean | Whether the creator hearted it. |
| `isReply` | boolean | `true` for replies. |
| `parentCommentId` | string | Parent comment ID (null for top-level). |
| `scrapedAt` | string | ISO 8601 timestamp. |

**Search result** (`type: "searchResult"`)

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `"searchResult"`. |
| `query` | string | The search query that matched. |
| `videoId` | string | Video ID. |
| `url` | string | Watch URL. |
| `title` | string | Video title. |
| `channelName` | string | Channel name (nullable). |
| `channelId` | string | Channel ID (nullable). |
| `viewCountText` | string | View-count display string from the search card (nullable). |
| `publishedTimeText` | string | Relative publish-time display string (nullable). |
| `lengthText` | string | Duration display string (nullable). |
| `thumbnails` | array | Array of `{ url, width, height }`. |
| `scrapedAt` | string | ISO 8601 timestamp. |

**Skipped** (`type: "skipped"`)

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `"skipped"`. |
| `videoId` | string | Video ID that could not be scraped. |
| `url` | string | Watch URL. |
| `reason` | string | Why it was skipped (e.g. `LOGIN_REQUIRED`, `AGE_VERIFICATION_REQUIRED`, `no_video_details`, `watch_fetch_failed: ...`). |
| `scrapedAt` | string | ISO 8601 timestamp. |

### Input reference

| Field | Type | Default | Description |
|---|---|---|---|
| `videoUrls` | array | – | YouTube watch URLs (`watch?v=`, `youtu.be/`, `/shorts/`, `/embed/`, `/live/`). Normalized to the 11-char ID. |
| `videoIds` | array | – | Raw 11-character video IDs. |
| `searchQueries` | array | – | Keyword search strings (videos only); matches are enriched like direct inputs. |
| `maxResultsPerSearch` | integer | 50 | Max videos per search query (pagination stops once reached). |
| `scrapeVideoMetadata` | boolean | true | Emit `type: "video"` items. |
| `scrapeTranscript` | boolean | true | Fetch transcript/captions (best-effort). |
| `scrapeComments` | boolean | false | Fetch comments (slowest, most rate-limited path). |
| `maxComments` | integer | 100 | Max top-level comments per video; 0 = unlimited. |
| `includeCommentReplies` | boolean | false | Also expand reply threads. |
| `commentsSortBy` | string | top | `"top"` or `"newest"`. |
| `language` | string | en | Preferred caption language code; also sets the InnerTube `hl` locale. |
| `preferManualCaptions` | boolean | true | Prefer human captions over auto-generated. |
| `emitSearchResults` | boolean | false | Also push raw `type: "searchResult"` items for searches. |
| `proxyConfiguration` | object | RESIDENTIAL | Apify proxy; RESIDENTIAL strongly recommended (and the default). |

### Common use cases

- **Transcript mining** – pull YouTube transcripts for summarization, search, or LLM/RAG pipelines.
- **Comment & sentiment analysis** – export top or newest comments (and replies) as a YouTube comments API for NLP and analysis.
- **Channel & topic research** – search a keyword and collect metadata across many videos at once.
- **Content monitoring** – track view counts, approximate likes, and comment volume over time.
- **Competitor & market research** – build datasets from competitor channels and export to JSON/CSV/Excel.

### FAQ

**Do I need a YouTube/Google API key?** No. This YouTube scraper uses YouTube's internal InnerTube endpoints — no API key, no OAuth, no quota.

**Why are some transcripts missing?** Transcripts are best-effort. Not every video has captions, and some only have auto-generated ones. YouTube also gates caption text behind PoToken/IP checks: the Actor first tries the InnerTube `get_transcript` panel endpoint via the iOS client (which still returns text on mobile clients) and falls back to the timedtext caption URL, but on a gated video/IP combination both can come back empty — in that case the video and comments are still scraped, just without a transcript. A residential proxy improves the YouTube transcript hit rate.

**Why are comments slow, and why do they need a proxy?** Comments are the slowest, most rate-limited path: the Actor paginates the InnerTube `next` endpoint one page at a time with jitter to stay under YouTube's limits, so a video with many comments takes proportionally longer. Datacenter IPs get 429s and empty responses quickly, so a residential proxy is strongly recommended when scraping comments at volume. Comments are off by default for this reason.

**Why do I need a residential proxy, and what does it cost?** Datacenter IPs get rate-limited (429s) and served empty responses, especially during comment pagination, so the default proxy group is `RESIDENTIAL`. Residential proxy bandwidth is the main cost driver of a run — fetching watch pages, comments, and transcripts all consume residential traffic — so scope your `maxComments` and `maxResultsPerSearch` to control spend.

**Which languages are supported?** Any language YouTube has a caption track for. Set `language` to a language code (e.g. `en`, `es`, `de`, `fr`, `pt`, `hi`, `ja`) to pick the caption track and the InnerTube `hl` locale; if that exact track is missing, the scraper falls back to another track or an auto-generated one. `preferManualCaptions` controls whether human captions win over ASR.

**How are limits and pagination handled?** `maxResultsPerSearch` caps videos per search query, and `maxComments` caps top-level comments per video (`0` = unlimited). Search and comments paginate automatically until the limit is hit or YouTube stops returning a continuation. Runs are resumable: a restarted run skips videos it already finished.

**What export formats are available?** The dataset can be exported to **JSON, CSV, or Excel** (also XML, JSONL, RSS, or HTML table) from the Apify Console, or fetched programmatically via the Apify API.

***

This YouTube scraper pairs well with our other social and video scrapers (TikTok, Instagram, Reddit, and more) when you need cross-platform data.

# Actor input Schema

## `videoUrls` (type: `array`):

YouTube watch URLs to scrape. Accepts watch?v=, youtu.be/, /shorts/ and /embed/ forms; each is normalized to its 11-character video ID. You can paste plain strings or { "url": "..." } objects.

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

Raw 11-character YouTube video IDs to scrape directly, e.g. "dQw4w9WgXcQ" (alternative to Video URLs).

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

Keyword search strings. Each runs a YouTube search (videos only); matched videos are then enriched exactly like direct inputs.

## `maxResultsPerSearch` (type: `integer`):

Maximum number of videos to collect per search query (pagination stops once reached).

## `scrapeVideoMetadata` (type: `boolean`):

Emit a `type: "video"` item per video (title, channel, views, publish date, duration, keywords, thumbnails, available caption languages, etc.).

## `scrapeTranscript` (type: `boolean`):

Fetch the transcript (full text plus timestamped segments). Best-effort: uses YouTube's InnerTube transcript-panel endpoint via the mobile client, with the timedtext caption URL as a fallback. YouTube gates caption text behind PoToken/IP checks, so a transcript may be unavailable for some videos/IPs even when captions exist — a residential proxy improves the hit rate.

## `scrapeComments` (type: `boolean`):

Fetch comments. This is the slowest, most rate-limited path, so it is off by default. A residential proxy is strongly recommended when enabled.

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

Maximum top-level comments per video. Set 0 for unlimited (will paginate until YouTube stops returning a continuation).

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

Also expand reply threads (one extra request per thread that has replies). Replies are emitted as comment items with `isReply: true` and a `parentCommentId`.

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

Which comment ordering to request from YouTube.

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

Preferred caption language code (e.g. "en", "es", "de"). The matching caption track is selected when available; otherwise the scraper falls back to another track or an auto-generated one. Also sets the InnerTube `hl` locale.

## `preferManualCaptions` (type: `boolean`):

Prefer human-written (non-ASR) captions over auto-generated ones when both exist for the chosen language.

## `emitSearchResults` (type: `boolean`):

When using search queries, also push a lightweight `type: "searchResult"` item for each matched video (query, title, channel, view-count text, etc.) in addition to the enriched video/transcript/comment items.

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

YouTube rate-limits datacenter IPs aggressively (429s and empty responses), so a RESIDENTIAL proxy is strongly recommended, especially for comments at volume.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://youtu.be/9bZkp7q19f0"
  ],
  "videoIds": [
    "dQw4w9WgXcQ"
  ],
  "searchQueries": [
    "lofi hip hop",
    "machine learning tutorial"
  ],
  "maxResultsPerSearch": 50,
  "scrapeVideoMetadata": true,
  "scrapeTranscript": true,
  "scrapeComments": false,
  "maxComments": 100,
  "includeCommentReplies": false,
  "commentsSortBy": "top",
  "language": "en",
  "preferManualCaptions": true,
  "emitSearchResults": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

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

No description

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

No description

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

No description

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "maxResultsPerSearch": 50,
    "maxComments": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidscrape/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 = {
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "maxResultsPerSearch": 50,
    "maxComments": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("solidscrape/youtube-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxResultsPerSearch": 50,
  "maxComments": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call solidscrape/youtube-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=solidscrape/youtube-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/KJ5hDf4eKTtRqT1H5/builds/s88VWWalWzs6IiyUk/openapi.json
