{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Video Scraper & YouTube Shorts Scraper: Search, Channel",
    "description": "YouTube scraper and YouTube Data API alternative for video details and metadata: keyword search with YouTube's filters, channel videos, Shorts and streams, playlists, hashtags, video URLs. Each video's exact views, likes, comment count, publish date, description, tags, chapters, channel. No login.",
    "version": "0.1",
    "x-build-id": "xaS0lomtyrIe5Lom1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/hyperbach~youtube-video-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-hyperbach-youtube-video-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/hyperbach~youtube-video-scraper/runs": {
      "post": {
        "operationId": "runs-sync-hyperbach-youtube-video-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/hyperbach~youtube-video-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-hyperbach-youtube-video-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": {
          "searchQueries": {
            "title": "Search keywords",
            "maxItems": 200,
            "type": "array",
            "description": "Keywords to search on YouTube, one search each (at most 200), read in YouTube's own order with the filters below. A YouTube search URL (https://www.youtube.com/results?search_query=…&sp=…) runs with its own filters. A channel, playlist, hashtag or video URL pasted here is read as what it is.",
            "items": {
              "type": "string",
              "maxLength": 2000
            },
            "default": []
          },
          "startUrls": {
            "title": "YouTube URLs or ids",
            "maxItems": 2000,
            "type": "array",
            "description": "Videos and Shorts (watch, youtu.be, shorts, live and embed links, or an 11-character id), channels (a channel URL, an @handle or a UC… id: its Videos tab, and its Shorts and Live tabs when maxResultsShorts or maxResultStreams is set; a URL that names a tab, such as /@name/shorts or /@name/streams, reads that tab alone, up to its own field or else maxResults; one channel given in several forms is read once), playlists (a playlist URL or a PL… id), hashtags (a #tag or a /hashtag/ URL) and search URLs (at most 2,000). A value that names none of these is a free invalid row; the run goes on.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Max videos per input",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "How many videos each search, playlist and hashtag delivers at most, in YouTube's order, and how many of a channel's Videos tab. 0 reads no search, playlist or hashtag and no channel Videos tab (set maxResultsShorts or maxResultStreams to read a channel's other tabs only).",
            "default": 50
          },
          "maxResultsShorts": {
            "title": "Max Shorts per channel",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "How many of each channel's Shorts tab to read, newest first (or in channelSortBy's order). 0 = the Shorts tab is not read. For a keyword search of Shorts set searchType to shorts.",
            "default": 0
          },
          "maxResultStreams": {
            "title": "Max live streams per channel",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "How many of each channel's Live tab (past streams, live now, scheduled) to read. 0 = the Live tab is not read.",
            "default": 0
          },
          "searchType": {
            "title": "Search for",
            "enum": [
              "video",
              "shorts",
              "all"
            ],
            "type": "string",
            "description": "Videos (YouTube's video filter), Shorts only (YouTube's Shorts filter: every row is a Short), or YouTube's unfiltered results (videos plus the Shorts shelf, each row typed). On a broad keyword most of these rows can be Shorts from the shelf (17 of 20 on our test), each charged as a video row.",
            "default": "video"
          },
          "uploadDate": {
            "title": "Upload date",
            "enum": [
              "any",
              "hour",
              "today",
              "week",
              "month",
              "year"
            ],
            "type": "string",
            "description": "YouTube's upload-date filter. YouTube's search has no working sort by upload date (it answers the relevance order), so this is the way to read recent videos; every detailed row carries its exact published_at. YouTube's own windows are a little wider than their names: 'This week' reached 7.4 days back and 'This month' 30.6 days on our test. For an exact cut-off day, set oldestPostDate.",
            "default": "any"
          },
          "duration": {
            "title": "Duration",
            "enum": [
              "any",
              "under4",
              "4to20",
              "over20"
            ],
            "type": "string",
            "description": "YouTube's duration filter.",
            "default": "any"
          },
          "features": {
            "title": "Features",
            "type": "array",
            "description": "YouTube's feature filters, each applied by YouTube (several narrow the search together).",
            "items": {
              "type": "string",
              "enum": [
                "live",
                "4k",
                "hd",
                "subtitles",
                "cc",
                "360",
                "vr180",
                "3d",
                "hdr",
                "location",
                "purchased"
              ],
              "enumTitles": [
                "Live",
                "4K",
                "HD",
                "Subtitles/CC",
                "Creative Commons",
                "360°",
                "VR180",
                "3D",
                "HDR",
                "Location",
                "Purchased"
              ]
            },
            "default": []
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "views"
            ],
            "type": "string",
            "description": "Relevance (YouTube's default) or view count. YouTube ignores its upload-date and rating sorts logged out (measured on every form), so they are not offered; use uploadDate for recent videos.",
            "default": "relevance"
          },
          "deepSearch": {
            "title": "Past one walk (duration slices)",
            "type": "boolean",
            "description": "A YouTube search ends after about 500 results (230–350 distinct videos). When maxResults asks for more, the search goes on into YouTube's three duration bands (under 4, 4–20, over 20 minutes), each walked to its own end, every video once (348 → 991 distinct videos for 'minecraft' on our test). A search with its own duration filter is not sliced. Off: one walk.",
            "default": true
          },
          "country": {
            "title": "Country of the search",
            "enum": [
              "US",
              "GB",
              "CA",
              "AU",
              "NZ",
              "IE",
              "IN",
              "PK",
              "BD",
              "PH",
              "ID",
              "MY",
              "SG",
              "TH",
              "VN",
              "JP",
              "KR",
              "TW",
              "HK",
              "DE",
              "AT",
              "CH",
              "FR",
              "BE",
              "NL",
              "ES",
              "PT",
              "IT",
              "PL",
              "CZ",
              "RO",
              "HU",
              "GR",
              "SE",
              "NO",
              "DK",
              "FI",
              "TR",
              "UA",
              "IL",
              "AE",
              "SA",
              "EG",
              "MA",
              "NG",
              "KE",
              "ZA",
              "BR",
              "MX",
              "AR",
              "CO",
              "CL",
              "PE",
              "LK",
              "KZ",
              "NP"
            ],
            "type": "string",
            "description": "YouTube shows a different search to each country (a GB, DE, IN, JP or BR reader shares 0–5 of the first 20 'news' results with a US reader): each search is read from a connection in this country, and every row says the country it was read from. Channels, playlists and video records are the same everywhere.",
            "default": "US"
          },
          "language": {
            "title": "Language",
            "pattern": "^[a-z]{2,3}(-[A-Za-z]{2,4})?$",
            "type": "string",
            "description": "YouTube's interface language (hl), such as en, de, pt-BR: the search's texts and the watch page's title (title_localized, when the creator translated it) follow it. The title is always the creator's original. Counts are read as numbers in English; in another language the subscriber text is kept as YouTube writes it.",
            "default": "en"
          },
          "channelSortBy": {
            "title": "Channel order",
            "enum": [
              "newest",
              "popular",
              "oldest"
            ],
            "type": "string",
            "description": "The order a channel's Videos, Shorts and Live tabs are read in: newest first (the tab's own order), or YouTube's own Popular and Oldest orders.",
            "default": "newest"
          },
          "oldestPostDate": {
            "title": "Oldest publish date",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$",
            "type": "string",
            "description": "YYYY-MM-DD. A video published before this day is dropped free; a channel tab read newest first stops at its first older video. The card's relative date (\"3 weeks ago\") decides where it is sure, the record's exact date otherwise; with includeDetails off, a card with no sure date (every Shorts card) is dated by one record call before it is delivered, so no older card is charged."
          },
          "includeDetails": {
            "title": "Read each video's record",
            "type": "boolean",
            "description": "On (recommended): every listed video's record and watch page — exact views and likes, the exact comment count, the ISO publish date, the full description with its links, tags, hashtags, chapters, category, the channel's subscribers, live and members-only status, age restriction, the Shorts flag. Off: the list's cards alone (id, title, duration, the view text, the relative date, the channel), faster and priced as a card row. A video URL is always read with its record.",
            "default": true
          },
          "includeMonetization": {
            "title": "Ads shown and paid promotion",
            "type": "boolean",
            "description": "One more call per video: ads_shown (YouTube served ad slots to a logged-out viewer of this video) and has_paid_promotion (the creator declared a paid promotion). A signal, not the channel's monetization status; null for a video that is not playable logged out (members-only, age-restricted, scheduled).",
            "default": false
          },
          "includeChannelDetails": {
            "title": "Channel details",
            "type": "boolean",
            "description": "Each channel's About once per run: country, joined date, exact video and view counts, on every row of its videos.",
            "default": false
          },
          "onlyNew": {
            "title": "Only new videos (memory between runs)",
            "type": "boolean",
            "description": "Remember every video delivered under this memory (stateStoreName, or a name derived from the inputs) and skip it free next time (a list's video, or a video input as a free skipped row): a scheduled run of a channel delivers only its new uploads. A remembered video still takes its place in maxResults, so a run reads the newest N and never walks past them to older videos.",
            "default": false
          },
          "stateStoreName": {
            "title": "Memory name",
            "pattern": "^([a-zA-Z0-9][a-zA-Z0-9._-]{0,63})?$",
            "type": "string",
            "description": "The name of the onlyNew memory, so several tasks can share one or keep theirs apart. Empty: a name derived from the inputs.",
            "default": ""
          },
          "skipVideoIds": {
            "title": "Videos to skip",
            "maxItems": 10000,
            "type": "array",
            "description": "Video ids or URLs you already have (at most 10,000): a listed video among them is skipped free and does not count against maxResults; a video input among them is a free skipped row.",
            "items": {
              "type": "string",
              "maxLength": 500
            },
            "default": []
          },
          "maxItems": {
            "title": "Max videos (whole run)",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "The most charged rows the run delivers over every input (summary rows and free rows do not count). 0 = no limit beyond maxResults. The log names the most the run can cost before the first request.",
            "default": 0
          },
          "maxConcurrency": {
            "title": "Connections in parallel",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "How many residential connections read video records at once (4 requests each). 2 by default. More connections spread YouTube's per-connection budget over more exits for a run of thousands of videos; they do not raise the rate (1, 2 and 4 gave 441–522 rows a minute on our test: the watch pages share the list connection).",
            "default": 2
          },
          "proxyUrl": {
            "title": "Proxy URL",
            "type": "string",
            "description": "Empty (recommended): YouTube is read through the Actor's own connections at no extra cost to you. Your own proxy URL (scheme://user:pass@host:port) carries every call instead; a video record needs a residential IP (YouTube refuses it to datacenter IPs)."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}