{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Transcript Scraper - Captions, SRT, AI Transcription",
    "description": "Get YouTube transcripts and subtitles from video, Shorts, channel, playlist or search links as text, timestamps, SRT or VTT. Any caption language or translated; AI audio transcription when a video has no captions. Only-new-videos mode for schedules. For AI agents, MCP and n8n. Pay per transcript.",
    "version": "0.1",
    "x-build-id": "Scn9LKApuCE0Na6q3"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapewise~youtube-transcript/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapewise-youtube-transcript",
        "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-transcript/runs": {
      "post": {
        "operationId": "runs-sync-scrapewise-youtube-transcript",
        "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-transcript/run-sync": {
      "post": {
        "operationId": "run-sync-scrapewise-youtube-transcript",
        "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": {
          "videoUrls": {
            "title": "Video, channel, playlist or search URLs",
            "type": "array",
            "description": "One per line, mixed freely. Videos: any YouTube URL (watch, youtu.be, Shorts, live, embed, m. or music.) or a bare 11-character id such as dQw4w9WgXcQ; each video gives one row. Channels (https://www.youtube.com/@veritasium, /channel/UC..., /c/..., /user/...), playlists (any URL with list=) and search URLs (/results?search_query=...) are expanded into their videos, newest first for channels, up to 'Max videos per channel, playlist or search'. Listing is free; you pay per transcript delivered. The same video in several URL formats is delivered and charged once. Also accepts 'videoUrl', 'youtube_url', 'urls', 'startUrls', 'video_urls' and 'videoIds'.",
            "items": {
              "type": "string"
            }
          },
          "searchQueries": {
            "title": "Search terms (optional)",
            "type": "array",
            "description": "Search terms, one per line, for example python asyncio explained. Each term is searched on YouTube and the top video results are transcribed (videos only, no channels or playlists), up to 'Max videos per channel, playlist or search'. 'sourceUrl' on each row says which search found it. Turn on 'Include Shorts' to keep Shorts in the results.",
            "items": {
              "type": "string"
            }
          },
          "languages": {
            "title": "Preferred languages",
            "type": "array",
            "description": "Caption language codes in order of preference, one per line, for example en, es, fr, de, ja or pt-BR. The first one the video has is used; 'language' on the row says which. Put auto alone to get the language actually spoken in the video. If none of the codes exists, the video's first manual caption is used, then the automatic one; turn on 'Translate when the language is missing' to always get your first language instead.",
            "items": {
              "type": "string"
            },
            "default": [
              "en",
              "pt",
              "pt-BR",
              "es"
            ]
          },
          "maxItems": {
            "title": "Maximum videos in the run",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard cap on rows for the whole run, across every video, channel, playlist and search, 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
          },
          "maxVideosPerSource": {
            "title": "Max videos per channel, playlist or search",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "How many videos to take from each channel, playlist or search, up to 5,000. Default 10. Channels are listed newest first from the Videos and Live tabs, playlists in playlist order, searches in YouTube's ranking. Combine with 'Only videos published after' to take only recent uploads. Also accepts 'max_videos'.",
            "default": 10
          },
          "publishedAfter": {
            "title": "Only videos published after",
            "type": "string",
            "description": "Skip videos published before this date, as YYYY-MM-DD (for example 2026-01-01). Applies to every input, including single videos. Skipped videos produce no row and are not charged. 'start_date' and 'end_date' from other transcript actors also work."
          },
          "includeShorts": {
            "title": "Include Shorts",
            "type": "boolean",
            "description": "Off (default): a channel gives its regular videos and past live streams, and a search gives regular videos. On: Shorts are listed too. Shorts sent directly as youtube.com/shorts/ URLs are always transcribed, with this setting on or off.",
            "default": false
          },
          "onlyNewVideos": {
            "title": "Only new videos since the last run",
            "type": "boolean",
            "description": "For schedules. Remembers which videos of each channel, playlist or search already got a transcript (in the key-value store 'youtube-transcript-only-new-videos' in your account) and skips them on later runs, so a daily run transcribes only new uploads and a day without uploads costs nothing. Videos that came back without captions are tried again next time, free. Delete the store to start over. Default off.",
            "default": false
          },
          "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' (any, manual, generated).",
            "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 you can link a quote to its timestamp (https://youtu.be/<id>?t=<start>) or chunk text for RAG. Turn it off for smaller rows when you only need the plain 'text'. Same price.",
            "default": true
          },
          "includeVideoStatus": {
            "title": "Include video status (public, unlisted, private, removed)",
            "type": "boolean",
            "description": "Adds 'videoStatus' (public, unlisted, private or removed) and 'publishDate' (as YouTube shows it, in the channel's time zone) to every row. Off by default so existing outputs keep the same columns. No extra charge, and rows without a transcript stay free.",
            "default": false
          },
          "subtitleFormats": {
            "title": "Subtitle files in the output",
            "type": "array",
            "description": "Adds the full subtitle file to each row: 'srt', 'vtt' or both, ready to load into a video editor or player. Empty by default (plain text and segments only). Same price. Also accepts 'output_formats' (srt, vtt, text).",
            "items": {
              "type": "string",
              "enum": [
                "srt",
                "vtt"
              ],
              "enumTitles": [
                "SRT",
                "WebVTT"
              ]
            },
            "default": []
          },
          "translateTo": {
            "title": "Translate to (optional)",
            "type": "string",
            "description": "Language code to translate every transcript into, for example en or es, 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 are kept. Same price. Also accepts 'translate_to'."
          },
          "autoTranslate": {
            "title": "Translate when the language is missing",
            "type": "boolean",
            "description": "When the video has no caption in your first preferred language, deliver a machine translation into that language instead of falling back to another one ('translatedTo' and 'translationSource' are set). Off by default; on by default when 'Transcript language' is filled. Same price."
          },
          "transcribeAudioIfNoCaptions": {
            "title": "Transcribe the audio when a video has no captions",
            "type": "boolean",
            "description": "Videos with no captions at all are transcribed from their audio with Whisper running inside the Actor (no API key, about 99 languages, language detected automatically). Rows get transcriptSource 'audio' and audioMinutes. Costs the transcript price plus US$ 0.015 per started minute of audio. Slower: about 15 to 60 seconds per audio minute, so give the run 2 to 4 GB of memory. Videos with captions are never affected. Default off.",
            "default": false
          },
          "maxAudioMinutes": {
            "title": "Longest video to transcribe from audio (minutes)",
            "minimum": 1,
            "maximum": 240,
            "type": "integer",
            "description": "Longest video, in minutes, to transcribe from audio when it has no captions. Default 30. Longer videos come back as a free row with errorCode AUDIO_TOO_LONG. Use it to cap the audio charge of US$ 0.015 per minute: 30 minutes cost at most US$ 0.455 per video.",
            "default": 30
          },
          "videoUrl": {
            "title": "Single video URL (optional)",
            "type": "string",
            "description": "A single video URL, for integrations that send one video per call (n8n, Make, Zapier). Same field name as other transcript scrapers, so you can switch without changing your workflow. It is merged with the URL list above; leave empty if you use the list."
          },
          "targetLanguage": {
            "title": "Transcript language (optional)",
            "type": "string",
            "description": "The one language you want the transcript in, as a code such as en, fr or de, or auto for the spoken language. It goes to the top of 'Preferred languages'; if the video has no caption in it, the transcript is translated into it and 'translatedTo' is set. Turn 'Translate when the language is missing' off to get the original captions instead. Also accepts 'language'."
          },
          "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 and the cost inside the price. Turn it off only if datacenter requests keep failing for your videos 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}