{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Transcript Scraper · Channels & Playlists · $5/1K",
    "description": "No cookies, no login. Turn YouTube video, channel and playlist URLs into clean, timestamped transcripts (JSON, text, SRT, VTT) with video metadata. Pay per delivered transcript; error rows are free.",
    "version": "0.1",
    "x-build-id": "mpW8EbHj6c3OmiGyU"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/gangling_polygon~youtube-transcript-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-gangling_polygon-youtube-transcript-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/gangling_polygon~youtube-transcript-scraper/runs": {
      "post": {
        "operationId": "runs-sync-gangling_polygon-youtube-transcript-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/gangling_polygon~youtube-transcript-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-gangling_polygon-youtube-transcript-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": "Video, Shorts, youtu.be, embed, mobile, channel or playlist URLs. Channels and playlists are expanded into their videos (newest first). Invalid URLs produce an uncharged error row.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "videoIds": {
            "title": "Video IDs",
            "type": "array",
            "description": "Bare 11-character YouTube video IDs (e.g. dQw4w9WgXcQ). Convenient for API calls.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "channelUrls": {
            "title": "Channels",
            "type": "array",
            "description": "Channel handles or URLs: @handle, https://www.youtube.com/@handle, /channel/UC…, /c/name or /user/name. Each is expanded to its newest videos, limited by 'Max videos per source'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "playlistUrls": {
            "title": "Playlists",
            "type": "array",
            "description": "Playlist URLs (…/playlist?list=PL…) or bare playlist IDs. Expanded in playlist order, limited by 'Max videos per source'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "searchQueries": {
            "title": "Search queries",
            "type": "array",
            "description": "Keywords to search YouTube for (up to 100). Each query is expanded to the matching videos in YouTube's relevance order, limited by 'Max videos per search'. Only regular videos are taken: Shorts, live and upcoming streams are not.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxVideosPerSearch": {
            "title": "Max videos per search",
            "minimum": 1,
            "maximum": 300,
            "type": "integer",
            "description": "Maximum number of videos taken from each search query (1–300). YouTube lists about 300 results per query at most.",
            "default": 50
          },
          "maxVideosPerSource": {
            "title": "Max videos per source",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum number of videos taken from each channel or playlist (1–1000).",
            "default": 50
          },
          "includeShorts": {
            "title": "Include Shorts from channels",
            "type": "boolean",
            "description": "When expanding a channel, also include its Shorts.",
            "default": true
          },
          "publishedAfter": {
            "title": "Published after",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string",
            "description": "Only videos published on or after this date (YYYY-MM-DD, UTC). Applies to channel and playlist sources."
          },
          "publishedBefore": {
            "title": "Published before",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string",
            "description": "Only videos published on or before this date (YYYY-MM-DD, UTC). Applies to channel and playlist sources."
          },
          "languages": {
            "title": "Languages (priority order)",
            "type": "array",
            "description": "Caption languages to try, in order, as BCP-47 codes (en, en-US, pl, de, …). The first available one is used. Use * to accept any language. Default: en.",
            "default": [
              "en"
            ],
            "items": {
              "type": "string"
            }
          },
          "captionType": {
            "title": "Caption type",
            "enum": [
              "any",
              "manual",
              "auto"
            ],
            "type": "string",
            "description": "any = prefer creator-uploaded captions, fall back to auto-generated; manual = creator-uploaded only; auto = auto-generated only.",
            "default": "any"
          },
          "anyLanguage": {
            "title": "Use any language if none of mine exists",
            "type": "boolean",
            "description": "When none of the languages above is available for a video, take any other caption track instead of returning LANGUAGE_NOT_FOUND. The languages you list still come first; the row says which language was delivered.",
            "default": false
          },
          "translationFallback": {
            "title": "Translate when the language is missing",
            "type": "boolean",
            "description": "Not available yet. Reserved for YouTube's built-in translation into the first requested language.",
            "default": false
          },
          "listOnly": {
            "title": "List available languages only",
            "type": "boolean",
            "description": "Free. For every video, return one row with status 'languages' and the list of caption tracks (availableLanguages), without fetching or charging a transcript. Languages, caption type and output formats are ignored. Limits: 500 videos per run, and a daily number of lookups per Apify account (100 on the free plan, 2,000 on paid plans).",
            "default": false
          },
          "outputFormats": {
            "title": "Output formats",
            "type": "array",
            "description": "json = timestamped segments; text = plain transcript; srt and vtt = subtitle files as strings; timestampedText = plain text with a [mm:ss] timestamp on every line; cleanText = transcript without sound tags such as [Music], split into paragraphs; paragraphs = the same paragraphs as {start, end, text}; chunks = the cleaned transcript cut into pieces of chunkSize words (see chunkSize and chunkOverlap). Default: json and text.",
            "items": {
              "type": "string",
              "enum": [
                "json",
                "text",
                "srt",
                "vtt",
                "timestampedText",
                "cleanText",
                "paragraphs",
                "chunks"
              ],
              "enumTitles": [
                "JSON segments",
                "Plain text",
                "SRT",
                "WebVTT",
                "Text with [mm:ss] timestamps",
                "Clean text in paragraphs",
                "Paragraphs with times",
                "Fixed-size text chunks"
              ]
            },
            "default": [
              "json",
              "text"
            ]
          },
          "timestampStyle": {
            "title": "Timestamp style",
            "enum": [
              "auto",
              "mmss",
              "hhmmss"
            ],
            "type": "string",
            "description": "Only used when timestampedText is among the output formats. auto = [mm:ss], switching to [hh:mm:ss] for videos an hour or longer; mmss = always [mm:ss] (minutes are not wrapped at 60); hhmmss = always [hh:mm:ss].",
            "default": "auto"
          },
          "includeSegmentEnd": {
            "title": "Include segment end time",
            "type": "boolean",
            "description": "Add an end time (seconds) to every item in segments, alongside start and dur.",
            "default": false
          },
          "chunkSize": {
            "title": "Chunk size (words)",
            "minimum": 60,
            "maximum": 5000,
            "type": "integer",
            "description": "Only used when chunks is among the output formats: words per chunk.",
            "default": 300
          },
          "chunkOverlap": {
            "title": "Chunk overlap (words)",
            "minimum": 0,
            "maximum": 2500,
            "type": "integer",
            "description": "Only used when chunks is among the output formats: words each chunk shares with the next one. At most half the chunk size. Overlapping words are repeated in the row, so it grows by about overlap divided by chunk size.",
            "default": 30
          },
          "includeChannelStats": {
            "title": "Add channel handle and subscriber count",
            "type": "boolean",
            "description": "Add channelHandle (such as @RickAstleyYT) and subscriberCount to every row. Needs one extra request per channel (shared by its videos), about 140 to 300 KB through the proxy. Subscriber counts are rounded the way YouTube shows them (4.55M).",
            "default": false
          },
          "wordTimestamps": {
            "title": "Word-level timestamps",
            "type": "boolean",
            "description": "Add a words field: every word with its start and end time (seconds). Only auto-generated captions carry word times; for manual captions words is empty and wordTimestampsAvailable is false. Makes rows larger (about 45 characters per word). Same price.",
            "default": false
          },
          "includeMetadata": {
            "title": "Include video metadata",
            "type": "boolean",
            "description": "Add title, channel, duration, views, likes, publish date, description, thumbnail and keywords to every row. Free of charge; turn off only to get smaller rows.",
            "default": true
          },
          "includeChapters": {
            "title": "Include chapters",
            "type": "boolean",
            "description": "Add `chapters` (title, start, end in seconds) and `chaptersAuto` to every transcript row. No extra charge. The chapters are read from the timestamp lines of the video description, so only chapters the creator wrote are found.",
            "default": false
          },
          "storeFiles": {
            "title": "Save transcripts as files",
            "type": "boolean",
            "description": "Also save each text, SRT, VTT or timestamped-text output as a file in this run's key-value store, and add a `files` object with a link for each to the row. Needs at least one of those formats in Output formats. No extra charge; the files use your storage and are kept for as long as your Apify plan keeps this run's data.",
            "default": false
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Videos processed in parallel (1–20).",
            "default": 5
          },
          "maxItems": {
            "title": "Max transcripts per run",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after this many videos have been attempted (ok, limited and error rows all count; videos outside the date window do not). Leave empty for no limit; the run also stops at your 'Max cost per run'."
          },
          "onlyNewVideos": {
            "title": "Only new videos",
            "type": "boolean",
            "description": "For channels and playlists: skip videos that an earlier run (using the same state store) already delivered, so a scheduled run returns only what is new. Skipped videos do not count toward Max videos per source. Videos given directly (URLs or ids) are never skipped. A video counts as delivered once its transcript row is written; videos that gave an error row are tried again.",
            "default": false
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Name of the key-value store that remembers delivered videos (used with Only new videos). 3 to 63 characters: lower-case letters, digits and hyphens, not starting or ending with a hyphen. Use a different name for an independent history. The store is created in your account and kept until you delete it.",
            "default": "youtube-transcript-delivered"
          },
          "resetDeliveredVideos": {
            "title": "Forget delivered videos",
            "type": "boolean",
            "description": "Used with Only new videos: forget what was delivered for the channels and playlists in this run, so all their videos count as new again. Other channels and playlists in the store are not touched.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "YouTube blocks datacenter IPs for caption requests, so Apify residential proxies are used by default. Changing this is likely to lower the success rate.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}