{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Channel Transcripts Scraper - Bulk, SRT & VTT",
    "description": "Get the transcripts of every video on a YouTube channel by channel URL or @handle, as text, timestamps, SRT or VTT, with publish date, views and length. Limit videos per channel, filter by date, translate, RAG chunks, schedule with only-new-videos mode. Videos without captions are free.",
    "version": "0.1",
    "x-build-id": "u2gllOIGnQAHaZRxW"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapewise~youtube-channel-transcripts/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapewise-youtube-channel-transcripts",
        "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/scrapewise~youtube-channel-transcripts/runs": {
      "post": {
        "operationId": "runs-sync-scrapewise-youtube-channel-transcripts",
        "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/scrapewise~youtube-channel-transcripts/run-sync": {
      "post": {
        "operationId": "run-sync-scrapewise-youtube-channel-transcripts",
        "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": {
          "channelUrls": {
            "title": "Channels",
            "type": "array",
            "description": "YouTube channels, one per line, in any format: https://www.youtube.com/@veritasium, @veritasium, a bare handle, /channel/UC..., /c/name or /user/name. Videos are listed newest first from the Videos and Live tabs, up to 'Max videos per channel, playlist or search' each. Playlist, search and single video URLs also work in the same list. Listing is free; you pay per transcript delivered, and 'sourceUrl' on every row says which channel it came from. Also accepts 'videoUrls', 'urls', 'startUrls', 'channel_url', 'channelUrl', 'channels' and 'channel'.",
            "items": {
              "type": "string"
            }
          },
          "maxVideosPerSource": {
            "title": "Max videos per channel, playlist or search",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "How many videos to transcribe from each channel (or playlist or search), newest first, up to 5,000. Default 10. Raise it to get a whole back catalogue, and raise 'Maximum videos in the run' too, because the smaller of the two wins. With 'Only new videos' on, it counts only videos you have not received yet. Also accepts 'max_videos', 'maxVideos' and 'maxVideosPerChannel'.",
            "default": 10
          },
          "publishedAfter": {
            "title": "Only videos published after",
            "type": "string",
            "description": "Skip videos published before this date, as YYYY-MM-DD (for example 2026-06-01). Skipped videos produce no row and are not charged. Set it to today's date together with 'Only new videos' to receive only uploads from now on, instead of filling in the back catalogue. 'start_date' and 'end_date' also work."
          },
          "onlyNewVideos": {
            "title": "Only new videos since the last run",
            "type": "boolean",
            "description": "For schedules. Remembers the videos already delivered for each channel (in the key-value store 'youtube-channel-transcripts-only-new-videos' in your account, one record per channel) and skips them on later runs, so a daily or weekly run transcribes only new uploads and a day without uploads costs nothing. On a channel you never ran, the first runs work through the back catalogue. Videos without captions are tried again next time, free. Delete the record to start over. Default off.",
            "default": false
          },
          "includeShorts": {
            "title": "Include Shorts",
            "type": "boolean",
            "description": "Off (default): a channel gives its regular videos and past live streams. On: Shorts are listed too, which can multiply the number of videos on channels that post many Shorts, so check 'Max videos per channel' before turning it on.",
            "default": false
          },
          "languages": {
            "title": "Preferred languages",
            "type": "array",
            "description": "Caption language codes in order of preference, one per line, for example en, es, fr, ja or pt-BR. The first one a video has is used, and 'language' on the row says which. Put auto alone for the language actually spoken in each video. If none of the codes exists, the first manual caption is used, then the automatic one; turn on 'Translate when the language is missing' to always get your first language.",
            "items": {
              "type": "string"
            },
            "default": [
              "en",
              "pt",
              "pt-BR",
              "es"
            ]
          },
          "targetLanguage": {
            "title": "Language you want (optional)",
            "type": "string",
            "description": "The one language you want every transcript in, as a code such as en, es or fr, or auto for the spoken language. It goes to the top of 'Preferred languages', and a video without a caption in it is translated into it ('translatedTo' is set). Turn 'Translate when the language is missing' off to get original captions only. Also accepts 'language'. Same price."
          },
          "autoTranslate": {
            "title": "Translate when the language is missing",
            "type": "boolean",
            "description": "When a video has no caption in your first preferred language, deliver a machine translation into it instead of falling back to another language ('translatedTo' and 'translationSource' are set). Off by default; on by default when 'Language you want' is filled. Same price."
          },
          "translateTo": {
            "title": "Translate to (optional)",
            "type": "string",
            "description": "Language code to translate every transcript into, for example es or en, even when the video has captions in other languages. YouTube's translation is tried first and Google Translate when YouTube refuses; 'translatedTo' and 'translationSource' say what happened, and if both fail the original is delivered with the reason in 'translationError'. Timestamps and RAG chunks follow the translated text. Also accepts 'translate_to'."
          },
          "captionType": {
            "title": "Caption type",
            "enum": [
              "any",
              "manual",
              "auto"
            ],
            "type": "string",
            "description": "Any (default) uses the best caption available, human-made first. Manual uses only captions written by people. Auto uses only YouTube's automatic captions. A video without the requested type comes back as a free row with errorCode NO_CAPTIONS_IN_LANGUAGE. Also accepts 'transcript_type'.",
            "default": "any"
          },
          "includeSegments": {
            "title": "Include timestamped segments",
            "type": "boolean",
            "description": "On (default): adds 'segments', one object per caption line with text, start and duration in seconds, so a quote can link to its timestamp (https://youtu.be/<id>?t=<start>). Turn it off for smaller rows when you only need 'text'. Same price.",
            "default": true
          },
          "subtitleFormats": {
            "title": "Subtitle formats",
            "type": "array",
            "description": "Adds the full subtitle file to each row: 'srt', 'vtt' or both, ready for a video editor or player. Empty by default. Same price. Also accepts 'output_formats'.",
            "items": {
              "type": "string",
              "enum": [
                "srt",
                "vtt"
              ],
              "enumTitles": [
                "SRT",
                "WebVTT"
              ]
            },
            "default": []
          },
          "chunkSizeWords": {
            "title": "RAG chunks: words per chunk",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "0 (default) turns chunking off. Above 0, each video gets a 'chunks' array ready for embeddings: pieces of about this many words, cut only between caption lines, each with index, text, wordCount, startSeconds, endSeconds and a deepLink that opens the video at that second. 300 is a good start for most embedding models. The 'RAG chunks' dataset view shows one row per chunk for a direct export to a vector store. Same price.",
            "default": 0
          },
          "chunkOverlapWords": {
            "title": "RAG chunks: overlap words",
            "minimum": 0,
            "maximum": 2500,
            "type": "integer",
            "description": "Words repeated from the end of one chunk at the start of the next, so a sentence cut in two keeps its context in both. Default 50; capped at half of 'words per chunk'. Used only when 'RAG chunks: words per chunk' is above 0.",
            "default": 50
          },
          "maxItems": {
            "title": "Maximum videos in the run",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard cap on rows for the whole run, across all channels, up to 10,000. Default 50. Since you pay per transcript (US$ 0.005 each on the Free plan), this also caps the cost: 50 transcripts cost at most US$ 0.25.",
            "default": 50
          },
          "tryDatacenterFirst": {
            "title": "Try cheaper datacenter proxy first",
            "type": "boolean",
            "description": "On (default): each video is tried twice through the cheaper datacenter proxy before falling back to the proxy below. Keeps runs fast. Turn it off only if datacenter requests keep failing and you want residential from the first request.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "YouTube blocks most datacenter IPs, so residential proxy is the default fallback and is included in the price. Blocked videos are retried on fresh IPs before becoming free BLOCKED rows. Keep the default unless you have a reason to change it.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}