{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Video Downloader & Scraper - YouTube All-in-One",
    "description": "Download YouTube videos, Shorts, playlists, and channels as MP4. Up to 10 concurrent downloads with no browser needed. Extract comments, captions, and rich metadata. Metadata-only mode for fast, cheap research. Quality selection with automatic fallback. $0.15/video download, $0.005 metadata-only.",
    "version": "0.3",
    "x-build-id": "BADEUOjzNsko8Vdoy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/jy-labs~youtube-all-in-one-downloader-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-jy-labs-youtube-all-in-one-downloader-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/jy-labs~youtube-all-in-one-downloader-scraper/runs": {
      "post": {
        "operationId": "runs-sync-jy-labs-youtube-all-in-one-downloader-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/jy-labs~youtube-all-in-one-downloader-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-jy-labs-youtube-all-in-one-downloader-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",
        "properties": {
          "startUrls": {
            "title": "YouTube URLs",
            "type": "array",
            "description": "Add one or more YouTube URLs to download. You can mix different types of URLs in a single run.",
            "items": {
              "type": "string"
            }
          },
          "searchQueries": {
            "title": "Search Queries",
            "type": "array",
            "description": "Search YouTube for videos matching these queries. Each query returns up to maxVideos results. Combined with startUrls if both are provided.",
            "items": {
              "type": "string"
            }
          },
          "quality": {
            "title": "Video Quality",
            "enum": [
              "highest",
              "1080p",
              "720p",
              "480p",
              "360p",
              "audio_only"
            ],
            "type": "string",
            "description": "Choose your preferred video quality. The default is 1080p. If the selected quality is not available for a video, the actor will automatically fall back to the closest lower quality. At the same resolution, H.264 is preferred over AV1 because it plays everywhere. If the selected quality's file would be larger than Max File Size, the actor downloads the highest lower quality that fits and notes it in the row's qualityFallback field. Larger files cost more residential proxy transfer, which you pay as platform usage, so 720p or 1080p is the cost-effective choice for most jobs ('Highest' can pick a large AV1 1440p or 4K stream, which can cost about $1 of usage per video).",
            "default": "1080p"
          },
          "maxFileSizeMb": {
            "title": "Max File Size (MB)",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Maximum size of a single downloaded video or audio file, in megabytes (1-2000). If your chosen quality would be larger than this, the actor downloads the highest lower quality that fits (for example 1080p instead of 4K) and records it in the row's qualityFallback field ({requested, delivered, reason: 'size_limit'}); the download is skipped when no lower quality has a reported size within the cap (or, for Audio Only, the audio track is over it), or when a stream still overflows mid-download after two step-downs to lower qualities. Each quality also has a fixed cap (360p 100 MB, 480p 150 MB, 720p 250 MB, 1080p 400 MB, highest 500 MB, audio 50 MB), and the smaller of the two applies. If a video is skipped and 'Extract Video Metadata' is on (the default), the video is still delivered as a metadata-only row marked downloadSkippedReason: 'size_limit_exceeded' and charged at the metadata rate instead of the video download rate; if it is off, the video counts as failed and only appears when 'Include Failed Videos in Output' is enabled. This is your cost ceiling: downloads go through the residential proxy (about $8/GB, paid by you as platform usage), so a 100 MB file costs about $0.80 of usage on top of the video download event.",
            "default": 200
          },
          "downloadVideo": {
            "title": "Download Video File",
            "type": "boolean",
            "description": "When enabled (default), the actor downloads the video file and stores it in Key-Value Store. Disable this to extract only metadata, captions, and comments without downloading the actual video -- significantly faster and cheaper.",
            "default": true
          },
          "downloadThumbnail": {
            "title": "Download Thumbnail Image",
            "type": "boolean",
            "description": "When enabled, the actor downloads the highest quality thumbnail image for each video and stores it in the Key-Value Store. The download URL is included in the output.",
            "default": false
          },
          "maxVideos": {
            "title": "Maximum Videos",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Limit the total number of videos to download. This is especially useful when downloading from playlists or channels to control costs and run time.",
            "default": 100
          },
          "filenameTemplate": {
            "title": "Filename Template",
            "type": "string",
            "description": "Custom filename template for downloaded files. Available placeholders: {videoId}, {title}, {quality}, {channelName}, {date}, {type}. Invalid filename characters are automatically removed.",
            "default": "{videoId}_{type}"
          },
          "extractMetadata": {
            "title": "Extract Video Metadata",
            "type": "boolean",
            "description": "When enabled (default), each result will include full video metadata: title, description, channel info, view/like counts, duration, tags, thumbnail URL, chapters, and category. When disabled, only the source URL, download link, video ID, delivered quality and file size are returned.",
            "default": true
          },
          "outputFormat": {
            "title": "Output Format",
            "enum": [
              "default",
              "llm_ready"
            ],
            "type": "string",
            "description": "Choose the output format. 'default' returns full metadata with download URLs. 'llm_ready' returns a flat structure optimized for AI/LLM pipelines with clean transcript text, word count, and minimal metadata — ideal for RAG, embeddings, and fine-tuning.",
            "default": "default"
          },
          "extractCaptions": {
            "title": "Extract Captions / Subtitles",
            "type": "boolean",
            "description": "When enabled, the actor will extract available captions (subtitles) from each video. The full transcript text is included in the output. This also enables metadata extraction automatically.",
            "default": false
          },
          "downloadCaptions": {
            "title": "Download Caption File (SRT/VTT)",
            "type": "boolean",
            "description": "When enabled, the actor downloads caption files in the specified format (SRT or VTT) and stores them in the Key-Value Store. The download URL is included in the output.",
            "default": false
          },
          "captionFormat": {
            "title": "Caption File Format",
            "enum": [
              "srt",
              "vtt"
            ],
            "type": "string",
            "description": "Format for downloaded caption files. SRT is widely compatible, VTT is the web standard. Only applies when 'Download Caption File' is enabled.",
            "default": "srt"
          },
          "captionLanguage": {
            "title": "Preferred Caption Language",
            "pattern": "^[a-z]{2,3}(-[A-Za-z]{2,4})?$",
            "type": "string",
            "description": "The language code for captions you want to extract (e.g., 'en' for English, 'ko' for Korean, 'ja' for Japanese, 'es' for Spanish). If the preferred language is not available, the first available language will be used instead. Only applies when 'Extract Captions' or 'Download Caption File' is enabled.",
            "default": "en"
          },
          "autoTranslateLanguage": {
            "title": "Auto-Translate Captions Language",
            "pattern": "^[a-z]{2,3}(-[A-Za-z]{2,4})?$",
            "type": "string",
            "description": "Automatically translate captions to this language using YouTube's built-in translation. For example, set to 'en' to get English translations of Korean, Japanese, or any other language video. Uses YouTube's 'tlang' parameter. Language code format: 'en', 'ko', 'ja', 'es', 'fr', etc. Only applies when 'Extract Captions' or output format is 'LLM-Ready'."
          },
          "extractComments": {
            "title": "Extract Comments",
            "type": "boolean",
            "description": "When enabled, the actor will extract top comments from each video. Comment data includes author, text, like count, and timestamp. This also enables metadata extraction automatically.",
            "default": false
          },
          "extractReplies": {
            "title": "Extract Comment Replies",
            "type": "boolean",
            "description": "When enabled with 'Extract Comments', the actor will also extract reply threads for each comment. This increases processing time but provides full conversation context.",
            "default": false
          },
          "maxComments": {
            "title": "Max Comments Per Video",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of comments to extract per video. Higher values increase run time and cost. Only applies when 'Extract Comments' is enabled.",
            "default": 100
          },
          "extractChannelInfo": {
            "title": "Extract Channel Info",
            "type": "boolean",
            "description": "When enabled with metadata extraction, adds detailed channel information including subscriber count, description, banner URL, and video count.",
            "default": false
          },
          "extractRelatedVideos": {
            "title": "Extract Related Videos",
            "type": "boolean",
            "description": "When enabled, extracts a list of related/suggested videos for each processed video. Up to 20 related videos are included with title, channel, view count, and duration.",
            "default": false
          },
          "monitorMode": {
            "title": "Monitor Mode (Incremental)",
            "type": "boolean",
            "description": "When enabled, the actor remembers previously processed video IDs using a named state store. On subsequent runs with the same state store name, only new videos are processed. This is ideal for scheduled runs monitoring channels or playlists for new content. Requires 'State Store Name' to be set.",
            "default": false
          },
          "stateStoreName": {
            "title": "State Store Name",
            "type": "string",
            "description": "Name of the Key-Value Store used to persist processed video IDs between runs. Use a descriptive name like 'my-channel-monitor'. Different monitoring jobs should use different store names. Only applies when 'Monitor Mode' is enabled."
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "Optional URL to receive a POST notification when all processing completes, including runs with nothing to process. The webhook payload includes processing statistics (processed count, failed count, success rate, total time) and noNewVideos, which is true only when monitor mode skipped every video as already processed. A run that found no valid video (for example, invalid URLs) reports total 0 with noNewVideos false."
          },
          "maxConcurrency": {
            "title": "Parallel Downloads",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Number of videos to download at the same time. Higher values finish faster but use more memory. Reduce this if you experience out-of-memory errors.",
            "default": 4
          },
          "maxRequestRetries": {
            "title": "Retry Attempts",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "How many times to retry downloading a video if it fails (e.g., due to network issues or rate limiting). Each retry uses exponential backoff with smart error classification (longer delays for rate-limiting, no retries for permanent failures).",
            "default": 3
          },
          "includeFailedVideos": {
            "title": "Include Failed Videos in Output",
            "type": "boolean",
            "description": "When enabled, videos that failed to download (after all retries) will still appear in the output dataset with an error message. Useful for debugging or tracking which videos could not be processed.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Configure a proxy to avoid YouTube rate limiting and geo-restrictions. Enabled by default with Apify Proxy. Downloads (and the PO token each download needs) go through the groups selected here from the first attempt, because YouTube's bot check blocks about 4 in 5 datacenter exits: keep RESIDENTIAL selected. When at least one retry is allowed, metadata-only and LLM-ready runs try a cheaper datacenter proxy first and retry on these groups if it fails. Residential transfer is billed per GB (about $8/GB) as platform usage that you pay, on top of the event price: a 100 MB file costs about $0.80. Choose 720p or 1080p and set Max File Size to control this cost. Disabling the proxy will cause most downloads to fail.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}