{
  "data": {
    "id": "mm7zKNeWAnPZWiEHh",
    "actId": "yNFXZ2tJKz5wBMxDw",
    "userId": "IYgBDiXtHOijAaUel",
    "startedAt": "2026-10-21T11:36:23.075Z",
    "finishedAt": "2026-10-21T11:36:38.234Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 15015,
      "runTimeSecs": 15.015,
      "computeUnits": 0.016683333333333335,
      "imageSizeBytes": 4411647488
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "QYo53EZkJk0prePWY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"YouTube Transcript Scraper Input\",\n  \"description\": \"Extract timestamped transcripts and rich metadata from YouTube videos, channels, and playlists, with optional AI transcription.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"Mode\",\n      \"type\": \"string\",\n      \"description\": \"What to scrape: specific videos, a channel's uploads, or a playlist.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"videos\",\n        \"channel\",\n        \"playlist\"\n      ],\n      \"enumTitles\": [\n        \"Video URLs\",\n        \"Channel uploads\",\n        \"Playlist videos\"\n      ],\n      \"default\": \"videos\",\n      \"prefill\": \"videos\"\n    },\n    \"videoUrls\": {\n      \"title\": \"Video URLs\",\n      \"type\": \"array\",\n      \"description\": \"YouTube watch URLs, youtu.be short links, Shorts/embed URLs, or plain 11-character video IDs (mode=videos). Duplicate IDs are processed once.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"prefill\": [\n        \"https://www.youtube.com/watch?v=jNQXAC9IVRw\"\n      ]\n    },\n    \"channelUrls\": {\n      \"title\": \"Channel URLs\",\n      \"type\": \"array\",\n      \"description\": \"Channel URLs or handles (mode=channel), e.g. https://www.youtube.com/@TED, https://www.youtube.com/channel/UC..., or @TED. Each channel's latest uploads are enumerated and every video is transcribed.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"maxVideosPerChannel\": {\n      \"title\": \"Max Videos per Channel\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of videos to enumerate from each channel (mode=channel). 1-1,000.\",\n      \"default\": 50,\n      \"minimum\": 1,\n      \"maximum\": 1000\n    },\n    \"playlistUrls\": {\n      \"title\": \"Playlist URLs\",\n      \"type\": \"array\",\n      \"description\": \"Playlist URLs or IDs (mode=playlist), e.g. https://www.youtube.com/playlist?list=PL... or PL.... Every video in the playlist is transcribed.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"maxVideosPerPlaylist\": {\n      \"title\": \"Max Videos per Playlist\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of videos to enumerate from each playlist (mode=playlist). 1-1,000.\",\n      \"default\": 50,\n      \"minimum\": 1,\n      \"maximum\": 1000\n    },\n    \"language\": {\n      \"title\": \"Preferred Language\",\n      \"type\": \"string\",\n      \"description\": \"Caption language to fetch. Leave Auto-detect to use the video's original language.\",\n      \"default\": \"\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"\",\n        \"af\",\n        \"sq\",\n        \"am\",\n        \"ar\",\n        \"hy\",\n        \"az\",\n        \"eu\",\n        \"be\",\n        \"bn\",\n        \"bs\",\n        \"bg\",\n        \"my\",\n        \"ca\",\n        \"ceb\",\n        \"zh-Hans\",\n        \"zh-Hant\",\n        \"co\",\n        \"hr\",\n        \"cs\",\n        \"da\",\n        \"nl\",\n        \"en\",\n        \"eo\",\n        \"et\",\n        \"fil\",\n        \"fi\",\n        \"fr\",\n        \"fy\",\n        \"gl\",\n        \"ka\",\n        \"de\",\n        \"el\",\n        \"gu\",\n        \"ht\",\n        \"ha\",\n        \"haw\",\n        \"he\",\n        \"hi\",\n        \"hmn\",\n        \"hu\",\n        \"is\",\n        \"ig\",\n        \"id\",\n        \"ga\",\n        \"it\",\n        \"ja\",\n        \"jv\",\n        \"kn\",\n        \"kk\",\n        \"km\",\n        \"rw\",\n        \"ko\",\n        \"ku\",\n        \"ky\",\n        \"lo\",\n        \"la\",\n        \"lv\",\n        \"lt\",\n        \"lb\",\n        \"mk\",\n        \"mg\",\n        \"ms\",\n        \"ml\",\n        \"mt\",\n        \"mi\",\n        \"mr\",\n        \"mn\",\n        \"ne\",\n        \"no\",\n        \"ny\",\n        \"or\",\n        \"ps\",\n        \"fa\",\n        \"pl\",\n        \"pt\",\n        \"pa\",\n        \"ro\",\n        \"ru\",\n        \"sm\",\n        \"gd\",\n        \"sr\",\n        \"sn\",\n        \"sd\",\n        \"si\",\n        \"sk\",\n        \"sl\",\n        \"so\",\n        \"st\",\n        \"es\",\n        \"su\",\n        \"sw\",\n        \"sv\",\n        \"tg\",\n        \"ta\",\n        \"tt\",\n        \"te\",\n        \"th\",\n        \"tr\",\n        \"tk\",\n        \"uk\",\n        \"ur\",\n        \"ug\",\n        \"uz\",\n        \"vi\",\n        \"cy\",\n        \"xh\",\n        \"yi\",\n        \"yo\",\n        \"zu\"\n      ],\n      \"enumTitles\": [\n        \"Auto-detect (video's original language)\",\n        \"Afrikaans\",\n        \"Albanian\",\n        \"Amharic\",\n        \"Arabic\",\n        \"Armenian\",\n        \"Azerbaijani\",\n        \"Basque\",\n        \"Belarusian\",\n        \"Bengali\",\n        \"Bosnian\",\n        \"Bulgarian\",\n        \"Burmese\",\n        \"Catalan\",\n        \"Cebuano\",\n        \"Chinese (Simplified)\",\n        \"Chinese (Traditional)\",\n        \"Corsican\",\n        \"Croatian\",\n        \"Czech\",\n        \"Danish\",\n        \"Dutch\",\n        \"English\",\n        \"Esperanto\",\n        \"Estonian\",\n        \"Filipino\",\n        \"Finnish\",\n        \"French\",\n        \"Frisian\",\n        \"Galician\",\n        \"Georgian\",\n        \"German\",\n        \"Greek\",\n        \"Gujarati\",\n        \"Haitian Creole\",\n        \"Hausa\",\n        \"Hawaiian\",\n        \"Hebrew\",\n        \"Hindi\",\n        \"Hmong\",\n        \"Hungarian\",\n        \"Icelandic\",\n        \"Igbo\",\n        \"Indonesian\",\n        \"Irish\",\n        \"Italian\",\n        \"Japanese\",\n        \"Javanese\",\n        \"Kannada\",\n        \"Kazakh\",\n        \"Khmer\",\n        \"Kinyarwanda\",\n        \"Korean\",\n        \"Kurdish\",\n        \"Kyrgyz\",\n        \"Lao\",\n        \"Latin\",\n        \"Latvian\",\n        \"Lithuanian\",\n        \"Luxembourgish\",\n        \"Macedonian\",\n        \"Malagasy\",\n        \"Malay\",\n        \"Malayalam\",\n        \"Maltese\",\n        \"Maori\",\n        \"Marathi\",\n        \"Mongolian\",\n        \"Nepali\",\n        \"Norwegian\",\n        \"Nyanja\",\n        \"Odia\",\n        \"Pashto\",\n        \"Persian\",\n        \"Polish\",\n        \"Portuguese\",\n        \"Punjabi\",\n        \"Romanian\",\n        \"Russian\",\n        \"Samoan\",\n        \"Scots Gaelic\",\n        \"Serbian\",\n        \"Shona\",\n        \"Sindhi\",\n        \"Sinhala\",\n        \"Slovak\",\n        \"Slovenian\",\n        \"Somali\",\n        \"Sesotho\",\n        \"Spanish\",\n        \"Sundanese\",\n        \"Swahili\",\n        \"Swedish\",\n        \"Tajik\",\n        \"Tamil\",\n        \"Tatar\",\n        \"Telugu\",\n        \"Thai\",\n        \"Turkish\",\n        \"Turkmen\",\n        \"Ukrainian\",\n        \"Urdu\",\n        \"Uyghur\",\n        \"Uzbek\",\n        \"Vietnamese\",\n        \"Welsh\",\n        \"Xhosa\",\n        \"Yiddish\",\n        \"Yoruba\",\n        \"Zulu\"\n      ]\n    },\n    \"includeAutoGenerated\": {\n      \"title\": \"Include Auto-Generated Captions\",\n      \"type\": \"boolean\",\n      \"prefill\": true,\n      \"description\": \"Whether to include auto-generated captions when manual captions are not available.\",\n      \"default\": true\n    },\n    \"useWhisper\": {\n      \"title\": \"Use Whisper AI fallback\",\n      \"type\": \"boolean\",\n      \"prefill\": true,\n      \"description\": \"When YouTube has no transcript (disabled captions, music-only, or blocked), download the audio and transcribe with Whisper AI (faster-whisper, CPU). Adds ~30-180 s per video. Enabled by default to guarantee transcript output even when YouTube captions are unavailable.\",\n      \"default\": true,\n      \"editor\": \"checkbox\"\n    },\n    \"whisperModel\": {\n      \"title\": \"Whisper Model\",\n      \"type\": \"string\",\n      \"description\": \"Whisper model size to use when `useWhisper` is enabled. Larger = more accurate but slower and more RAM. 'base' is balanced.\",\n      \"editor\": \"select\",\n      \"default\": \"base\",\n      \"prefill\": \"tiny\",\n      \"enum\": [\n        \"tiny\",\n        \"base\",\n        \"small\",\n        \"medium\",\n        \"large-v3-turbo\"\n      ],\n      \"enumTitles\": [\n        \"Tiny (fastest, ~39 MB)\",\n        \"Base (balanced, ~74 MB)\",\n        \"Small (~244 MB)\",\n        \"Medium (best quality/speed, ~769 MB)\",\n        \"Large-v3-turbo (highest accuracy, ~800 MB)\"\n      ]\n    },\n    \"includeWordTimings\": {\n      \"title\": \"Include Word Timings\",\n      \"type\": \"boolean\",\n      \"description\": \"Add a wordTimings array with word-level start/end times. Only auto-generated YouTube captions expose word timings; manual captions and AI transcripts do not.\",\n      \"default\": false,\n      \"prefill\": false,\n      \"editor\": \"checkbox\"\n    },\n    \"maxWhisperMinutes\": {\n      \"title\": \"Max AI Length (minutes)\",\n      \"type\": \"integer\",\n      \"description\": \"Leave unset for the legacy behavior (AI enabled with no length limit). Set to 0 explicitly to disable AI transcription. A positive value only sends videos of that length or shorter to AI. AI still requires Use Whisper AI fallback.\",\n      \"minimum\": 0,\n      \"maximum\": 1440\n    },\n    \"proxyCountry\": {\n      \"title\": \"Proxy Country\",\n      \"type\": \"string\",\n      \"description\": \"Country/region for the proxy IP. Useful if transcripts are geo-blocked in the default US region.\",\n      \"default\": \"US\",\n      \"sectionCaption\": \"Advanced\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"US\",\n        \"GB\",\n        \"CA\",\n        \"AU\",\n        \"DE\",\n        \"FR\",\n        \"JP\",\n        \"KR\",\n        \"BR\",\n        \"IN\",\n        \"MX\",\n        \"IT\",\n        \"ES\",\n        \"NL\",\n        \"PL\",\n        \"RU\",\n        \"SE\",\n        \"NO\",\n        \"DK\",\n        \"FI\",\n        \"ZA\",\n        \"SG\",\n        \"HK\",\n        \"TW\",\n        \"ID\",\n        \"MY\",\n        \"TH\",\n        \"PH\",\n        \"AR\",\n        \"CO\",\n        \"CL\"\n      ],\n      \"enumTitles\": [\n        \"United States\",\n        \"United Kingdom\",\n        \"Canada\",\n        \"Australia\",\n        \"Germany\",\n        \"France\",\n        \"Japan\",\n        \"South Korea\",\n        \"Brazil\",\n        \"India\",\n        \"Mexico\",\n        \"Italy\",\n        \"Spain\",\n        \"Netherlands\",\n        \"Poland\",\n        \"Russia\",\n        \"Sweden\",\n        \"Norway\",\n        \"Denmark\",\n        \"Finland\",\n        \"South Africa\",\n        \"Singapore\",\n        \"Hong Kong\",\n        \"Taiwan\",\n        \"Indonesia\",\n        \"Malaysia\",\n        \"Thailand\",\n        \"Philippines\",\n        \"Argentina\",\n        \"Colombia\",\n        \"Chile\"\n      ],\n      \"prefill\": \"GB\"\n    },\n    \"outputFormat\": {\n      \"title\": \"Output Format\",\n      \"type\": \"string\",\n      \"description\": \"How transcript data is included. 'full' = segments and full_text; 'text_only' = full_text only; 'segments_only' = segments only; 'srt' / 'vtt' = ready-to-use subtitle text derived from the segments.\",\n      \"default\": \"full\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"full\",\n        \"text_only\",\n        \"segments_only\",\n        \"srt\",\n        \"vtt\"\n      ],\n      \"enumTitles\": [\n        \"Full (segments + text)\",\n        \"Text Only (no segments array)\",\n        \"Segments Only (no full_text)\",\n        \"SRT subtitles\",\n        \"WebVTT subtitles\"\n      ]\n    }\n  }\n}",
    "readme": "# YouTube Caption & Whisper AI Transcript Extractor\r\n\r\nGet clean, timestamped transcripts from YouTube — single videos, whole channels, or playlists — together with the metadata you need to organize, translate, and publish the result. Every row includes the full text, timed segments, caption-track details, chapters, and channel identity, with optional AI transcription and ready-to-use SRT or WebVTT subtitles.\r\n\r\n## What this actor does\r\n\r\n- **Three collection modes:** scrape specific video URLs, every upload from one or more channels, or every video in a playlist.\r\n- **Transcripts with timing:** full text, timestamped segments (start, duration, and end), optional word-level timings for auto-generated captions, and SRT/VTT export.\r\n- **Language selection and translation:** request a caption language; when the video has no track in that language, the actor translates through YouTube's own translation targets.\r\n- **Rich video and channel metadata:** exact publish time, channel handle/URL/avatar/verification, subscriber and comment display counts, chapters, most-replayed heatmap, caption tracks, translation targets, and access/live status.\r\n- **AI fallback:** when a video has no captions at all, optional Whisper transcription produces a transcript from the audio.\r\n- **Empty fields are omitted:** if a video genuinely lacks a data point (for example, no chapters), that field is left out of the record instead of being written as `null`.\r\n\r\n## Output per video\r\n\r\n- `video_id`, `title`, `channel_name`, `channel_id` — core video and channel identity\r\n- `canonicalUrl` — canonical `https://www.youtube.com/watch?v=...` URL\r\n- `published_date` — publication date (`YYYY-MM-DD`)\r\n- `publishedAt` — exact publication timestamp with timezone\r\n- `duration_seconds`, `views`, `like_count`, `category`, `keywords`, `description`\r\n- `thumbnail` — video thumbnail URL\r\n- `channelHandle`, `channelUrl`, `channelThumbnail`, `channelVerified`\r\n- `subscriberCountText` — display text such as `6.71M subscribers`\r\n- `subscriberCount` — approximate integer parsed from the display text\r\n- `commentCountText` — display text such as `10M` (not an exact integer)\r\n- `isUnlisted`, `is_family_safe`, `is_live_content`, `is_upcoming`\r\n- `accessStatus` — `ok`, `live`, `upcoming`, `age_restricted`, `private`, `unavailable`, `region_blocked`, or `login_required`\r\n- `wasLive`, `liveStatus` — `live`, `upcoming`, or `ended_live` when applicable\r\n- `scheduledStartTime` — scheduled or actual broadcast start for live/upcoming videos\r\n- `chapters[]` — `{ title, start, duration, startText }` for videos that expose chapters\r\n- `heatmap[]` — most-replayed buckets as `{ start, duration, intensity }`\r\n- `captionTracks[]` — `{ languageCode, languageName, isAutoGenerated, isTranslatable }`\r\n- `translationLanguages[]` — `{ languageCode, languageName }` targets YouTube offers\r\n- `requested_language`, `transcript_language`, `transcript_language_name`\r\n- `language_matched` — whether the returned transcript is in the requested language\r\n- `is_auto_generated` — `true` for YouTube auto-captions, `false` for manual/translated captions or AI output\r\n- `was_translated` — `true` only when YouTube translated the transcript into the requested language\r\n- `transcript_source` — `library`, `android_player`, `playwright_dom`, or `whisper`\r\n- `available_languages[]` — every caption track YouTube offers as `{ code, name, is_auto_generated }`\r\n- `segments[]` — `{ start, dur, end, text }` (seconds with millisecond precision); omitted for `text_only`, `srt`, and `vtt`\r\n- `full_text` — the complete transcript as one string; omitted for `segments_only`, `srt`, and `vtt`\r\n- `wordTimings[]` — `{ start, end, text }` word timings, only when `includeWordTimings` is on and the source is auto-generated\r\n- `srt`, `vtt` — subtitle text when `outputFormat` is `srt` or `vtt`\r\n- `segment_count`, `transcript_available`, `success`\r\n- `error` — human-readable explanation when no transcript was produced\r\n- `errorCode` — machine-readable reason: `captions_disabled`, `no_captions`, `age_restricted`, `login_required`, `blocked`, `unavailable`, `private`, `upcoming`, `live_no_transcript`, `timeout`, `invalid_url`, or `whisper_failed`\r\n- `retryable` — whether a later run may succeed (for example, a temporary block or timeout)\r\n- `language_probability` — language-detection confidence for AI transcripts\r\n- `inputUrl` — the URL that produced this row\r\n- `scrapedAt` — ISO timestamp of the scrape\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|---|---|---|---|\r\n| `mode` | String | `videos` | `videos` (specific URLs), `channel` (channel uploads), or `playlist` (playlist videos) |\r\n| `videoUrls` | Array | – | Watch URLs, `youtu.be` links, Shorts/embed URLs, or plain 11-character IDs (mode=videos). Duplicate IDs run once. |\r\n| `channelUrls` | Array | – | Channel URLs, `@handles`, or `UC...` IDs (mode=channel) |\r\n| `maxVideosPerChannel` | Integer | `50` | Maximum videos enumerated per channel (1–1,000) |\r\n| `playlistUrls` | Array | – | Playlist URLs or playlist IDs (mode=playlist) |\r\n| `maxVideosPerPlaylist` | Integer | `50` | Maximum videos enumerated per playlist (1–1,000) |\r\n| `language` | String | Auto-detect (video's original language) | Caption language to prefer, as a two-letter code such as `en`, `es`, `ja`, or `ar` |\r\n| `includeAutoGenerated` | Boolean | `true` | Use YouTube auto-generated captions when manual captions are unavailable |\r\n| `useWhisper` | Boolean | `true` | Transcribe the audio with AI when no YouTube transcript can be retrieved |\r\n| `whisperModel` | String | `base` | `tiny`, `base`, `small`, `medium`, or `large-v3-turbo` |\r\n| `includeWordTimings` | Boolean | `false` | Include word-level timings (auto-generated captions only) |\r\n| `maxWhisperMinutes` | Integer | – | Leave unset for no length limit; `0` disables AI explicitly; a positive value caps AI to that video length. |\r\n| `proxyCountry` | String | `US` | Country for the network connection, one of the 31 supported codes |\r\n| `outputFormat` | String | `full` | `full`, `text_only`, `segments_only`, `srt`, or `vtt` |\r\n\r\n### Example: several videos with SRT subtitles\r\n\r\n```json\r\n{\r\n  \"mode\": \"videos\",\r\n  \"videoUrls\": [\r\n    \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\r\n    \"https://youtu.be/jNQXAC9IVRw\",\r\n    \"https://www.youtube.com/shorts/s5ORfA5W-M0\"\r\n  ],\r\n  \"language\": \"en\",\r\n  \"outputFormat\": \"srt\"\r\n}\r\n```\r\n\r\n### Example: every upload from a channel\r\n\r\n```json\r\n{\r\n  \"mode\": \"channel\",\r\n  \"channelUrls\": [\"https://www.youtube.com/@TED\"],\r\n  \"maxVideosPerChannel\": 25,\r\n  \"language\": \"en\",\r\n  \"includeWordTimings\": true\r\n}\r\n```\r\n\r\n### Example: a playlist translated to Spanish\r\n\r\n```json\r\n{\r\n  \"mode\": \"playlist\",\r\n  \"playlistUrls\": [\"https://www.youtube.com/playlist?list=PL1234567890abcdef\"],\r\n  \"maxVideosPerPlaylist\": 100,\r\n  \"language\": \"es\",\r\n  \"outputFormat\": \"full\"\r\n}\r\n```\r\n\r\n### Example: AI transcription for videos without captions\r\n\r\n```json\r\n{\r\n  \"mode\": \"videos\",\r\n  \"videoUrls\": [\"https://www.youtube.com/watch?v=IR1xf8jG7ug\"],\r\n  \"useWhisper\": true,\r\n  \"whisperModel\": \"small\",\r\n  \"maxWhisperMinutes\": 20\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **AI and RAG pipelines** — feed clean, timestamped transcripts into language models, search indexes, and knowledge bases.\r\n- **Content repurposing** — turn webinars, interviews, and long-form videos into articles, summaries, and social posts.\r\n- **Subtitling and localization** — export SRT/VTT and translate transcripts for multilingual audiences.\r\n- **Media monitoring** — follow a channel or playlist and collect everything its creators publish.\r\n- **Research and journalism** — quote speakers accurately with timestamps, chapters, and exact publish dates.\r\n- **Education and accessibility** — build searchable transcripts for lectures, courses, and public talks.\r\n\r\n## FAQ\r\n\r\n**Which videos can I scrape?**\r\nAny public YouTube video with manual or auto-generated captions, plus public videos without captions when AI transcription is enabled. Private, deleted, members-only, and age-restricted videos cannot be transcribed.\r\n\r\n**What happens with live, upcoming, or age-restricted videos?**\r\nThe actor returns the metadata it can see (title, channel, dates, status) with `success: false` and a truthful `accessStatus` / `errorCode`. Live streams, premieres, and age-gated videos have no transcript until they become publicly playable.\r\n\r\n**What if a video has no captions at all?**\r\nKeep `useWhisper` on and the actor transcribes the audio. `base` is a good balance; use `small` for accented speech, multiple speakers, or noisy recordings. Use `maxWhisperMinutes` to skip very long videos, or set it to `0` explicitly to turn AI off.\r\n\r\n**How does the requested language work?**\r\nThe actor first looks for a caption track in your language, then for a regional variant such as `en-GB` for `en`. If no track exists, it asks YouTube to translate an available track. `was_translated` and `language_matched` tell you exactly what happened.\r\n\r\n**Which output formats are available?**\r\n`full` returns text plus timed segments; `text_only` returns only the text; `segments_only` returns only the timed segments; `srt` and `vtt` return ready-to-use subtitle files. All formats keep the video metadata.\r\n\r\n**Can I collect a whole channel or playlist?**\r\nYes. Choose `channel` or `playlist` mode and provide one or more URLs. You can cap each target with `maxVideosPerChannel` or `maxVideosPerPlaylist`. Duplicate videos across targets are collected once.\r\n\r\n**Are word-level timestamps available?**\r\nYes, for videos with auto-generated YouTube captions. Turn on `includeWordTimings`; manually uploaded captions and AI transcripts do not expose word timings.\r\n\r\n**Do I need to set up a proxy?**\r\nNo. The actor chooses a working connection to YouTube automatically. Just fill in the input and run it.\r\n\r\n**Is this affiliated with YouTube?**\r\nNo. This is an independent, third-party actor that reads publicly available YouTube data. It is not affiliated with, endorsed by, or operated by YouTube or Google.\r\n\r\n## Limitations\r\n\r\n- YouTube sometimes blocks automated requests from cloud networks. The actor retries and switches connection paths automatically, but an occasional video may still return a truthful `success: false` row.\r\n- Age-restricted, members-only, private, deleted, live, and upcoming videos are metadata-only; they cannot be transcribed without a signed-in session.\r\n- Translation uses YouTube's own translation targets. If YouTube does not offer the requested language, the actor returns the original transcript with `language_matched: false` rather than inventing a translation. When YouTube login-walls the translation page for an automated connection, the same fallback applies.\r\n- AI transcription downloads the audio; when the connection is blocked, the actor retries through a residential path and still reports a truthful `whisper_failed` if the block persists.\r\n- Channel and playlist expansion reads YouTube's public listings and honours `maxVideosPerChannel` / `maxVideosPerPlaylist`; private, blocked or empty listings return fewer videos (or none) with a status note.\r\n- Chapters, heatmaps, and comment counts are not exposed for every video. They are omitted when YouTube does not provide them.\r\n- Subscriber and comment counts are display strings; `subscriberCount` is an approximation and `commentCountText` is not an exact integer.\r\n- AI transcription is not available for live or upcoming broadcasts, and its accuracy depends on audio quality, music, and the selected model.\r\n- Setting `maxWhisperMinutes` to `0` disables AI explicitly; leaving the field unset keeps the legacy no-length-limit behavior.\r\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "youtube-caption-and-whisper-ai-transcript",
      "title": "YouTube Caption & Whisper AI Transcript Extractor",
      "description": "Timestamped transcripts and rich metadata from YouTube videos, channels, and playlists: full text, timed segments, SRT/VTT subtitles, chapters, caption tracks, and optional AI transcription when captions are missing.",
      "version": "1.0",
      "buildTag": "latest",
      "dockerfile": "../Dockerfile",
      "readme": "# YouTube Caption & Whisper AI Transcript Extractor\r\n\r\nGet clean, timestamped transcripts from YouTube — single videos, whole channels, or playlists — together with the metadata you need to organize, translate, and publish the result. Every row includes the full text, timed segments, caption-track details, chapters, and channel identity, with optional AI transcription and ready-to-use SRT or WebVTT subtitles.\r\n\r\n## What this actor does\r\n\r\n- **Three collection modes:** scrape specific video URLs, every upload from one or more channels, or every video in a playlist.\r\n- **Transcripts with timing:** full text, timestamped segments (start, duration, and end), optional word-level timings for auto-generated captions, and SRT/VTT export.\r\n- **Language selection and translation:** request a caption language; when the video has no track in that language, the actor translates through YouTube's own translation targets.\r\n- **Rich video and channel metadata:** exact publish time, channel handle/URL/avatar/verification, subscriber and comment display counts, chapters, most-replayed heatmap, caption tracks, translation targets, and access/live status.\r\n- **AI fallback:** when a video has no captions at all, optional Whisper transcription produces a transcript from the audio.\r\n- **Empty fields are omitted:** if a video genuinely lacks a data point (for example, no chapters), that field is left out of the record instead of being written as `null`.\r\n\r\n## Output per video\r\n\r\n- `video_id`, `title`, `channel_name`, `channel_id` — core video and channel identity\r\n- `canonicalUrl` — canonical `https://www.youtube.com/watch?v=...` URL\r\n- `published_date` — publication date (`YYYY-MM-DD`)\r\n- `publishedAt` — exact publication timestamp with timezone\r\n- `duration_seconds`, `views`, `like_count`, `category`, `keywords`, `description`\r\n- `thumbnail` — video thumbnail URL\r\n- `channelHandle`, `channelUrl`, `channelThumbnail`, `channelVerified`\r\n- `subscriberCountText` — display text such as `6.71M subscribers`\r\n- `subscriberCount` — approximate integer parsed from the display text\r\n- `commentCountText` — display text such as `10M` (not an exact integer)\r\n- `isUnlisted`, `is_family_safe`, `is_live_content`, `is_upcoming`\r\n- `accessStatus` — `ok`, `live`, `upcoming`, `age_restricted`, `private`, `unavailable`, `region_blocked`, or `login_required`\r\n- `wasLive`, `liveStatus` — `live`, `upcoming`, or `ended_live` when applicable\r\n- `scheduledStartTime` — scheduled or actual broadcast start for live/upcoming videos\r\n- `chapters[]` — `{ title, start, duration, startText }` for videos that expose chapters\r\n- `heatmap[]` — most-replayed buckets as `{ start, duration, intensity }`\r\n- `captionTracks[]` — `{ languageCode, languageName, isAutoGenerated, isTranslatable }`\r\n- `translationLanguages[]` — `{ languageCode, languageName }` targets YouTube offers\r\n- `requested_language`, `transcript_language`, `transcript_language_name`\r\n- `language_matched` — whether the returned transcript is in the requested language\r\n- `is_auto_generated` — `true` for YouTube auto-captions, `false` for manual/translated captions or AI output\r\n- `was_translated` — `true` only when YouTube translated the transcript into the requested language\r\n- `transcript_source` — `library`, `android_player`, `playwright_dom`, or `whisper`\r\n- `available_languages[]` — every caption track YouTube offers as `{ code, name, is_auto_generated }`\r\n- `segments[]` — `{ start, dur, end, text }` (seconds with millisecond precision); omitted for `text_only`, `srt`, and `vtt`\r\n- `full_text` — the complete transcript as one string; omitted for `segments_only`, `srt`, and `vtt`\r\n- `wordTimings[]` — `{ start, end, text }` word timings, only when `includeWordTimings` is on and the source is auto-generated\r\n- `srt`, `vtt` — subtitle text when `outputFormat` is `srt` or `vtt`\r\n- `segment_count`, `transcript_available`, `success`\r\n- `error` — human-readable explanation when no transcript was produced\r\n- `errorCode` — machine-readable reason: `captions_disabled`, `no_captions`, `age_restricted`, `login_required`, `blocked`, `unavailable`, `private`, `upcoming`, `live_no_transcript`, `timeout`, `invalid_url`, or `whisper_failed`\r\n- `retryable` — whether a later run may succeed (for example, a temporary block or timeout)\r\n- `language_probability` — language-detection confidence for AI transcripts\r\n- `inputUrl` — the URL that produced this row\r\n- `scrapedAt` — ISO timestamp of the scrape\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|---|---|---|---|\r\n| `mode` | String | `videos` | `videos` (specific URLs), `channel` (channel uploads), or `playlist` (playlist videos) |\r\n| `videoUrls` | Array | – | Watch URLs, `youtu.be` links, Shorts/embed URLs, or plain 11-character IDs (mode=videos). Duplicate IDs run once. |\r\n| `channelUrls` | Array | – | Channel URLs, `@handles`, or `UC...` IDs (mode=channel) |\r\n| `maxVideosPerChannel` | Integer | `50` | Maximum videos enumerated per channel (1–1,000) |\r\n| `playlistUrls` | Array | – | Playlist URLs or playlist IDs (mode=playlist) |\r\n| `maxVideosPerPlaylist` | Integer | `50` | Maximum videos enumerated per playlist (1–1,000) |\r\n| `language` | String | Auto-detect (video's original language) | Caption language to prefer, as a two-letter code such as `en`, `es`, `ja`, or `ar` |\r\n| `includeAutoGenerated` | Boolean | `true` | Use YouTube auto-generated captions when manual captions are unavailable |\r\n| `useWhisper` | Boolean | `true` | Transcribe the audio with AI when no YouTube transcript can be retrieved |\r\n| `whisperModel` | String | `base` | `tiny`, `base`, `small`, `medium`, or `large-v3-turbo` |\r\n| `includeWordTimings` | Boolean | `false` | Include word-level timings (auto-generated captions only) |\r\n| `maxWhisperMinutes` | Integer | – | Leave unset for no length limit; `0` disables AI explicitly; a positive value caps AI to that video length. |\r\n| `proxyCountry` | String | `US` | Country for the network connection, one of the 31 supported codes |\r\n| `outputFormat` | String | `full` | `full`, `text_only`, `segments_only`, `srt`, or `vtt` |\r\n\r\n### Example: several videos with SRT subtitles\r\n\r\n```json\r\n{\r\n  \"mode\": \"videos\",\r\n  \"videoUrls\": [\r\n    \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\r\n    \"https://youtu.be/jNQXAC9IVRw\",\r\n    \"https://www.youtube.com/shorts/s5ORfA5W-M0\"\r\n  ],\r\n  \"language\": \"en\",\r\n  \"outputFormat\": \"srt\"\r\n}\r\n```\r\n\r\n### Example: every upload from a channel\r\n\r\n```json\r\n{\r\n  \"mode\": \"channel\",\r\n  \"channelUrls\": [\"https://www.youtube.com/@TED\"],\r\n  \"maxVideosPerChannel\": 25,\r\n  \"language\": \"en\",\r\n  \"includeWordTimings\": true\r\n}\r\n```\r\n\r\n### Example: a playlist translated to Spanish\r\n\r\n```json\r\n{\r\n  \"mode\": \"playlist\",\r\n  \"playlistUrls\": [\"https://www.youtube.com/playlist?list=PL1234567890abcdef\"],\r\n  \"maxVideosPerPlaylist\": 100,\r\n  \"language\": \"es\",\r\n  \"outputFormat\": \"full\"\r\n}\r\n```\r\n\r\n### Example: AI transcription for videos without captions\r\n\r\n```json\r\n{\r\n  \"mode\": \"videos\",\r\n  \"videoUrls\": [\"https://www.youtube.com/watch?v=IR1xf8jG7ug\"],\r\n  \"useWhisper\": true,\r\n  \"whisperModel\": \"small\",\r\n  \"maxWhisperMinutes\": 20\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **AI and RAG pipelines** — feed clean, timestamped transcripts into language models, search indexes, and knowledge bases.\r\n- **Content repurposing** — turn webinars, interviews, and long-form videos into articles, summaries, and social posts.\r\n- **Subtitling and localization** — export SRT/VTT and translate transcripts for multilingual audiences.\r\n- **Media monitoring** — follow a channel or playlist and collect everything its creators publish.\r\n- **Research and journalism** — quote speakers accurately with timestamps, chapters, and exact publish dates.\r\n- **Education and accessibility** — build searchable transcripts for lectures, courses, and public talks.\r\n\r\n## FAQ\r\n\r\n**Which videos can I scrape?**\r\nAny public YouTube video with manual or auto-generated captions, plus public videos without captions when AI transcription is enabled. Private, deleted, members-only, and age-restricted videos cannot be transcribed.\r\n\r\n**What happens with live, upcoming, or age-restricted videos?**\r\nThe actor returns the metadata it can see (title, channel, dates, status) with `success: false` and a truthful `accessStatus` / `errorCode`. Live streams, premieres, and age-gated videos have no transcript until they become publicly playable.\r\n\r\n**What if a video has no captions at all?**\r\nKeep `useWhisper` on and the actor transcribes the audio. `base` is a good balance; use `small` for accented speech, multiple speakers, or noisy recordings. Use `maxWhisperMinutes` to skip very long videos, or set it to `0` explicitly to turn AI off.\r\n\r\n**How does the requested language work?**\r\nThe actor first looks for a caption track in your language, then for a regional variant such as `en-GB` for `en`. If no track exists, it asks YouTube to translate an available track. `was_translated` and `language_matched` tell you exactly what happened.\r\n\r\n**Which output formats are available?**\r\n`full` returns text plus timed segments; `text_only` returns only the text; `segments_only` returns only the timed segments; `srt` and `vtt` return ready-to-use subtitle files. All formats keep the video metadata.\r\n\r\n**Can I collect a whole channel or playlist?**\r\nYes. Choose `channel` or `playlist` mode and provide one or more URLs. You can cap each target with `maxVideosPerChannel` or `maxVideosPerPlaylist`. Duplicate videos across targets are collected once.\r\n\r\n**Are word-level timestamps available?**\r\nYes, for videos with auto-generated YouTube captions. Turn on `includeWordTimings`; manually uploaded captions and AI transcripts do not expose word timings.\r\n\r\n**Do I need to set up a proxy?**\r\nNo. The actor chooses a working connection to YouTube automatically. Just fill in the input and run it.\r\n\r\n**Is this affiliated with YouTube?**\r\nNo. This is an independent, third-party actor that reads publicly available YouTube data. It is not affiliated with, endorsed by, or operated by YouTube or Google.\r\n\r\n## Limitations\r\n\r\n- YouTube sometimes blocks automated requests from cloud networks. The actor retries and switches connection paths automatically, but an occasional video may still return a truthful `success: false` row.\r\n- Age-restricted, members-only, private, deleted, live, and upcoming videos are metadata-only; they cannot be transcribed without a signed-in session.\r\n- Translation uses YouTube's own translation targets. If YouTube does not offer the requested language, the actor returns the original transcript with `language_matched: false` rather than inventing a translation. When YouTube login-walls the translation page for an automated connection, the same fallback applies.\r\n- AI transcription downloads the audio; when the connection is blocked, the actor retries through a residential path and still reports a truthful `whisper_failed` if the block persists.\r\n- Channel and playlist expansion reads YouTube's public listings and honours `maxVideosPerChannel` / `maxVideosPerPlaylist`; private, blocked or empty listings return fewer videos (or none) with a status note.\r\n- Chapters, heatmaps, and comment counts are not exposed for every video. They are omitted when YouTube does not provide them.\r\n- Subscriber and comment counts are display strings; `subscriberCount` is an approximation and `commentCountText` is not an exact integer.\r\n- AI transcription is not available for live or upcoming broadcasts, and its accuracy depends on audio quality, music, and the selected model.\r\n- Setting `maxWhisperMinutes` to `0` disables AI explicitly; leaving the field unset keeps the legacy no-length-limit behavior.\r\n",
      "input": {
        "title": "YouTube Transcript Scraper Input",
        "description": "Extract timestamped transcripts and rich metadata from YouTube videos, channels, and playlists, with optional AI transcription.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "Mode",
            "type": "string",
            "description": "What to scrape: specific videos, a channel's uploads, or a playlist.",
            "editor": "select",
            "enum": [
              "videos",
              "channel",
              "playlist"
            ],
            "enumTitles": [
              "Video URLs",
              "Channel uploads",
              "Playlist videos"
            ],
            "default": "videos",
            "prefill": "videos"
          },
          "videoUrls": {
            "title": "Video URLs",
            "type": "array",
            "description": "YouTube watch URLs, youtu.be short links, Shorts/embed URLs, or plain 11-character video IDs (mode=videos). Duplicate IDs are processed once.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "prefill": [
              "https://www.youtube.com/watch?v=jNQXAC9IVRw"
            ]
          },
          "channelUrls": {
            "title": "Channel URLs",
            "type": "array",
            "description": "Channel URLs or handles (mode=channel), e.g. https://www.youtube.com/@TED, https://www.youtube.com/channel/UC..., or @TED. Each channel's latest uploads are enumerated and every video is transcribed.",
            "editor": "stringList",
            "items": {
              "type": "string"
            }
          },
          "maxVideosPerChannel": {
            "title": "Max Videos per Channel",
            "type": "integer",
            "description": "Maximum number of videos to enumerate from each channel (mode=channel). 1-1,000.",
            "default": 50,
            "minimum": 1,
            "maximum": 1000
          },
          "playlistUrls": {
            "title": "Playlist URLs",
            "type": "array",
            "description": "Playlist URLs or IDs (mode=playlist), e.g. https://www.youtube.com/playlist?list=PL... or PL.... Every video in the playlist is transcribed.",
            "editor": "stringList",
            "items": {
              "type": "string"
            }
          },
          "maxVideosPerPlaylist": {
            "title": "Max Videos per Playlist",
            "type": "integer",
            "description": "Maximum number of videos to enumerate from each playlist (mode=playlist). 1-1,000.",
            "default": 50,
            "minimum": 1,
            "maximum": 1000
          },
          "language": {
            "title": "Preferred Language",
            "type": "string",
            "description": "Caption language to fetch. Leave Auto-detect to use the video's original language.",
            "default": "",
            "editor": "select",
            "enum": [
              "",
              "af",
              "sq",
              "am",
              "ar",
              "hy",
              "az",
              "eu",
              "be",
              "bn",
              "bs",
              "bg",
              "my",
              "ca",
              "ceb",
              "zh-Hans",
              "zh-Hant",
              "co",
              "hr",
              "cs",
              "da",
              "nl",
              "en",
              "eo",
              "et",
              "fil",
              "fi",
              "fr",
              "fy",
              "gl",
              "ka",
              "de",
              "el",
              "gu",
              "ht",
              "ha",
              "haw",
              "he",
              "hi",
              "hmn",
              "hu",
              "is",
              "ig",
              "id",
              "ga",
              "it",
              "ja",
              "jv",
              "kn",
              "kk",
              "km",
              "rw",
              "ko",
              "ku",
              "ky",
              "lo",
              "la",
              "lv",
              "lt",
              "lb",
              "mk",
              "mg",
              "ms",
              "ml",
              "mt",
              "mi",
              "mr",
              "mn",
              "ne",
              "no",
              "ny",
              "or",
              "ps",
              "fa",
              "pl",
              "pt",
              "pa",
              "ro",
              "ru",
              "sm",
              "gd",
              "sr",
              "sn",
              "sd",
              "si",
              "sk",
              "sl",
              "so",
              "st",
              "es",
              "su",
              "sw",
              "sv",
              "tg",
              "ta",
              "tt",
              "te",
              "th",
              "tr",
              "tk",
              "uk",
              "ur",
              "ug",
              "uz",
              "vi",
              "cy",
              "xh",
              "yi",
              "yo",
              "zu"
            ],
            "enumTitles": [
              "Auto-detect (video's original language)",
              "Afrikaans",
              "Albanian",
              "Amharic",
              "Arabic",
              "Armenian",
              "Azerbaijani",
              "Basque",
              "Belarusian",
              "Bengali",
              "Bosnian",
              "Bulgarian",
              "Burmese",
              "Catalan",
              "Cebuano",
              "Chinese (Simplified)",
              "Chinese (Traditional)",
              "Corsican",
              "Croatian",
              "Czech",
              "Danish",
              "Dutch",
              "English",
              "Esperanto",
              "Estonian",
              "Filipino",
              "Finnish",
              "French",
              "Frisian",
              "Galician",
              "Georgian",
              "German",
              "Greek",
              "Gujarati",
              "Haitian Creole",
              "Hausa",
              "Hawaiian",
              "Hebrew",
              "Hindi",
              "Hmong",
              "Hungarian",
              "Icelandic",
              "Igbo",
              "Indonesian",
              "Irish",
              "Italian",
              "Japanese",
              "Javanese",
              "Kannada",
              "Kazakh",
              "Khmer",
              "Kinyarwanda",
              "Korean",
              "Kurdish",
              "Kyrgyz",
              "Lao",
              "Latin",
              "Latvian",
              "Lithuanian",
              "Luxembourgish",
              "Macedonian",
              "Malagasy",
              "Malay",
              "Malayalam",
              "Maltese",
              "Maori",
              "Marathi",
              "Mongolian",
              "Nepali",
              "Norwegian",
              "Nyanja",
              "Odia",
              "Pashto",
              "Persian",
              "Polish",
              "Portuguese",
              "Punjabi",
              "Romanian",
              "Russian",
              "Samoan",
              "Scots Gaelic",
              "Serbian",
              "Shona",
              "Sindhi",
              "Sinhala",
              "Slovak",
              "Slovenian",
              "Somali",
              "Sesotho",
              "Spanish",
              "Sundanese",
              "Swahili",
              "Swedish",
              "Tajik",
              "Tamil",
              "Tatar",
              "Telugu",
              "Thai",
              "Turkish",
              "Turkmen",
              "Ukrainian",
              "Urdu",
              "Uyghur",
              "Uzbek",
              "Vietnamese",
              "Welsh",
              "Xhosa",
              "Yiddish",
              "Yoruba",
              "Zulu"
            ]
          },
          "includeAutoGenerated": {
            "title": "Include Auto-Generated Captions",
            "type": "boolean",
            "prefill": true,
            "description": "Whether to include auto-generated captions when manual captions are not available.",
            "default": true
          },
          "useWhisper": {
            "title": "Use Whisper AI fallback",
            "type": "boolean",
            "prefill": true,
            "description": "When YouTube has no transcript (disabled captions, music-only, or blocked), download the audio and transcribe with Whisper AI (faster-whisper, CPU). Adds ~30-180 s per video. Enabled by default to guarantee transcript output even when YouTube captions are unavailable.",
            "default": true,
            "editor": "checkbox"
          },
          "whisperModel": {
            "title": "Whisper Model",
            "type": "string",
            "description": "Whisper model size to use when `useWhisper` is enabled. Larger = more accurate but slower and more RAM. 'base' is balanced.",
            "editor": "select",
            "default": "base",
            "prefill": "tiny",
            "enum": [
              "tiny",
              "base",
              "small",
              "medium",
              "large-v3-turbo"
            ],
            "enumTitles": [
              "Tiny (fastest, ~39 MB)",
              "Base (balanced, ~74 MB)",
              "Small (~244 MB)",
              "Medium (best quality/speed, ~769 MB)",
              "Large-v3-turbo (highest accuracy, ~800 MB)"
            ]
          },
          "includeWordTimings": {
            "title": "Include Word Timings",
            "type": "boolean",
            "description": "Add a wordTimings array with word-level start/end times. Only auto-generated YouTube captions expose word timings; manual captions and AI transcripts do not.",
            "default": false,
            "prefill": false,
            "editor": "checkbox"
          },
          "maxWhisperMinutes": {
            "title": "Max AI Length (minutes)",
            "type": "integer",
            "description": "Leave unset for the legacy behavior (AI enabled with no length limit). Set to 0 explicitly to disable AI transcription. A positive value only sends videos of that length or shorter to AI. AI still requires Use Whisper AI fallback.",
            "minimum": 0,
            "maximum": 1440
          },
          "proxyCountry": {
            "title": "Proxy Country",
            "type": "string",
            "description": "Country/region for the proxy IP. Useful if transcripts are geo-blocked in the default US region.",
            "default": "US",
            "sectionCaption": "Advanced",
            "editor": "select",
            "enum": [
              "US",
              "GB",
              "CA",
              "AU",
              "DE",
              "FR",
              "JP",
              "KR",
              "BR",
              "IN",
              "MX",
              "IT",
              "ES",
              "NL",
              "PL",
              "RU",
              "SE",
              "NO",
              "DK",
              "FI",
              "ZA",
              "SG",
              "HK",
              "TW",
              "ID",
              "MY",
              "TH",
              "PH",
              "AR",
              "CO",
              "CL"
            ],
            "enumTitles": [
              "United States",
              "United Kingdom",
              "Canada",
              "Australia",
              "Germany",
              "France",
              "Japan",
              "South Korea",
              "Brazil",
              "India",
              "Mexico",
              "Italy",
              "Spain",
              "Netherlands",
              "Poland",
              "Russia",
              "Sweden",
              "Norway",
              "Denmark",
              "Finland",
              "South Africa",
              "Singapore",
              "Hong Kong",
              "Taiwan",
              "Indonesia",
              "Malaysia",
              "Thailand",
              "Philippines",
              "Argentina",
              "Colombia",
              "Chile"
            ],
            "prefill": "GB"
          },
          "outputFormat": {
            "title": "Output Format",
            "type": "string",
            "description": "How transcript data is included. 'full' = segments and full_text; 'text_only' = full_text only; 'segments_only' = segments only; 'srt' / 'vtt' = ready-to-use subtitle text derived from the segments.",
            "default": "full",
            "editor": "select",
            "enum": [
              "full",
              "text_only",
              "segments_only",
              "srt",
              "vtt"
            ],
            "enumTitles": [
              "Full (segments + text)",
              "Text Only (no segments array)",
              "Segments Only (no full_text)",
              "SRT subtitles",
              "WebVTT subtitles"
            ]
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "YouTube Caption & Whisper AI Transcript Extractor Output",
        "description": "One record per video with its transcript (segments, full text, SRT/VTT, optional word timings), caption/translation metadata, chapters, heatmap, and channel identity.",
        "properties": {
          "transcripts": {
            "type": "string",
            "title": "YouTube Transcript Scraper dataset",
            "description": "Dataset containing every scraped video transcript with timed segments and metadata.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Transcripts Overview",
              "transformation": {
                "fields": [
                  "video_id",
                  "title",
                  "channel_name",
                  "publishedAt",
                  "transcript_language",
                  "segment_count",
                  "success",
                  "transcript_available",
                  "transcript_source",
                  "accessStatus",
                  "errorCode",
                  "duration_seconds",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            },
            "transcripts": {
              "title": "Full Transcripts",
              "transformation": {
                "fields": [
                  "video_id",
                  "canonicalUrl",
                  "title",
                  "channel_name",
                  "channel_id",
                  "channelHandle",
                  "publishedAt",
                  "full_text",
                  "transcript_language",
                  "transcript_language_name",
                  "is_auto_generated",
                  "was_translated",
                  "segment_count",
                  "duration_seconds",
                  "views",
                  "published_date",
                  "segments",
                  "wordTimings",
                  "srt",
                  "vtt",
                  "available_languages",
                  "captionTracks",
                  "chapters",
                  "heatmap",
                  "transcript_source",
                  "transcript_available",
                  "accessStatus",
                  "success",
                  "errorCode",
                  "inputUrl",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.0.3",
    "imageDigest": "e426a45f86c80267189f97a9747f557db1f4591e884454581289d289c1ab5b95",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.016683333333333335
    }
  }
}