# YouTube Comments Scraper (Videos & Shorts) (`lurkapi/youtube-comments-scraper`) Actor

Scrape comments from YouTube videos and Shorts. Get comment text, author, likes, replies, timestamps, pinned status, and more.

- **URL**: https://apify.com/lurkapi/youtube-comments-scraper.md
- **Developed by:** [LurkAPI](https://apify.com/lurkapi) (community)
- **Categories:** Automation, Social media, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 comment 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Comments Scraper (Videos & Shorts)

Extract comments and replies from any YouTube video, Short, channel, or playlist. Get structured data ready for analysis in seconds.

### 🎬 What it does

Give it one or more YouTube URLs, and it will:

1. **Pull every comment** from each video, including Shorts
2. **Grab reply threads** with configurable depth
3. **Expand channels and playlists** automatically into individual videos
4. **Filter comments** by keyword or date range
5. **Detect comment language** and **look up commenter location** (optional add-ons)
6. **Deliver structured data** you can export as JSON, CSV, or Excel

Perfect for sentiment analysis, audience research, competitor monitoring, content strategy, and brand tracking.

### 📋 How to use it

#### Step 1: Add your URLs

Paste YouTube URLs or 11-character video IDs into the input field. You can add up to 500 per run.

**Supported formats:**
- `https://www.youtube.com/watch?v=VIDEO_ID` (regular videos)
- `https://youtu.be/VIDEO_ID` (short links)
- `https://www.youtube.com/shorts/VIDEO_ID` (Shorts)
- `https://www.youtube.com/live/VIDEO_ID` (live streams)
- `https://www.youtube.com/embed/VIDEO_ID` (embeds)
- `https://www.youtube.com/@ChannelName` (channels: expands to videos automatically)
- `https://www.youtube.com/channel/CHANNEL_ID` (channels by ID)
- `https://www.youtube.com/playlist?list=PLAYLIST_ID` (playlists: expands to videos automatically)
- Bare video IDs like `dQw4w9WgXcQ`

When you provide a channel or playlist URL, the scraper finds the videos for you and scrapes comments from each one.

#### Step 2: Configure options

- **Sort by**: Choose "Top comments" (most popular) or "Newest first" (most recent).
- **Max comments per video**: Limit how many top-level comments to collect. Default is 100. Set to 0 for unlimited.
- **Include replies**: Toggle reply collection on or off. On by default.
- **Max replies per comment**: Limit replies per thread. Default is 10. Set to 0 for unlimited.
- **Comment filter keywords**: Only keep comments containing specific text. Case-insensitive. Leave empty to keep all.
- **Date range**: Only keep comments posted within a specific window. Approximate, since YouTube shows relative timestamps.
- **Max videos per channel**: When scraping a channel, how many videos to include. Default is 50, max 500.

#### Step 3: Run and get results

Click **Start** and wait for the run to finish. Results appear in the **Output** tab as a table. You can download the data as JSON, CSV, or Excel.

#### Using the API

```json
{
    "urls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://www.youtube.com/shorts/kJQP7kiw5Fk",
        "https://www.youtube.com/@ChannelName",
        "9bZkp7q19f0"
    ],
    "sortBy": "TOP_COMMENTS",
    "maxCommentsPerVideo": 100,
    "includeReplies": true,
    "maxRepliesPerComment": 10,
    "maxVideosPerChannel": 50
}
````

### 📊 Output fields

Each row in the output represents one comment or reply.

| Field | Description |
|-------|-------------|
| `status` | "Success" or an error message explaining what went wrong |
| `videoId` | YouTube video ID |
| `videoUrl` | Full YouTube URL |
| `videoTitle` | Title of the video |
| `channelName` | Name of the channel that uploaded the video |
| `channelId` | Channel ID |
| `totalCommentCount` | Total number of comments on the video (when available) |
| `commentId` | Unique comment ID |
| `text` | The comment text |
| `authorName` | Display name of the commenter |
| `authorChannelId` | Commenter's channel ID |
| `authorChannelUrl` | Link to the commenter's channel |
| `authorProfileImageUrl` | Commenter's profile picture URL |
| `likeCount` | Number of likes on the comment |
| `replyCount` | Number of replies (top-level comments only) |
| `publishedAt` | When the comment was posted (ISO 8601 datetime) |
| `isReply` | Whether this row is a reply to another comment |
| `parentCommentId` | The parent comment's ID (for replies only) |
| `isPinned` | Whether the comment is pinned by the video creator |
| `isHearted` | Whether the creator hearted this comment |
| `isAuthorChannelOwner` | Whether the commenter is the video creator |
| `detectedLanguage` | ISO 639-3 language code (only when language detection is enabled) |
| `authorLocation` | Self-reported location from commenter's channel (only when location lookup is enabled) |

#### Example output

```json
{
    "status": "Success",
    "videoId": "dQw4w9WgXcQ",
    "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "videoTitle": "Rick Astley - Never Gonna Give You Up",
    "channelName": "Rick Astley",
    "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
    "totalCommentCount": 3200000,
    "commentId": "UgyL2...",
    "text": "This song is a masterpiece.",
    "authorName": "MusicFan42",
    "authorChannelId": "UC...",
    "authorChannelUrl": "https://www.youtube.com/@MusicFan42",
    "authorProfileImageUrl": "https://yt3.ggpht.com/...",
    "likeCount": 1200,
    "replyCount": 15,
    "publishedAt": "2024-03-15T10:30:00.000Z",
    "isReply": false,
    "parentCommentId": null,
    "isPinned": true,
    "isHearted": true,
    "isAuthorChannelOwner": false,
    "detectedLanguage": "eng",
    "authorLocation": "United States"
}
```

#### The status field

Every row has a `status` field. When everything works, it says "Success". When something goes wrong, the status tells you exactly what happened and what you can do about it:

- "Comments are disabled for this video."
- "This video is private and cannot be accessed."
- "This video is unavailable. It may have been removed by the creator."
- "Could not load channel videos. The channel may not exist or may be private."

### 🌍 Country & Language

These optional features add extra data to each comment. They are disabled by default and each has a separate cost.

#### Detect comment language

Turn on "Detect Comment Language" to identify the language of each comment. The result appears in the `detectedLanguage` field as an ISO 639-3 code (e.g., "eng" for English, "kor" for Korean, "fra" for French).

**Cost:** $0.50 per 1,000 detections ($0.0005 per comment). You are only charged when a language is successfully detected, not when detection fails on very short comments.

Language detection works best on comments longer than a few words. Very short comments (like "lol" or emojis) may not return a result.

#### Look up author location

Turn on "Look Up Author Location" to get the self-reported location from each commenter's YouTube channel. The result appears in the `authorLocation` field.

**Cost:** $2 per 1,000 unique authors ($0.002 per author). You are only charged once per unique commenter, and only when a location is found. If the commenter hasn't set a location on their channel, no charge applies.

**Good to know about location lookup:**

- Not all YouTube users set a location on their channel. Many will return empty.
- The location is self-reported, not verified by YouTube.
- This feature increases run time because it checks each unique commenter's profile.

### 🌐 Proxy settings

By default, the scraper uses Apify's datacenter proxies to access YouTube.

- **Automatic (default)**: Apify selects the best proxy automatically.
- **Datacenter**: Fast and affordable. Works for most videos.
- **Residential**: Use this if you're getting frequent blocks or empty results. Residential IPs look like regular users to YouTube.
- **Own proxies**: Provide your own proxy URLs.
- **No proxy**: Disable proxies entirely. There will be no IP rotation if you get blocked.

If you see errors about sign-in challenges or bot detection, switch to residential proxies.

### 💰 Pricing

**Base cost:** $1 per 1,000 comments ($0.001 per comment).

Both top-level comments and replies count toward the total. You only pay for comments that are successfully collected. Comments filtered out by keyword or date range are not charged.

**Optional add-ons:**

- Language detection: +$0.50 per 1,000 successful detections
- Author location lookup: +$2 per 1,000 locations found

**Examples:**

- 100 comments from one video: $0.10
- 1,000 comments with replies: $1.00
- 10 videos with 100 comments each: $1.00
- 1,000 comments with language detection: ~$1.50
- 1,000 comments with location lookup (500 unique authors, 50 locations found): $1.10

Set `maxCommentsPerVideo` to control costs. The default of 100 comments per video costs about $0.10 per video.

### 💡 Good to know

- **Shorts work just like regular videos.** The same comment collection works for both.
- **Channels and playlists expand automatically.** Provide a channel URL and the scraper finds the videos for you. Use `maxVideosPerChannel` to control how many (default 50, max 500).
- **Reply threads can go deep.** Use `maxRepliesPerComment` to limit how many replies are collected per thread.
- **Keyword filtering saves money.** Comments that don't match your filter are skipped entirely and not charged.
- **Date filtering is approximate.** YouTube shows relative timestamps ("2 days ago"), which get converted to dates. Recent comments are accurate to the hour, older ones to the month.
- **Disabled comments show a clear message.** You'll see "Comments are disabled for this video" instead of a silent failure.
- **Duplicates are removed automatically.** If you paste the same video twice, it only gets scraped once.
- **Data is stored in your Apify storage.** How long it's kept depends on your Apify plan.
- **Up to 500 URLs per run.** For larger batches, split them across multiple runs.

### ❓ FAQ

**Why did my scrape return no comments?**
The video might have comments disabled, or it might be private or unavailable. Check the `status` field in the output for details. If you're seeing bot detection errors, try switching to residential proxies.

**What's the difference between "Top comments" and "Newest first"?**
"Top comments" shows the most popular comments first (by likes and engagement). "Newest first" shows the most recently posted comments. This matches the sort options you see on YouTube itself.

**Are replies included in the comment count?**
Yes. Both top-level comments and replies are charged. Replies are collected separately after each top-level comment and have their own limit via `maxRepliesPerComment`.

**How accurate are the timestamps?**
YouTube shows relative timestamps ("2 days ago", "3 months ago"). The scraper converts these to approximate ISO dates. Recent comments are accurate to the hour, older ones to the month.

**Can I scrape all comments from a channel?**
Yes. Provide a channel URL (like `https://www.youtube.com/@ChannelName`) and set `maxVideosPerChannel` to control how many of their videos to scrape. The scraper expands the channel into individual videos and scrapes comments from each one.

**How does the keyword filter work?**
Enter a word or phrase in the "Comment Filter Keywords" field. Only comments containing that text (case-insensitive) will be included in the output and charged. Non-matching comments are skipped entirely.

**Which proxy should I use?**
Start with the default (datacenter). If you get frequent errors about sign-in challenges, switch to residential proxies. Residential proxies are slower but much harder for YouTube to detect.

**How long are the files stored?**
Stored in your Apify storage. How long they're kept depends on your Apify plan.

### 🔗 Other tools you might like

- [YouTube Transcript Download](https://apify.com/lurkapi/youtube-transcript-download) - Download transcripts and subtitles from YouTube videos.
- [YouTube Channel Email Scraper](https://apify.com/lurkapi/youtube-channel-email-scraper) - Find email addresses from YouTube channels.

### ⚖️ Disclaimer

This tool is intended for personal, research, and educational use. You are responsible for complying with YouTube's Terms of Service and applicable laws in your jurisdiction. The developer is not liable for misuse. Data availability depends on YouTube at run time.

**Keywords:** youtube comments, youtube comment scraper, youtube shorts comments, youtube data extraction, comment analysis, youtube channel comments, youtube playlist comments

# Actor input Schema

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

YouTube video URLs, Shorts URLs, channel URLs, playlist URLs, or bare 11-character video IDs. Supports batch processing up to 500 URLs.

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

Sort order for comments. 'Top' shows most popular first, 'Newest' shows most recent first.

## `maxCommentsPerVideo` (type: `integer`):

Maximum number of top-level comments to scrape per video. Set to 0 for unlimited.

## `includeReplies` (type: `boolean`):

Scrape replies to top-level comments. Replies are nested under their parent comment.

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

Maximum number of replies to scrape per top-level comment. Set to 0 for unlimited. Only used when 'Include Replies' is enabled.

## `commentFilter` (type: `string`):

Only include comments containing this text. Leave empty to include all comments. Case-insensitive.

## `dateFrom` (type: `string`):

Only include comments posted after this date (approximate). YouTube shows relative timestamps, so filtering is approximate.

## `dateTo` (type: `string`):

Only include comments posted before this date (approximate).

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

Maximum number of videos to scrape from channel URLs.

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

Detect the language of each comment using NLP. Adds a 'detectedLanguage' field to the output. You are only charged when a language is successfully detected, not when detection fails.

## `lookupAuthorLocation` (type: `boolean`):

Fetch the self-reported location from each commenter's YouTube channel. Adds an 'authorLocation' field. Not all users set a location. You are only charged when a location is found, not when it is unavailable. This significantly increases run time.

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

Number of videos to process in parallel. Higher values are faster but use more memory.

## `proxyConfig` (type: `object`):

Select proxies for accessing YouTube.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "sortBy": "TOP_COMMENTS",
  "maxCommentsPerVideo": 100,
  "includeReplies": true,
  "maxRepliesPerComment": 10,
  "maxVideosPerChannel": 50,
  "detectLanguage": false,
  "lookupAuthorLocation": false,
  "concurrency": 1,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# Actor output Schema

## `comments` (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 = {
    "urls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "sortBy": "TOP_COMMENTS",
    "proxyConfig": {
        "useApifyProxy": true,
        "apifyProxyGroups": []
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lurkapi/youtube-comments-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": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "sortBy": "TOP_COMMENTS",
    "proxyConfig": {
        "useApifyProxy": True,
        "apifyProxyGroups": [],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lurkapi/youtube-comments-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 '{
  "urls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "sortBy": "TOP_COMMENTS",
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}' |
apify call lurkapi/youtube-comments-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Comments Scraper (Videos & Shorts)",
        "description": "Scrape comments from YouTube videos and Shorts. Get comment text, author, likes, replies, timestamps, pinned status, and more.",
        "version": "0.0",
        "x-build-id": "DSbzkCJowrVwlx2Ou"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/lurkapi~youtube-comments-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-lurkapi-youtube-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/lurkapi~youtube-comments-scraper/runs": {
            "post": {
                "operationId": "runs-sync-lurkapi-youtube-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/lurkapi~youtube-comments-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-lurkapi-youtube-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "YouTube URLs or Video IDs",
                        "maxItems": 500,
                        "type": "array",
                        "description": "YouTube video URLs, Shorts URLs, channel URLs, playlist URLs, or bare 11-character video IDs. Supports batch processing up to 500 URLs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "sortBy": {
                        "title": "Sort Comments By",
                        "enum": [
                            "TOP_COMMENTS",
                            "NEWEST_FIRST"
                        ],
                        "type": "string",
                        "description": "Sort order for comments. 'Top' shows most popular first, 'Newest' shows most recent first.",
                        "default": "TOP_COMMENTS"
                    },
                    "maxCommentsPerVideo": {
                        "title": "Max Comments Per Video",
                        "minimum": 0,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Maximum number of top-level comments to scrape per video. Set to 0 for unlimited.",
                        "default": 100
                    },
                    "includeReplies": {
                        "title": "Include Replies",
                        "type": "boolean",
                        "description": "Scrape replies to top-level comments. Replies are nested under their parent comment.",
                        "default": true
                    },
                    "maxRepliesPerComment": {
                        "title": "Max Replies Per Comment",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of replies to scrape per top-level comment. Set to 0 for unlimited. Only used when 'Include Replies' is enabled.",
                        "default": 10
                    },
                    "commentFilter": {
                        "title": "Comment Filter Keywords",
                        "type": "string",
                        "description": "Only include comments containing this text. Leave empty to include all comments. Case-insensitive."
                    },
                    "dateFrom": {
                        "title": "Comments From Date",
                        "type": "string",
                        "description": "Only include comments posted after this date (approximate). YouTube shows relative timestamps, so filtering is approximate."
                    },
                    "dateTo": {
                        "title": "Comments To Date",
                        "type": "string",
                        "description": "Only include comments posted before this date (approximate)."
                    },
                    "maxVideosPerChannel": {
                        "title": "Max Videos Per Channel",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of videos to scrape from channel URLs.",
                        "default": 50
                    },
                    "detectLanguage": {
                        "title": "Detect Comment Language",
                        "type": "boolean",
                        "description": "Detect the language of each comment using NLP. Adds a 'detectedLanguage' field to the output. You are only charged when a language is successfully detected, not when detection fails.",
                        "default": false
                    },
                    "lookupAuthorLocation": {
                        "title": "Look Up Author Location",
                        "type": "boolean",
                        "description": "Fetch the self-reported location from each commenter's YouTube channel. Adds an 'authorLocation' field. Not all users set a location. You are only charged when a location is found, not when it is unavailable. This significantly increases run time.",
                        "default": false
                    },
                    "concurrency": {
                        "title": "Concurrency",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Number of videos to process in parallel. Higher values are faster but use more memory.",
                        "default": 1
                    },
                    "proxyConfig": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Select proxies for accessing YouTube.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": []
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
