{
  "data": {
    "id": "VOgav5hJOcKjn0MxC",
    "actId": "cGTM28m4PZXzrUeWS",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-10-26T15:38:34.558Z",
    "finishedAt": "2026-10-26T15:38:43.451Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 8755,
      "runTimeSecs": 8.755,
      "computeUnits": 0.009727777777777778,
      "imageSizeBytes": 318669824
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"YouTube Video Metadata & Chapter Extractor Input\",\n  \"description\": \"Scrape metadata, chapters, heatmap and caption availability for YouTube videos or Shorts.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"required\": [\n    \"videoUrls\"\n  ],\n  \"properties\": {\n    \"videoUrls\": {\n      \"title\": \"Video URLs or IDs\",\n      \"type\": \"array\",\n      \"description\": \"YouTube watch, youtu.be, Shorts, embed or live links, or 11-character video IDs. Duplicates are removed.\",\n      \"editor\": \"stringList\",\n      \"prefill\": [\n        \"jNQXAC9IVRw\",\n        \"dQw4w9WgXcQ\",\n        \"M7lc1UVf-VE\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"minItems\": 1\n    },\n    \"maxComments\": {\n      \"title\": \"Max comments per video\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum comment texts to collect per video. Set to 0 to skip comments. The display comment count is extracted separately.\",\n      \"default\": 0,\n      \"minimum\": 0,\n      \"maximum\": 1000,\n      \"editor\": \"number\"\n    },\n    \"includeChapters\": {\n      \"title\": \"Extract chapters\",\n      \"type\": \"boolean\",\n      \"description\": \"Extract manual and automatic chapters with title, start, end and source.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeHeatmap\": {\n      \"title\": \"Extract heatmap\",\n      \"type\": \"boolean\",\n      \"description\": \"Add the Most replayed heatmap segments and labels when YouTube provides them.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"includeEndscreen\": {\n      \"title\": \"Extract endscreen\",\n      \"type\": \"boolean\",\n      \"description\": \"Extract endscreen elements shown at the end of the video.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeCards\": {\n      \"title\": \"Extract info cards\",\n      \"type\": \"boolean\",\n      \"description\": \"Extract interactive info cards embedded in the video.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"includeTranscriptMetadata\": {\n      \"title\": \"List caption tracks\",\n      \"type\": \"boolean\",\n      \"description\": \"List available caption tracks with language and manual or auto-generated status.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeTranscript\": {\n      \"title\": \"Extract transcript text\",\n      \"type\": \"boolean\",\n      \"description\": \"Download the transcript when a caption track is available. Adds one request per video.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeRelatedVideos\": {\n      \"title\": \"Max related videos\",\n      \"type\": \"integer\",\n      \"description\": \"Number of related videos to extract from the watch page sidebar. 0 skips them.\",\n      \"default\": 0,\n      \"minimum\": 0,\n      \"maximum\": 50,\n      \"editor\": \"number\"\n    }\n  }\n}",
    "readme": "# YouTube Video Metadata & Chapter Extractor\n\nGive this actor YouTube video or Short links (or bare 11-character IDs) and get one structured row per video: exact metadata, manual and automatic chapters, heatmap segments, caption-track availability, live and age status, and optional comments or transcript text. No YouTube API key, cookies, or proxy setup.\n\n## What this actor does\n\n- **Exact metadata:** title, description, channel, exact views and likes, duration, ISO publish time, category, creator keywords, thumbnails and canonical URL.\n- **Chapters:** manual creator chapters and YouTube-generated automatic chapters, each with title, start, end, source and a deep link. Description timestamps are used only when YouTube exposes no chapter panel.\n- **Heatmap:** optional Most replayed segments and YouTube's own labels. Heatmap is available when YouTube provides it and is omitted otherwise.\n- **Captions:** the full caption-track list with language, manual or auto-generated status, and a transcript when a track can be downloaded.\n- **Status:** live now, was live, upcoming, age-restricted, unlisted, family-safe, available countries and playability flags.\n- **Shorts and batches:** watch, youtu.be, Shorts, embed, live, `/v/` and mobile links or bare IDs; repeated IDs are processed once.\n- **Comments:** up to 1,000 comment texts per video when enabled. The display comment count is captured separately.\n- **Omit-empty:** a field is present only when YouTube returned real data. On a gated page some values, including caption summaries, can be unavailable rather than genuinely empty; see Limitations.\n\n## Output\n\nEach dataset row is one unique video.\n\n| Field | Type | Notes |\n|---|---|---|\n| `videoId`, `url`, `inputUrl` | string | Canonical watch URL and the original input |\n| `type`, `uploadType` | string | `video` or `short`; a Short is labelled `short` from a `/shorts/` link or the Shorts player surface |\n| `title`, `description` | string | Full values on normal pages; a gated description can be truncated to about 160 characters |\n| `channelId`, `channelName` | string | Uploader identity |\n| `channel` | object | id, name, handle, url, subscriber count/text, logo, badges |\n| `viewCount`, `likeCount` | integer | Exact values when YouTube exposes them |\n| `commentCountText` | string | Display count such as `2.4M` |\n| `commentCount` | integer | Only when the display value is an exact integer |\n| `durationSeconds` | integer | Omitted for live streams or unknown duration |\n| `publishedDate` | string | `YYYY-MM-DD` |\n| `publishedAt` | string | ISO-8601 timestamp with the original offset; omitted when YouTube hides it on a gated page |\n| `uploadDate` | string | Raw YouTube upload value |\n| `category`, `tags`, `hashtags` | string / array | Creator settings and description hashtags |\n| `thumbnails` | object | default, medium, high, standard, maxres when available |\n| `captionTracks` | array | language, name, auto-generated flag, translatable; empty when YouTube exposes none or gates the page |\n| `captionTrackCount`, `hasManualCaptions`, `hasAutoCaptions` | integer / boolean | Caption availability summary; `0`/`false` can mean \"not observed\" on a gated page |\n| `chapterSource` | string | `manual`, `auto` or `description` |\n| `chapters` | array | title, startSeconds, endSeconds, startTimeText, source, url, thumbnailUrl |\n| `heatmap` | array | startSeconds, endSeconds, intensity (when enabled) |\n| `mostReplayed` | array | YouTube's Most replayed labels (when enabled) |\n| `heatmapSegmentCount` | integer | Present only when a heatmap exists |\n| `liveStatus` | string | `live_now`, `was_live` or `upcoming`; omitted for regular uploads |\n| `isLiveNow`, `isUpcoming`, `isUnlisted`, `isFamilySafe`, `isShortsEligible` | boolean | Availability flags |\n| `isAgeGated`, `requiresLogin`, `isPlayable`, `playabilityStatus` | boolean / string | Access state |\n| `availableCountries` | array | Country codes YouTube reports |\n| `transcript` | array | Timed `{start, dur, text}` segments when available |\n| `comments` | array | Comment texts when `maxComments` > 0 |\n| `success`, `error`, `scrapedAt` | boolean / string | Result state; failure rows still carry real partial data |\n\nFailure rows are written for invalid, removed, private or region-blocked links. They keep the input URL, a real video ID when known, `success: false` and an explanatory `error`; they never invent metadata.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `videoUrls` | array | – (required) | Watch/youtu.be/Shorts/embed/live/`/v/` links or bare 11-character IDs. Duplicates are removed. |\n| `maxComments` | integer | `0` | Comment texts to collect per video (0–1000). `0` skips comments. |\n| `includeChapters` | boolean | `true` | Manual and automatic chapters with source and end times. |\n| `includeHeatmap` | boolean | `false` | Most replayed segments and labels when available. |\n| `includeEndscreen` | boolean | `true` | Endscreen elements when YouTube exposes them. |\n| `includeCards` | boolean | `false` | Info cards embedded in the player. |\n| `includeTranscriptMetadata` | boolean | `true` | Caption-track list with language and manual/auto status. |\n| `includeTranscript` | boolean | `true` | Download transcript text when a caption track is available. |\n| `includeRelatedVideos` | integer | `0` | Related sidebar videos to include (0–50). |\n\n### Example: core metadata and chapters\n\n```json\n{\n  \"videoUrls\": [\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"],\n  \"includeChapters\": true,\n  \"includeHeatmap\": false\n}\n```\n\n### Example: batch IDs with heatmap and comments\n\n```json\n{\n  \"videoUrls\": [\"jNQXAC9IVRw\", \"https://youtu.be/dQw4w9WgXcQ\", \"https://www.youtube.com/shorts/IaSm0LeErrc\"],\n  \"includeHeatmap\": true,\n  \"maxComments\": 20,\n  \"includeTranscript\": false\n}\n```\n\n## Use cases\n\n- **Content research:** compare exact views, likes, dates and chapter structure across a list of videos.\n- **SEO and publishing:** inspect titles, descriptions, tags, categories and hashtags from competitors.\n- **Retention analysis:** see which parts YouTube marks as Most replayed and how they line up with chapters.\n- **Caption and accessibility audits:** find which languages have manual captions versus auto-generated tracks.\n- **Monitoring:** re-run the same list to track view growth, live status and availability changes.\n- **AI and analytics pipelines:** feed clean, stable JSON into summaries, dashboards or datasets.\n\n## FAQ\n\n**Does it need cookies or a proxy?**\nNo. It reads public YouTube pages and public InnerTube endpoints without cookies, logins or API keys. No proxy setup is required. After a block it can retry through Apify's built-in datacenter proxy automatically; there is no proxy field and nothing to configure.\n\n**Why is `commentCount` missing when I can see a count on YouTube?**\nYouTube shows abbreviated counts such as `2.4M`. That value is returned in `commentCountText`. `commentCount` is populated only when the display value is an exact integer, so a rounded number is never presented as exact.\n\n**Why is a description short or a field missing?**\nOn Apify cloud/datacenter IPs YouTube sometimes shows a bot-check page. The actor still returns the chapters and heatmap visible on that page and recovers what it can, but some fields (publish time, duration, tags, caption tracks, transcript) may be missing and a gated description can be cut to about 160 characters. It never invents values. Re-running can recover more because the gate is per request.\n\n**Why is a heatmap missing?**\nYouTube does not publish Most replayed data for every video. It is commonly absent on live streams, very new or low-view videos, some music videos and age-restricted videos. The field is omitted rather than fabricated.\n\n**Why do some videos have no chapters?**\nOnly creators who add chapters, or videos where YouTube generates automatic chapters, have them. `chapterSource` tells you which kind was found. Videos with neither have no `chapters` field.\n\n**Are auto-generated chapters supported?**\nYes. They use YouTube's `AUTO_CHAPTERS` surface and are labelled `auto`; creator chapters are labelled `manual`.\n\n**Why are captions missing for some videos?**\nYouTube only exposes caption tracks when the uploader provided them or the platform generated them. Live streams, some age-restricted videos and bot-gated pages often have none. `captionTrackCount`, `hasManualCaptions` and `hasAutoCaptions` show what was observed; a zero on a gated page can mean \"not observed\" rather than \"no captions\".\n\n**Is the transcript always available?**\nNo. Transcript text is returned only when a caption track can be downloaded. Set `includeTranscript` to `false` to skip the extra request.\n\n**What happens for age-restricted or private videos?**\nAge-restricted videos can return real metadata with `isAgeGated: true`. Private, removed or members-only videos produce a failure row with `success: false` and the reason YouTube gave. The actor does not bypass access controls.\n\n**Does a failed link stop the run?**\nNo. Every unique input gets its own row; failures do not stop the remaining videos.\n\n**Is this affiliated with YouTube?**\nNo. It is an independent tool that reads publicly available YouTube data.\n\n## Limitations\n\n- Heatmap, automatic chapters, captions and transcripts are conditional on what YouTube publishes for each video.\n- Cloud runs can be partially gated by YouTube. Missing fields (publish time, duration, tags, caption tracks, transcript) are omitted rather than guessed; a gated description can be truncated to about 160 characters, and summary values such as `captionTrackCount: 0` can mean \"not observed\" rather than \"none\". Re-running can recover more because the gate is per request.\n- A Short is labelled `short` when the input uses a `/shorts/` link or YouTube exposes the Shorts player; a bare ID without those signals is labelled `video` (`isShortsEligible` and duration are still returned).\n- Exact comment counts and exact subscriber counts are not available from the public surfaces used here; display text is returned instead.\n- Private, members-only and login-gated content is not supported.\n- YouTube's public endpoints can intermittently ask for a bot check; the actor retries with a fresh connection before reporting a real failure.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "youtube-video-metadata-and-chapter-extractor",
      "title": "YouTube Video Metadata & Chapter Extractor",
      "description": "Get metadata for any public YouTube video or Short: exact view and like counts, publish times, manual and automatic chapters, heatmap, caption tracks, live status and comments, from a URL or video ID.",
      "version": "1.0",
      "buildTag": "latest",
      "defaultMemoryMbytes": 1024,
      "minMemoryMbytes": 1024,
      "environmentVariables": {},
      "dockerfile": "../Dockerfile",
      "input": {
        "title": "YouTube Video Metadata & Chapter Extractor Input",
        "description": "Scrape metadata, chapters, heatmap and caption availability for YouTube videos or Shorts.",
        "type": "object",
        "schemaVersion": 1,
        "required": [
          "videoUrls"
        ],
        "properties": {
          "videoUrls": {
            "title": "Video URLs or IDs",
            "type": "array",
            "description": "YouTube watch, youtu.be, Shorts, embed or live links, or 11-character video IDs. Duplicates are removed.",
            "editor": "stringList",
            "prefill": [
              "jNQXAC9IVRw",
              "dQw4w9WgXcQ",
              "M7lc1UVf-VE"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 1
          },
          "maxComments": {
            "title": "Max comments per video",
            "type": "integer",
            "description": "Maximum comment texts to collect per video. Set to 0 to skip comments. The display comment count is extracted separately.",
            "default": 0,
            "minimum": 0,
            "maximum": 1000,
            "editor": "number"
          },
          "includeChapters": {
            "title": "Extract chapters",
            "type": "boolean",
            "description": "Extract manual and automatic chapters with title, start, end and source.",
            "default": true,
            "prefill": true
          },
          "includeHeatmap": {
            "title": "Extract heatmap",
            "type": "boolean",
            "description": "Add the Most replayed heatmap segments and labels when YouTube provides them.",
            "default": false,
            "prefill": false
          },
          "includeEndscreen": {
            "title": "Extract endscreen",
            "type": "boolean",
            "description": "Extract endscreen elements shown at the end of the video.",
            "default": true,
            "prefill": false
          },
          "includeCards": {
            "title": "Extract info cards",
            "type": "boolean",
            "description": "Extract interactive info cards embedded in the video.",
            "default": false,
            "prefill": false
          },
          "includeTranscriptMetadata": {
            "title": "List caption tracks",
            "type": "boolean",
            "description": "List available caption tracks with language and manual or auto-generated status.",
            "default": true,
            "prefill": true
          },
          "includeTranscript": {
            "title": "Extract transcript text",
            "type": "boolean",
            "description": "Download the transcript when a caption track is available. Adds one request per video.",
            "default": true,
            "prefill": false
          },
          "includeRelatedVideos": {
            "title": "Max related videos",
            "type": "integer",
            "description": "Number of related videos to extract from the watch page sidebar. 0 skips them.",
            "default": 0,
            "minimum": 0,
            "maximum": 50,
            "editor": "number"
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "YouTube Video Metadata & Chapter Extractor Output",
        "description": "One record per video with exact metadata, manual and automatic chapters, heatmap segments, caption-track availability, live and age status, comments and transcript when available.",
        "properties": {
          "videos": {
            "type": "string",
            "title": "YouTube Video Details Scraper dataset",
            "description": "Dataset containing all scraped full video details, nested collections, and comments.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Overview",
              "transformation": {
                "fields": [
                  "videoId",
                  "url",
                  "title",
                  "channelName",
                  "viewCount",
                  "likeCount",
                  "commentCount",
                  "durationSeconds",
                  "publishedDate",
                  "publishedAt",
                  "category",
                  "playabilityStatus",
                  "isPlayable",
                  "isAgeGated",
                  "commentsDisabled",
                  "success"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "videoId": {
                    "label": "Video ID",
                    "format": "text"
                  },
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "channelName": {
                    "label": "Channel",
                    "format": "text"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "likeCount": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "commentCount": {
                    "label": "Comments",
                    "format": "number"
                  },
                  "durationSeconds": {
                    "label": "Duration (s)",
                    "format": "number"
                  },
                  "publishedDate": {
                    "label": "Published",
                    "format": "text"
                  },
                  "category": {
                    "label": "Category",
                    "format": "text"
                  },
                  "playabilityStatus": {
                    "label": "Playability",
                    "format": "text"
                  },
                  "isPlayable": {
                    "label": "Playable",
                    "format": "boolean"
                  },
                  "isAgeGated": {
                    "label": "Age Gated",
                    "format": "boolean"
                  },
                  "commentsDisabled": {
                    "label": "Comments Disabled",
                    "format": "boolean"
                  },
                  "success": {
                    "label": "Success",
                    "format": "boolean"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  },
                  "publishedAt": {
                    "label": "Published at",
                    "format": "text"
                  }
                }
              }
            },
            "detailed": {
              "title": "Detailed",
              "transformation": {
                "fields": [
                  "type",
                  "videoId",
                  "url",
                  "title",
                  "description",
                  "channelId",
                  "channelName",
                  "publishedDate",
                  "publishedAt",
                  "durationSeconds",
                  "viewCount",
                  "likeCount",
                  "commentCount",
                  "commentCountText",
                  "tags",
                  "category",
                  "defaultAudioLanguage",
                  "liveStatus",
                  "isLiveNow",
                  "isUpcoming",
                  "isUnlisted",
                  "engagementRate",
                  "hashtags",
                  "uploadType",
                  "resolution",
                  "isFamilySafe",
                  "isShortsEligible",
                  "thumbnails",
                  "playabilityStatus",
                  "isPlayable",
                  "isAgeGated",
                  "requiresLogin",
                  "commentsDisabled",
                  "availableCountries",
                  "captionTracks",
                  "captionTrackCount",
                  "hasManualCaptions",
                  "hasAutoCaptions",
                  "chapters",
                  "heatmap",
                  "mostReplayed",
                  "heatmapSegmentCount",
                  "chapterSource",
                  "endscreen",
                  "relatedVideos",
                  "transcript",
                  "comments",
                  "clipId",
                  "clipStartMs",
                  "clipEndMs",
                  "channel.id",
                  "channel.name",
                  "channel.handle",
                  "channel.url",
                  "channel.subscriberCount",
                  "channel.subscriberCountText",
                  "channel.badges",
                  "success",
                  "inputUrl",
                  "scrapedAt"
                ],
                "flatten": [
                  "channel"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "type": {
                    "label": "Type",
                    "format": "text"
                  },
                  "videoId": {
                    "label": "Video ID",
                    "format": "text"
                  },
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "description": {
                    "label": "Description",
                    "format": "text"
                  },
                  "channelId": {
                    "label": "Channel ID",
                    "format": "text"
                  },
                  "channelName": {
                    "label": "Channel",
                    "format": "text"
                  },
                  "publishedDate": {
                    "label": "Published",
                    "format": "text"
                  },
                  "durationSeconds": {
                    "label": "Duration (s)",
                    "format": "number"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "likeCount": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "commentCount": {
                    "label": "Comments",
                    "format": "number"
                  },
                  "tags": {
                    "label": "Tags",
                    "format": "text"
                  },
                  "category": {
                    "label": "Category",
                    "format": "text"
                  },
                  "defaultAudioLanguage": {
                    "label": "Audio Language",
                    "format": "text"
                  },
                  "liveStatus": {
                    "label": "Live Status",
                    "format": "text"
                  },
                  "isUpcoming": {
                    "label": "Upcoming",
                    "format": "boolean"
                  },
                  "isUnlisted": {
                    "label": "Unlisted",
                    "format": "boolean"
                  },
                  "engagementRate": {
                    "label": "Engagement Rate",
                    "format": "number"
                  },
                  "hashtags": {
                    "label": "Hashtags",
                    "format": "text"
                  },
                  "uploadType": {
                    "label": "Upload Type",
                    "format": "text"
                  },
                  "resolution": {
                    "label": "Resolution",
                    "format": "text"
                  },
                  "isFamilySafe": {
                    "label": "Family Safe",
                    "format": "boolean"
                  },
                  "isShortsEligible": {
                    "label": "Shorts Eligible",
                    "format": "boolean"
                  },
                  "thumbnails": {
                    "label": "Thumbnails",
                    "format": "text"
                  },
                  "playabilityStatus": {
                    "label": "Playability Status",
                    "format": "text"
                  },
                  "isPlayable": {
                    "label": "Is Playable",
                    "format": "boolean"
                  },
                  "isAgeGated": {
                    "label": "Age Gated",
                    "format": "boolean"
                  },
                  "requiresLogin": {
                    "label": "Requires Login",
                    "format": "boolean"
                  },
                  "commentsDisabled": {
                    "label": "Comments Disabled",
                    "format": "boolean"
                  },
                  "availableCountries": {
                    "label": "Available Countries",
                    "format": "text"
                  },
                  "captionTracks": {
                    "label": "Caption Tracks",
                    "format": "text"
                  },
                  "chapters": {
                    "label": "Chapters",
                    "format": "text"
                  },
                  "endscreen": {
                    "label": "Endscreen",
                    "format": "text"
                  },
                  "relatedVideos": {
                    "label": "Related Videos",
                    "format": "text"
                  },
                  "clipId": {
                    "label": "Clip ID",
                    "format": "text"
                  },
                  "clipStartMs": {
                    "label": "Clip Start (ms)",
                    "format": "number"
                  },
                  "clipEndMs": {
                    "label": "Clip End (ms)",
                    "format": "number"
                  },
                  "channel.id": {
                    "label": "Channel ID",
                    "format": "text"
                  },
                  "channel.name": {
                    "label": "Channel Name",
                    "format": "text"
                  },
                  "channel.handle": {
                    "label": "Handle",
                    "format": "text"
                  },
                  "channel.url": {
                    "label": "Channel URL",
                    "format": "link"
                  },
                  "channel.subscriberCount": {
                    "label": "Subscribers",
                    "format": "number"
                  },
                  "channel.subscriberCountText": {
                    "label": "Subscribers Text",
                    "format": "text"
                  },
                  "channel.badges": {
                    "label": "Channel Badges",
                    "format": "text"
                  },
                  "success": {
                    "label": "Success",
                    "format": "boolean"
                  },
                  "inputUrl": {
                    "label": "Input URL",
                    "format": "link"
                  },
                  "scrapedAt": {
                    "label": "Scraped At",
                    "format": "text"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  },
                  "publishedAt": {
                    "label": "Published at",
                    "format": "text"
                  },
                  "commentCountText": {
                    "label": "Comments (display)",
                    "format": "text"
                  },
                  "chapterSource": {
                    "label": "Chapter source",
                    "format": "text"
                  },
                  "heatmap": {
                    "label": "Heatmap",
                    "format": "text"
                  },
                  "mostReplayed": {
                    "label": "Most replayed",
                    "format": "text"
                  },
                  "heatmapSegmentCount": {
                    "label": "Heatmap segments",
                    "format": "number"
                  },
                  "captionTrackCount": {
                    "label": "Caption tracks",
                    "format": "number"
                  },
                  "hasManualCaptions": {
                    "label": "Manual captions",
                    "format": "boolean"
                  },
                  "hasAutoCaptions": {
                    "label": "Auto captions",
                    "format": "boolean"
                  },
                  "isLiveNow": {
                    "label": "Live now",
                    "format": "boolean"
                  },
                  "transcript": {
                    "label": "Transcript",
                    "format": "text"
                  },
                  "comments": {
                    "label": "Comments",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      },
      "readme": "# YouTube Video Metadata & Chapter Extractor\n\nGive this actor YouTube video or Short links (or bare 11-character IDs) and get one structured row per video: exact metadata, manual and automatic chapters, heatmap segments, caption-track availability, live and age status, and optional comments or transcript text. No YouTube API key, cookies, or proxy setup.\n\n## What this actor does\n\n- **Exact metadata:** title, description, channel, exact views and likes, duration, ISO publish time, category, creator keywords, thumbnails and canonical URL.\n- **Chapters:** manual creator chapters and YouTube-generated automatic chapters, each with title, start, end, source and a deep link. Description timestamps are used only when YouTube exposes no chapter panel.\n- **Heatmap:** optional Most replayed segments and YouTube's own labels. Heatmap is available when YouTube provides it and is omitted otherwise.\n- **Captions:** the full caption-track list with language, manual or auto-generated status, and a transcript when a track can be downloaded.\n- **Status:** live now, was live, upcoming, age-restricted, unlisted, family-safe, available countries and playability flags.\n- **Shorts and batches:** watch, youtu.be, Shorts, embed, live, `/v/` and mobile links or bare IDs; repeated IDs are processed once.\n- **Comments:** up to 1,000 comment texts per video when enabled. The display comment count is captured separately.\n- **Omit-empty:** a field is present only when YouTube returned real data. On a gated page some values, including caption summaries, can be unavailable rather than genuinely empty; see Limitations.\n\n## Output\n\nEach dataset row is one unique video.\n\n| Field | Type | Notes |\n|---|---|---|\n| `videoId`, `url`, `inputUrl` | string | Canonical watch URL and the original input |\n| `type`, `uploadType` | string | `video` or `short`; a Short is labelled `short` from a `/shorts/` link or the Shorts player surface |\n| `title`, `description` | string | Full values on normal pages; a gated description can be truncated to about 160 characters |\n| `channelId`, `channelName` | string | Uploader identity |\n| `channel` | object | id, name, handle, url, subscriber count/text, logo, badges |\n| `viewCount`, `likeCount` | integer | Exact values when YouTube exposes them |\n| `commentCountText` | string | Display count such as `2.4M` |\n| `commentCount` | integer | Only when the display value is an exact integer |\n| `durationSeconds` | integer | Omitted for live streams or unknown duration |\n| `publishedDate` | string | `YYYY-MM-DD` |\n| `publishedAt` | string | ISO-8601 timestamp with the original offset; omitted when YouTube hides it on a gated page |\n| `uploadDate` | string | Raw YouTube upload value |\n| `category`, `tags`, `hashtags` | string / array | Creator settings and description hashtags |\n| `thumbnails` | object | default, medium, high, standard, maxres when available |\n| `captionTracks` | array | language, name, auto-generated flag, translatable; empty when YouTube exposes none or gates the page |\n| `captionTrackCount`, `hasManualCaptions`, `hasAutoCaptions` | integer / boolean | Caption availability summary; `0`/`false` can mean \"not observed\" on a gated page |\n| `chapterSource` | string | `manual`, `auto` or `description` |\n| `chapters` | array | title, startSeconds, endSeconds, startTimeText, source, url, thumbnailUrl |\n| `heatmap` | array | startSeconds, endSeconds, intensity (when enabled) |\n| `mostReplayed` | array | YouTube's Most replayed labels (when enabled) |\n| `heatmapSegmentCount` | integer | Present only when a heatmap exists |\n| `liveStatus` | string | `live_now`, `was_live` or `upcoming`; omitted for regular uploads |\n| `isLiveNow`, `isUpcoming`, `isUnlisted`, `isFamilySafe`, `isShortsEligible` | boolean | Availability flags |\n| `isAgeGated`, `requiresLogin`, `isPlayable`, `playabilityStatus` | boolean / string | Access state |\n| `availableCountries` | array | Country codes YouTube reports |\n| `transcript` | array | Timed `{start, dur, text}` segments when available |\n| `comments` | array | Comment texts when `maxComments` > 0 |\n| `success`, `error`, `scrapedAt` | boolean / string | Result state; failure rows still carry real partial data |\n\nFailure rows are written for invalid, removed, private or region-blocked links. They keep the input URL, a real video ID when known, `success: false` and an explanatory `error`; they never invent metadata.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `videoUrls` | array | – (required) | Watch/youtu.be/Shorts/embed/live/`/v/` links or bare 11-character IDs. Duplicates are removed. |\n| `maxComments` | integer | `0` | Comment texts to collect per video (0–1000). `0` skips comments. |\n| `includeChapters` | boolean | `true` | Manual and automatic chapters with source and end times. |\n| `includeHeatmap` | boolean | `false` | Most replayed segments and labels when available. |\n| `includeEndscreen` | boolean | `true` | Endscreen elements when YouTube exposes them. |\n| `includeCards` | boolean | `false` | Info cards embedded in the player. |\n| `includeTranscriptMetadata` | boolean | `true` | Caption-track list with language and manual/auto status. |\n| `includeTranscript` | boolean | `true` | Download transcript text when a caption track is available. |\n| `includeRelatedVideos` | integer | `0` | Related sidebar videos to include (0–50). |\n\n### Example: core metadata and chapters\n\n```json\n{\n  \"videoUrls\": [\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"],\n  \"includeChapters\": true,\n  \"includeHeatmap\": false\n}\n```\n\n### Example: batch IDs with heatmap and comments\n\n```json\n{\n  \"videoUrls\": [\"jNQXAC9IVRw\", \"https://youtu.be/dQw4w9WgXcQ\", \"https://www.youtube.com/shorts/IaSm0LeErrc\"],\n  \"includeHeatmap\": true,\n  \"maxComments\": 20,\n  \"includeTranscript\": false\n}\n```\n\n## Use cases\n\n- **Content research:** compare exact views, likes, dates and chapter structure across a list of videos.\n- **SEO and publishing:** inspect titles, descriptions, tags, categories and hashtags from competitors.\n- **Retention analysis:** see which parts YouTube marks as Most replayed and how they line up with chapters.\n- **Caption and accessibility audits:** find which languages have manual captions versus auto-generated tracks.\n- **Monitoring:** re-run the same list to track view growth, live status and availability changes.\n- **AI and analytics pipelines:** feed clean, stable JSON into summaries, dashboards or datasets.\n\n## FAQ\n\n**Does it need cookies or a proxy?**\nNo. It reads public YouTube pages and public InnerTube endpoints without cookies, logins or API keys. No proxy setup is required. After a block it can retry through Apify's built-in datacenter proxy automatically; there is no proxy field and nothing to configure.\n\n**Why is `commentCount` missing when I can see a count on YouTube?**\nYouTube shows abbreviated counts such as `2.4M`. That value is returned in `commentCountText`. `commentCount` is populated only when the display value is an exact integer, so a rounded number is never presented as exact.\n\n**Why is a description short or a field missing?**\nOn Apify cloud/datacenter IPs YouTube sometimes shows a bot-check page. The actor still returns the chapters and heatmap visible on that page and recovers what it can, but some fields (publish time, duration, tags, caption tracks, transcript) may be missing and a gated description can be cut to about 160 characters. It never invents values. Re-running can recover more because the gate is per request.\n\n**Why is a heatmap missing?**\nYouTube does not publish Most replayed data for every video. It is commonly absent on live streams, very new or low-view videos, some music videos and age-restricted videos. The field is omitted rather than fabricated.\n\n**Why do some videos have no chapters?**\nOnly creators who add chapters, or videos where YouTube generates automatic chapters, have them. `chapterSource` tells you which kind was found. Videos with neither have no `chapters` field.\n\n**Are auto-generated chapters supported?**\nYes. They use YouTube's `AUTO_CHAPTERS` surface and are labelled `auto`; creator chapters are labelled `manual`.\n\n**Why are captions missing for some videos?**\nYouTube only exposes caption tracks when the uploader provided them or the platform generated them. Live streams, some age-restricted videos and bot-gated pages often have none. `captionTrackCount`, `hasManualCaptions` and `hasAutoCaptions` show what was observed; a zero on a gated page can mean \"not observed\" rather than \"no captions\".\n\n**Is the transcript always available?**\nNo. Transcript text is returned only when a caption track can be downloaded. Set `includeTranscript` to `false` to skip the extra request.\n\n**What happens for age-restricted or private videos?**\nAge-restricted videos can return real metadata with `isAgeGated: true`. Private, removed or members-only videos produce a failure row with `success: false` and the reason YouTube gave. The actor does not bypass access controls.\n\n**Does a failed link stop the run?**\nNo. Every unique input gets its own row; failures do not stop the remaining videos.\n\n**Is this affiliated with YouTube?**\nNo. It is an independent tool that reads publicly available YouTube data.\n\n## Limitations\n\n- Heatmap, automatic chapters, captions and transcripts are conditional on what YouTube publishes for each video.\n- Cloud runs can be partially gated by YouTube. Missing fields (publish time, duration, tags, caption tracks, transcript) are omitted rather than guessed; a gated description can be truncated to about 160 characters, and summary values such as `captionTrackCount: 0` can mean \"not observed\" rather than \"none\". Re-running can recover more because the gate is per request.\n- A Short is labelled `short` when the input uses a `/shorts/` link or YouTube exposes the Shorts player; a bare ID without those signals is labelled `video` (`isShortsEligible` and duration are still returned).\n- Exact comment counts and exact subscriber counts are not available from the public surfaces used here; display text is returned instead.\n- Private, members-only and login-gated content is not supported.\n- YouTube's public endpoints can intermittently ask for a bot check; the actor retries with a fresh connection before reporting a real failure.\n"
    },
    "buildNumber": "1.0.2",
    "imageDigest": "069031b15a5e358b8c968ea588d141696ecac0ff87a1541522b009fdf6bd702d",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.009727777777777778
    }
  }
}