{
  "data": {
    "id": "0FNJCUuVaIotK9dva",
    "actId": "cykekv5MVPOSaBpoP",
    "userId": "9Um4NEFR7z42j35AD",
    "startedAt": "2026-10-04T15:59:10.182Z",
    "finishedAt": "2026-10-04T15:59:33.243Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 22955,
      "runTimeSecs": 22.955,
      "computeUnits": 0.025505555555555556,
      "imageSizeBytes": 537077760
    },
    "options": {
      "useCache": false,
      "betaPackages": false,
      "tag": "release-candidate",
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"YouTube Metrics Scraper input\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"startUrls\": {\n      \"title\": \"YouTube post or channel URLs\",\n      \"type\": \"array\",\n      \"description\": \"Paste YouTube video URLs, Shorts URLs, video IDs, channel URLs, channel IDs, or @handles. Direct posts become metric rows. Channel inputs discover public posts first, then collect the same metrics.\",\n      \"editor\": \"stringList\",\n      \"sectionCaption\": \"Inputs\",\n      \"sectionDescription\": \"Add direct YouTube posts, channel URLs, or @handles. The actor auto-detects each input and returns one metric row per resolved video or Short.\",\n      \"minItems\": 0,\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^\\\\s*\\\\S[\\\\s\\\\S]*$\"\n      },\n      \"prefill\": [\n        \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"\n      ],\n      \"default\": []\n    },\n    \"maxItems\": {\n      \"title\": \"Optional total row cap\",\n      \"type\": \"integer\",\n      \"description\": \"Optional maximum metric rows across direct posts and channel discovery. Leave blank to process every public item the Actor can find. Large values such as 999999 are accepted.\",\n      \"editor\": \"number\",\n      \"minimum\": 1\n    },\n    \"channelSort\": {\n      \"title\": \"Channel post order\",\n      \"type\": \"string\",\n      \"description\": \"Choose the public channel discovery order.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"recent\",\n        \"popular\",\n        \"oldest\"\n      ],\n      \"enumTitles\": [\n        \"Newest\",\n        \"Most popular\",\n        \"Oldest\"\n      ],\n      \"default\": \"recent\"\n    },\n    \"publishedAfter\": {\n      \"title\": \"Published on or after\",\n      \"type\": \"string\",\n      \"description\": \"Only keep discovered channel posts published on or after this YYYY-MM-DD date.\",\n      \"editor\": \"textfield\",\n      \"pattern\": \"^$|^\\\\d{4}-\\\\d{2}-\\\\d{2}$\",\n      \"default\": \"\"\n    },\n    \"publishedBefore\": {\n      \"title\": \"Published on or before\",\n      \"type\": \"string\",\n      \"description\": \"Only keep discovered channel posts published on or before this YYYY-MM-DD date.\",\n      \"editor\": \"textfield\",\n      \"pattern\": \"^$|^\\\\d{4}-\\\\d{2}-\\\\d{2}$\",\n      \"default\": \"\"\n    },\n    \"maxAgeDays\": {\n      \"title\": \"Only last N days\",\n      \"type\": \"integer\",\n      \"description\": \"Only keep discovered channel posts from the last N days. This combines with Published on or after by using the newer lower-bound date.\",\n      \"editor\": \"number\",\n      \"minimum\": 1\n    },\n    \"titleIncludes\": {\n      \"title\": \"Title contains\",\n      \"type\": \"array\",\n      \"description\": \"Only keep discovered channel posts whose public title contains at least one of these phrases.\",\n      \"editor\": \"stringList\",\n      \"default\": [],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"titleExcludes\": {\n      \"title\": \"Title does not contain\",\n      \"type\": \"array\",\n      \"description\": \"Skip discovered channel posts whose public title contains any of these phrases.\",\n      \"editor\": \"stringList\",\n      \"default\": [],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy configuration\",\n      \"type\": \"object\",\n      \"description\": \"Use Apify Proxy for public YouTube requests. The default is enabled because direct cloud requests are commonly challenged by YouTube.\",\n      \"editor\": \"proxy\",\n      \"sectionCaption\": \"Advanced run settings\",\n      \"sectionDescription\": \"Tune public request behavior and failure semantics. Defaults are recommended for most users.\",\n      \"default\": {\n        \"useApifyProxy\": true\n      }\n    },\n    \"requestTimeoutSecs\": {\n      \"title\": \"Request timeout\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum seconds to wait for each public YouTube request.\",\n      \"editor\": \"number\",\n      \"default\": 20,\n      \"minimum\": 5\n    },\n    \"maxConcurrency\": {\n      \"title\": \"Max concurrency\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of YouTube requests to resolve at the same time.\",\n      \"editor\": \"number\",\n      \"default\": 8,\n      \"minimum\": 1\n    },\n    \"failOnNoMetrics\": {\n      \"title\": \"Fail when no metrics are exposed\",\n      \"type\": \"boolean\",\n      \"description\": \"Fail the run if none of the input URLs expose public metrics. Individual URLs without metrics still emit rows with structured statuses.\",\n      \"editor\": \"checkbox\",\n      \"default\": false\n    }\n  }\n}",
    "readme": "# YouTube Metrics Scraper\n\n## 📊 What does YouTube Metrics Scraper do?\n\nYouTube Metrics Scraper collects public metrics for YouTube videos, Shorts, live\nposts, and channel uploads. Paste known post URLs to measure them directly, or\npaste channel URLs, channel IDs, and `@handles` to discover public uploads\nfirst.\n\nUse it when you need clean YouTube data for creator research, influencer\nreporting, campaign tracking, competitor monitoring, social analytics,\ndashboards, warehouse loads, and scheduled metric snapshots.\n\nThe Actor returns flat CSV/API-friendly rows with views, likes, comments, Shorts\nremixes, subscriber counts, IDs, titles, descriptions, publish dates,\ncollaboration channels, row statuses, and per-metric quality labels.\n\nThis Actor does not log in, use cookies, scrape private YouTube content, collect\ncomment text, download videos, return dislikes, or access YouTube Studio\nanalytics. It only returns data that is publicly available at run time.\n\nWith YouTube Metrics Scraper, you can:\n\n- 📈 Track public performance for known YouTube videos, Shorts, and live posts.\n- 🎬 Measure videos and Shorts side by side in one normalized dataset.\n- 👤 Discover public uploads from channel URLs, channel IDs, and `@handles`.\n- 🔥 Sort discovered channel posts by newest, most popular, or oldest.\n- 💬 Collect public views, likes, comments, and Shorts remix counts when\n  available.\n- 👥 Add public channel subscriber counts and channel identity fields.\n- 🤝 Capture owner and collaborator channels when YouTube identifies them\n  publicly.\n- 🧭 Keep unavailable metrics as unavailable instead of turning them into fake\n  zeroes.\n- 📦 Export results as JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n\n## ✨ What You Get\n\nEach dataset row represents one YouTube video, Short, live post, or discovered\nchannel post.\n\n| Data group         | Example fields                                                              |\n| ------------------ | --------------------------------------------------------------------------- |\n| 🔗 URL identity    | `inputUrl`, `postUrl`                                                       |\n| 🆔 YouTube IDs     | `postId`, `postType`, `isShort`, `channelId`, `channelHandle`, `channelUrl` |\n| 🧾 Post details    | `title`, `description`, `publishedAt`, `isLive`                             |\n| 📊 Post metrics    | `views`, `likes`, `comments`, `remixes`                                     |\n| 👥 Channel metrics | `channelSubscribersCount`                                                   |\n| 🎯 Metric quality  | `postMetricStatus`, `channelMetricStatus`                                   |\n| 🤝 Collaborations  | `collaborationCount`, `collaborationChannels`                               |\n| 🚦 Row status      | `status`, `scrapedAt`                                                       |\n\nMetric availability depends on what YouTube exposes publicly for each post or\nchannel. Some public counters are exact, some are rounded, and some are hidden\nor delayed. Missing counts stay missing; they are not guessed and they are not\nreplaced with `0`.\n\n## ⚙️ Can I use this Actor through an API?\n\nYes. You can run YouTube Metrics Scraper manually in Apify Console or use it\nthrough:\n\n- Apify API\n- Python SDK\n- Node.js SDK\n- Webhooks\n- Scheduled runs\n- Apify integrations\n\nThis makes it useful for social media dashboards, influencer lists, competitive\nintelligence, creator databases, campaign reporting, content audits, data\nwarehouses, and automated market research workflows.\n\n## 🎯 Why scrape YouTube video, Shorts, and channel metrics?\n\nYouTube public metrics help you understand which creators, channels, videos,\nShorts, campaigns, and competitors are gaining traction.\n\n| Use case                     | How YouTube metric data helps                                                        |\n| ---------------------------- | ------------------------------------------------------------------------------------ |\n| 📈 Track creator performance | Monitor public views, likes, comments, and subscriber context over time.             |\n| 🎬 Compare content formats   | Compare videos, Shorts, and live posts in one flat export.                           |\n| 📣 Measure campaigns         | Collect repeatable snapshots for sponsored videos, creator deliverables, and drops.  |\n| 🕵️ Monitor competitors       | Track known competitor videos or discover channel uploads before collecting metrics. |\n| 🔥 Research top content      | Pull popular channel posts and compare the strongest public performers.              |\n| 🧱 Build reporting workflows | Feed normalized YouTube rows into dashboards, spreadsheets, and BI tools.            |\n| 🔎 Audit metric availability | Separate available, rounded, unavailable, and failed rows cleanly.                   |\n\n## 💵 Pricing Event\n\nYouTube Metrics Scraper uses pay-per-result pricing. One result means one\nYouTube video, Short, live post, or discovered channel post metric row written\nto the default dataset.\n\nEvery direct post input is processed by default. Use the optional `maxItems`\nsetting only when you want a total row cap. Use `maxItemsPerChannel` to control\nchannel discovery. Start with a small batch of 3 to 10 URLs when testing. The\nrun summary and row statuses show which URLs resolved, which returned public\nmetrics, and whether any inputs failed or were unsupported.\n\n## 🚀 How do I use YouTube Metrics Scraper?\n\n1. Create or log in to your Apify account.\n2. Open **YouTube Metrics Scraper**.\n3. Paste YouTube video URLs, Shorts URLs, channel URLs, channel IDs, `@handles`,\n   or a mix of them.\n4. Set an optional total row cap, or leave it blank to process every direct input.\n5. Choose the channel post order if you are using channel discovery.\n6. Leave the default settings for your first run.\n7. Click **Start**.\n8. Open the **Output** tab to inspect the dataset and run summary.\n9. Download your data in JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n\n## ⬇️ Input\n\nThe main input is `startUrls`. Paste at least one YouTube post URL, channel URL,\nchannel ID, raw video ID, or `@handle`. Direct posts and channel inputs can be\nmixed in the same run.\n\n```json\n{\n    \"startUrls\": [\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"],\n    \"proxyConfiguration\": {\n        \"useApifyProxy\": true\n    }\n}\n```\n\n### 🔗 YouTube URLs and handles\n\nSupported input shapes include:\n\n```text\nhttps://www.youtube.com/watch?v=VIDEO_ID\nhttps://youtu.be/VIDEO_ID\nhttps://www.youtube.com/shorts/VIDEO_ID\nhttps://www.youtube.com/embed/VIDEO_ID\nVIDEO_ID\nhttps://www.youtube.com/@handle\nhttps://www.youtube.com/@handle/videos\nhttps://www.youtube.com/@handle/shorts\n@handle\nhttps://www.youtube.com/channel/UC...\nUC...\n```\n\nBest results usually come from public post URLs and public channel pages that\nopen in a logged-out browser.\n\n### 📺 Channel discovery\n\nUse channel discovery when you want the Actor to find public posts from a\nYouTube channel before collecting metrics.\n\n```json\n{\n    \"startUrls\": [\"@MrBeast\"],\n    \"channelSort\": \"popular\",\n    \"maxItemsPerChannel\": 25\n}\n```\n\nChannel inputs discover public videos, Shorts, and live replays, then return the\nsame row shape as direct post URLs.\n\n### 🎛️ Settings\n\n| Option               | What it does                                                                              |\n| -------------------- | ----------------------------------------------------------------------------------------- |\n| `startUrls`          | YouTube post URLs, raw video IDs, channel URLs, channel IDs, `@handles`, or mixed inputs. |\n| `maxItems`           | Optional total row cap. Leave blank to process every direct post input.                   |\n| `maxItemsPerChannel` | Maximum public posts to discover from each channel input.                                 |\n| `channelSort`        | `recent`, `popular`, or `oldest` channel discovery order.                                 |\n| `publishedAfter`     | Only keep discovered channel posts published on or after a `YYYY-MM-DD` date.             |\n| `publishedBefore`    | Only keep discovered channel posts published on or before a `YYYY-MM-DD` date.            |\n| `maxAgeDays`         | Only keep discovered channel posts from the last N days.                                  |\n| `titleIncludes`      | Only keep discovered channel posts whose public title contains one of these phrases.      |\n| `titleExcludes`      | Skip discovered channel posts whose public title contains any of these phrases.           |\n| `maxConcurrency`     | Controls how many YouTube posts are resolved at the same time.                            |\n| `requestTimeoutSecs` | Maximum wait time for each public YouTube request.                                        |\n| `failOnNoMetrics`    | Fails the run if none of the input URLs expose public metrics.                            |\n\n## ⬆️ Output sample\n\nUseful metric results are stored in the default dataset. Each result is one YouTube metric\nrow.\n\n```json\n{\n    \"inputUrl\": \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\n    \"postUrl\": \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\n    \"postId\": \"dQw4w9WgXcQ\",\n    \"postType\": \"video\",\n    \"isShort\": false,\n    \"title\": \"Example YouTube video title\",\n    \"description\": \"Example public description\",\n    \"publishedAt\": \"2009-10-25\",\n    \"channelId\": \"UCuAXFkgsw1L7xaCfnd5JJOw\",\n    \"channelHandle\": \"@Example\",\n    \"channelUrl\": \"https://www.youtube.com/@Example\",\n    \"views\": 123456789,\n    \"likes\": 1234567,\n    \"comments\": 12345,\n    \"remixes\": null,\n    \"postMetricStatus\": [\n        {\n            \"metric\": \"views\",\n            \"value\": 123456789,\n            \"status\": \"present\",\n            \"precision\": \"exact\"\n        },\n        {\n            \"metric\": \"likes\",\n            \"value\": 1234567,\n            \"status\": \"present\",\n            \"precision\": \"exact\"\n        },\n        {\n            \"metric\": \"comments\",\n            \"value\": 12345,\n            \"status\": \"present\",\n            \"precision\": \"display_rounded\"\n        }\n    ],\n    \"collaborationCount\": 1,\n    \"collaborationChannels\": [\n        {\n            \"id\": \"UCuAXFkgsw1L7xaCfnd5JJOw\",\n            \"handle\": \"@Example\",\n            \"url\": \"https://www.youtube.com/@Example\",\n            \"role\": \"owner\"\n        }\n    ],\n    \"channelSubscribersCount\": 4510000,\n    \"channelMetricStatus\": [\n        {\n            \"metric\": \"channelSubscribersCount\",\n            \"value\": 4510000,\n            \"status\": \"present\",\n            \"precision\": \"display_rounded\"\n        }\n    ],\n    \"status\": \"ok\",\n    \"scrapedAt\": \"2026-06-24T00:00:00.000Z\",\n    \"isLive\": false\n}\n```\n\n`inputUrl` preserves the input that produced the row. `postUrl` is the resolved\npublic YouTube post URL. For Shorts, `postUrl` uses the public Shorts URL shape.\n\n## 🎯 Metric status\n\nYouTube can expose exact, rounded, delayed, or unavailable counters depending on\nthe post type, channel settings, geography, and current public page state.\n\nThe status fields help you separate:\n\n- `present` metrics that were found,\n- `unavailable` metrics that YouTube did not expose publicly,\n- `not_attempted` metrics that do not apply to that row,\n- `exact` values that appeared as full public integers,\n- `display_rounded` or `likely_rounded` values that appeared as rounded public\n  display counts.\n\nMissing counts stay missing. This lets you filter rows without guessing whether\na blank value means zero.\n\n## 🚦 Status values\n\nRows use explicit statuses so partial, unavailable, or failed inputs are still\nauditable. Only `ok` rows enter the default dataset and incur a result charge.\nAll other rows enter the **Unbilled results** dataset. Both datasets use the\nsame row fields. Each attempted input has one row across these two datasets.\n\n| Status                       | Meaning                                                                                             |\n| ---------------------------- | --------------------------------------------------------------------------------------------------- |\n| `ok`                         | The public YouTube post resolved and at least one useful public metric or metadata field was found. |\n| `resolved_no_public_metrics` | The input resolved, but public metric fields were not exposed for that item.                        |\n| `invalid_input`              | The input was not a valid YouTube URL, video ID, channel ID, or `@handle`.                          |\n| `unsupported_url`            | The URL is a YouTube surface this Actor does not support.                                           |\n| `blocked_or_challenged`      | YouTube returned a challenge, unavailable page, or blocked response.                                |\n| `failed`                     | The input could not be resolved after retry.                                                        |\n\n## 🧾 Output summary\n\nThe `OUTPUT` record contains a compact run summary with input counts, discovered\nURL counts, status counts, metric coverage counts, skipped-input counts, and\npost-type counts. `datasetRows` counts paid metric rows. `unbilledRows` counts\nrows in **Unbilled results**.\n\nUse it to audit a run quickly before downloading the full dataset.\n\n## ⚠️ Notes and limitations\n\n- Public pages can hide, round, delay, or omit metrics.\n- Comment bodies are not collected. The Actor only returns public comment\n  counts when available.\n- Search result scraping, playlist scraping, hashtag discovery, transcripts,\n  subtitles, and media downloads are not part of this Actor.\n- Dislikes are not public and are not returned.\n- Channel discovery is best-effort and depends on public channel pages.\n- Apify Proxy is enabled by default because direct cloud requests to YouTube are\n  commonly challenged.\n\n## 🔗 Related social media scrapers\n\nContinue the same workflow on this platform or compare public data across\nplatforms.\n\n### Continue on YouTube\n\n- [YouTube Channel Scraper](https://apify.com/chronometrica/youtube-channel-scraper)\n  — collect public channel details, links, and audience stats.\n- [YouTube Search Scraper](https://apify.com/chronometrica/youtube-search-scraper)\n  — find public videos, Shorts, channels, and metrics by keyword.\n- [YouTube Comments Scraper](https://apify.com/chronometrica/youtube-comments-scraper)\n  — collect public comments, replies, authors, likes, pins, and creator\n  hearts.\n- [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)\n  — extract public captions as text, timestamps, SRT, VTT, or JSON.\n\n### Compare metrics across platforms\n\n- [Facebook Metrics Scraper](https://apify.com/chronometrica/facebook-metrics-scraper)\n  — collect public post, Reel, video, photo, and profile metrics.\n- [Instagram Metrics Scraper](https://apify.com/chronometrica/instagram-metrics-scraper)\n  — collect public post, Reel, carousel, profile, and collaboration metrics.\n- [TikTok Metrics Scraper](https://apify.com/chronometrica/tiktok-metrics-scraper)\n  — collect public video, profile, engagement, hashtag, and music data.\n- [Snapchat Spotlight Metrics Scraper](https://apify.com/chronometrica/snapchat-metrics-scraper)\n  — collect public Spotlight post views, engagement, creator, and media data.\n- [X Post Metrics Scraper](https://apify.com/chronometrica/x-post-metrics)\n  — collect public post views, engagement, media, and author details.\n",
    "changelog": "# Changelog\n\n## October 2026\n\n- Fixed result billing so only successful metric rows incur a result charge.\n- Added Unbilled results for invalid, unsupported, unavailable, and failed inputs.\n\n## 1.0.1\n\n- Improved metric matching for direct YouTube video and Shorts URLs so public\n  counts are tied more reliably to the requested post.\n\n## 1.0.0 - Initial Public Release\n\n- Launched YouTube Metrics Scraper for public videos, Shorts, live posts, and\n  channel uploads.\n- Added mixed-input support for direct post URLs, video IDs, channel URLs,\n  channel IDs, and `@handles`.\n- Added channel discovery with recent, popular, and oldest ordering.\n- Added channel discovery filters for publish date, max age, and title text.\n- Added public metric rows for views, likes, comments, subscriber counts, and\n  Shorts remix counts when available.\n- Added public post and channel metric status fields so users can distinguish\n  exact, rounded, unavailable, and not-attempted metrics.\n- Added public owner and collaborator channel fields when YouTube identifies\n  them publicly.\n- Added a compact run summary in the actor output.\n",
    "actorDefinition": {
      "$schema": "https://apify.com/schemas/v1/actor.ide.json",
      "actorSpecification": 1,
      "name": "youtube-metrics-scraper",
      "title": "YouTube Metrics Scraper - Videos, Shorts & Channels",
      "description": "Collect public metrics for YouTube videos, Shorts, live posts, and channel uploads. Get views, likes, comments, remixes, channel IDs, handles, publish dates, subscriber counts, and status fields.",
      "seoTitle": "YouTube Metrics Scraper - Video & Shorts Stats",
      "seoDescription": "Scrape public YouTube metrics from videos, Shorts, live posts, channels, and @handles. Export views, likes, comments, IDs, dates, and channel stats.",
      "categories": [
        "SOCIAL_MEDIA",
        "VIDEOS"
      ],
      "version": "1.1",
      "buildTag": "release-candidate",
      "defaultRunOptions": {
        "build": "latest",
        "timeoutSecs": 3600,
        "memoryMbytes": 4096
      },
      "exampleRunInput": {
        "contentType": "application/json; charset=utf-8",
        "body": "{\n    \"startUrls\": [\n        \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"\n    ],\n    \"proxyConfiguration\": {\n        \"useApifyProxy\": true\n    }\n}"
      },
      "input": {
        "title": "YouTube Metrics Scraper input",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "startUrls": {
            "title": "YouTube post or channel URLs",
            "type": "array",
            "description": "Paste YouTube video URLs, Shorts URLs, video IDs, channel URLs, channel IDs, or @handles. Direct posts become metric rows. Channel inputs discover public posts first, then collect the same metrics.",
            "editor": "stringList",
            "sectionCaption": "Inputs",
            "sectionDescription": "Add direct YouTube posts, channel URLs, or @handles. The actor auto-detects each input and returns one metric row per resolved video or Short.",
            "minItems": 0,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^\\s*\\S[\\s\\S]*$"
            },
            "prefill": [
              "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
            ],
            "default": []
          },
          "maxItems": {
            "title": "Optional total row cap",
            "type": "integer",
            "description": "Optional maximum metric rows across direct posts and channel discovery. Leave blank to process every public item the Actor can find. Large values such as 999999 are accepted.",
            "editor": "number",
            "minimum": 1
          },
          "channelSort": {
            "title": "Channel post order",
            "type": "string",
            "description": "Choose the public channel discovery order.",
            "editor": "select",
            "enum": [
              "recent",
              "popular",
              "oldest"
            ],
            "enumTitles": [
              "Newest",
              "Most popular",
              "Oldest"
            ],
            "default": "recent"
          },
          "publishedAfter": {
            "title": "Published on or after",
            "type": "string",
            "description": "Only keep discovered channel posts published on or after this YYYY-MM-DD date.",
            "editor": "textfield",
            "pattern": "^$|^\\d{4}-\\d{2}-\\d{2}$",
            "default": ""
          },
          "publishedBefore": {
            "title": "Published on or before",
            "type": "string",
            "description": "Only keep discovered channel posts published on or before this YYYY-MM-DD date.",
            "editor": "textfield",
            "pattern": "^$|^\\d{4}-\\d{2}-\\d{2}$",
            "default": ""
          },
          "maxAgeDays": {
            "title": "Only last N days",
            "type": "integer",
            "description": "Only keep discovered channel posts from the last N days. This combines with Published on or after by using the newer lower-bound date.",
            "editor": "number",
            "minimum": 1
          },
          "titleIncludes": {
            "title": "Title contains",
            "type": "array",
            "description": "Only keep discovered channel posts whose public title contains at least one of these phrases.",
            "editor": "stringList",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "titleExcludes": {
            "title": "Title does not contain",
            "type": "array",
            "description": "Skip discovered channel posts whose public title contains any of these phrases.",
            "editor": "stringList",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Use Apify Proxy for public YouTube requests. The default is enabled because direct cloud requests are commonly challenged by YouTube.",
            "editor": "proxy",
            "sectionCaption": "Advanced run settings",
            "sectionDescription": "Tune public request behavior and failure semantics. Defaults are recommended for most users.",
            "default": {
              "useApifyProxy": true
            }
          },
          "requestTimeoutSecs": {
            "title": "Request timeout",
            "type": "integer",
            "description": "Maximum seconds to wait for each public YouTube request.",
            "editor": "number",
            "default": 20,
            "minimum": 5
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "type": "integer",
            "description": "Maximum number of YouTube requests to resolve at the same time.",
            "editor": "number",
            "default": 8,
            "minimum": 1
          },
          "failOnNoMetrics": {
            "title": "Fail when no metrics are exposed",
            "type": "boolean",
            "description": "Fail the run if none of the input URLs expose public metrics. Individual URLs without metrics still emit rows with structured statuses.",
            "editor": "checkbox",
            "default": false
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "YouTube Metrics Scraper output",
        "description": "Useful metric rows are stored in the default dataset. Other result rows are stored in the unbilled dataset. OUTPUT contains the run summary.",
        "properties": {
          "results": {
            "type": "string",
            "title": "Metric results",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          },
          "output": {
            "type": "string",
            "title": "Run summary",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/OUTPUT"
          },
          "unbilled": {
            "type": "string",
            "title": "Unbilled results",
            "description": "Invalid, unavailable, or failed inputs. These rows do not incur a result charge.",
            "template": "{{storages.datasets.unbilled.apiUrl}}/items"
          }
        }
      },
      "storages": {
        "datasets": {
          "default": {
            "actorSpecification": 1,
            "fields": {
              "$schema": "http://json-schema.org/draft-07/schema#",
              "type": "object",
              "properties": {
                "inputUrl": {
                  "type": "string",
                  "title": "Input URL"
                },
                "postUrl": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post URL"
                },
                "postId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post ID"
                },
                "postType": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post Type"
                },
                "isShort": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "title": "Is Short"
                },
                "title": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Title"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Description"
                },
                "publishedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Published At"
                },
                "channelId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel ID"
                },
                "channelHandle": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel Handle"
                },
                "channelUrl": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel URL"
                },
                "views": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Views"
                },
                "likes": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Likes"
                },
                "comments": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Comments"
                },
                "remixes": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Remixes",
                  "description": "Public Shorts remix count when available."
                },
                "postMetricStatus": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "metric": {
                        "type": "string",
                        "enum": [
                          "views",
                          "likes",
                          "comments",
                          "remixes"
                        ]
                      },
                      "value": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "present",
                          "unavailable",
                          "not_attempted"
                        ]
                      },
                      "precision": {
                        "type": "string",
                        "enum": [
                          "exact",
                          "display_rounded",
                          "likely_rounded",
                          "unavailable",
                          "unknown"
                        ]
                      }
                    },
                    "required": [
                      "metric",
                      "value",
                      "status",
                      "precision"
                    ]
                  },
                  "title": "Post Metric Status",
                  "description": "Public status and precision metadata for post-level metrics."
                },
                "collaborationCount": {
                  "type": "integer",
                  "title": "Collaboration Count"
                },
                "collaborationChannels": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "handle": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "url": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "role": {
                        "type": "string",
                        "enum": [
                          "owner",
                          "collaborator"
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "handle",
                      "url",
                      "role"
                    ]
                  },
                  "title": "Collaboration Channels",
                  "description": "Confirmed public owner and collaborator channels for the post."
                },
                "channelSubscribersCount": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Subscribers"
                },
                "channelMetricStatus": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "metric": {
                        "type": "string",
                        "enum": [
                          "channelSubscribersCount"
                        ]
                      },
                      "value": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "present",
                          "unavailable",
                          "not_attempted"
                        ]
                      },
                      "precision": {
                        "type": "string",
                        "enum": [
                          "exact",
                          "display_rounded",
                          "likely_rounded",
                          "unavailable",
                          "unknown"
                        ]
                      }
                    },
                    "required": [
                      "metric",
                      "value",
                      "status",
                      "precision"
                    ]
                  },
                  "title": "Channel Metric Status",
                  "description": "Public status and precision metadata for channel-level metrics."
                },
                "status": {
                  "type": "string",
                  "title": "Status"
                },
                "scrapedAt": {
                  "type": "string",
                  "format": "date-time",
                  "title": "Scraped At"
                },
                "isLive": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "title": "Is Live",
                  "description": "Whether the post is marked as live content."
                }
              },
              "required": [
                "inputUrl",
                "status",
                "scrapedAt"
              ]
            },
            "views": {
              "overview": {
                "title": "YouTube metrics",
                "description": "One row per YouTube video, Short, live post, or discovered channel post.",
                "transformation": {
                  "fields": [
                    "inputUrl",
                    "postUrl",
                    "postId",
                    "postType",
                    "isShort",
                    "title",
                    "description",
                    "publishedAt",
                    "channelId",
                    "channelHandle",
                    "channelUrl",
                    "views",
                    "likes",
                    "comments",
                    "remixes",
                    "postMetricStatus",
                    "collaborationCount",
                    "collaborationChannels",
                    "channelSubscribersCount",
                    "channelMetricStatus",
                    "status",
                    "scrapedAt",
                    "isLive"
                  ]
                },
                "display": {
                  "component": "table",
                  "properties": {
                    "inputUrl": {
                      "label": "Input URL",
                      "format": "link"
                    },
                    "postUrl": {
                      "label": "Post URL",
                      "format": "link"
                    },
                    "postId": {
                      "label": "Post ID",
                      "format": "text"
                    },
                    "postType": {
                      "label": "Post Type",
                      "format": "text"
                    },
                    "isShort": {
                      "label": "Is Short",
                      "format": "boolean"
                    },
                    "title": {
                      "label": "Title",
                      "format": "text"
                    },
                    "description": {
                      "label": "Description",
                      "format": "text"
                    },
                    "publishedAt": {
                      "label": "Published At",
                      "format": "date"
                    },
                    "channelId": {
                      "label": "Channel ID",
                      "format": "text"
                    },
                    "channelHandle": {
                      "label": "Channel Handle",
                      "format": "text"
                    },
                    "channelUrl": {
                      "label": "Channel URL",
                      "format": "link"
                    },
                    "views": {
                      "label": "Views",
                      "format": "number"
                    },
                    "likes": {
                      "label": "Likes",
                      "format": "number"
                    },
                    "comments": {
                      "label": "Comments",
                      "format": "number"
                    },
                    "remixes": {
                      "label": "Remixes",
                      "format": "number"
                    },
                    "postMetricStatus": {
                      "label": "Post Metric Status",
                      "format": "object",
                      "title": "Post Metric Status",
                      "description": "Public status and precision metadata for post-level metrics."
                    },
                    "collaborationCount": {
                      "label": "Collaboration Count",
                      "format": "number"
                    },
                    "collaborationChannels": {
                      "label": "Collaboration Channels",
                      "format": "object",
                      "title": "Collaboration Channels",
                      "description": "Confirmed public owner and collaborator channels for the post."
                    },
                    "channelSubscribersCount": {
                      "label": "Subscribers",
                      "format": "number"
                    },
                    "channelMetricStatus": {
                      "label": "Channel Metric Status",
                      "format": "object",
                      "title": "Channel Metric Status",
                      "description": "Public status and precision metadata for channel-level metrics."
                    },
                    "status": {
                      "label": "Status",
                      "format": "text"
                    },
                    "scrapedAt": {
                      "label": "Scraped At",
                      "format": "date"
                    },
                    "isLive": {
                      "label": "Is Live",
                      "format": "boolean"
                    }
                  }
                }
              }
            }
          },
          "unbilled": {
            "actorSpecification": 1,
            "fields": {
              "$schema": "http://json-schema.org/draft-07/schema#",
              "type": "object",
              "properties": {
                "inputUrl": {
                  "type": "string",
                  "title": "Input URL"
                },
                "postUrl": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post URL"
                },
                "postId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post ID"
                },
                "postType": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Post Type"
                },
                "isShort": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "title": "Is Short"
                },
                "title": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Title"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Description"
                },
                "publishedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Published At"
                },
                "channelId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel ID"
                },
                "channelHandle": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel Handle"
                },
                "channelUrl": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "title": "Channel URL"
                },
                "views": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Views"
                },
                "likes": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Likes"
                },
                "comments": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Comments"
                },
                "remixes": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Remixes",
                  "description": "Public Shorts remix count when available."
                },
                "postMetricStatus": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "metric": {
                        "type": "string",
                        "enum": [
                          "views",
                          "likes",
                          "comments",
                          "remixes"
                        ]
                      },
                      "value": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "present",
                          "unavailable",
                          "not_attempted"
                        ]
                      },
                      "precision": {
                        "type": "string",
                        "enum": [
                          "exact",
                          "display_rounded",
                          "likely_rounded",
                          "unavailable",
                          "unknown"
                        ]
                      }
                    },
                    "required": [
                      "metric",
                      "value",
                      "status",
                      "precision"
                    ]
                  },
                  "title": "Post Metric Status",
                  "description": "Public status and precision metadata for post-level metrics."
                },
                "collaborationCount": {
                  "type": "integer",
                  "title": "Collaboration Count"
                },
                "collaborationChannels": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "handle": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "url": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "role": {
                        "type": "string",
                        "enum": [
                          "owner",
                          "collaborator"
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "handle",
                      "url",
                      "role"
                    ]
                  },
                  "title": "Collaboration Channels",
                  "description": "Confirmed public owner and collaborator channels for the post."
                },
                "channelSubscribersCount": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "title": "Subscribers"
                },
                "channelMetricStatus": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "properties": {
                      "metric": {
                        "type": "string",
                        "enum": [
                          "channelSubscribersCount"
                        ]
                      },
                      "value": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "present",
                          "unavailable",
                          "not_attempted"
                        ]
                      },
                      "precision": {
                        "type": "string",
                        "enum": [
                          "exact",
                          "display_rounded",
                          "likely_rounded",
                          "unavailable",
                          "unknown"
                        ]
                      }
                    },
                    "required": [
                      "metric",
                      "value",
                      "status",
                      "precision"
                    ]
                  },
                  "title": "Channel Metric Status",
                  "description": "Public status and precision metadata for channel-level metrics."
                },
                "status": {
                  "type": "string",
                  "title": "Status"
                },
                "scrapedAt": {
                  "type": "string",
                  "format": "date-time",
                  "title": "Scraped At"
                },
                "isLive": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "title": "Is Live",
                  "description": "Whether the post is marked as live content."
                }
              },
              "required": [
                "inputUrl",
                "status",
                "scrapedAt"
              ]
            },
            "views": {
              "overview": {
                "title": "YouTube metrics",
                "description": "One row per YouTube video, Short, live post, or discovered channel post.",
                "transformation": {
                  "fields": [
                    "inputUrl",
                    "postUrl",
                    "postId",
                    "postType",
                    "isShort",
                    "title",
                    "description",
                    "publishedAt",
                    "channelId",
                    "channelHandle",
                    "channelUrl",
                    "views",
                    "likes",
                    "comments",
                    "remixes",
                    "postMetricStatus",
                    "collaborationCount",
                    "collaborationChannels",
                    "channelSubscribersCount",
                    "channelMetricStatus",
                    "status",
                    "scrapedAt",
                    "isLive"
                  ]
                },
                "display": {
                  "component": "table",
                  "properties": {
                    "inputUrl": {
                      "label": "Input URL",
                      "format": "link"
                    },
                    "postUrl": {
                      "label": "Post URL",
                      "format": "link"
                    },
                    "postId": {
                      "label": "Post ID",
                      "format": "text"
                    },
                    "postType": {
                      "label": "Post Type",
                      "format": "text"
                    },
                    "isShort": {
                      "label": "Is Short",
                      "format": "boolean"
                    },
                    "title": {
                      "label": "Title",
                      "format": "text"
                    },
                    "description": {
                      "label": "Description",
                      "format": "text"
                    },
                    "publishedAt": {
                      "label": "Published At",
                      "format": "date"
                    },
                    "channelId": {
                      "label": "Channel ID",
                      "format": "text"
                    },
                    "channelHandle": {
                      "label": "Channel Handle",
                      "format": "text"
                    },
                    "channelUrl": {
                      "label": "Channel URL",
                      "format": "link"
                    },
                    "views": {
                      "label": "Views",
                      "format": "number"
                    },
                    "likes": {
                      "label": "Likes",
                      "format": "number"
                    },
                    "comments": {
                      "label": "Comments",
                      "format": "number"
                    },
                    "remixes": {
                      "label": "Remixes",
                      "format": "number"
                    },
                    "postMetricStatus": {
                      "label": "Post Metric Status",
                      "format": "object",
                      "title": "Post Metric Status",
                      "description": "Public status and precision metadata for post-level metrics."
                    },
                    "collaborationCount": {
                      "label": "Collaboration Count",
                      "format": "number"
                    },
                    "collaborationChannels": {
                      "label": "Collaboration Channels",
                      "format": "object",
                      "title": "Collaboration Channels",
                      "description": "Confirmed public owner and collaborator channels for the post."
                    },
                    "channelSubscribersCount": {
                      "label": "Subscribers",
                      "format": "number"
                    },
                    "channelMetricStatus": {
                      "label": "Channel Metric Status",
                      "format": "object",
                      "title": "Channel Metric Status",
                      "description": "Public status and precision metadata for channel-level metrics."
                    },
                    "status": {
                      "label": "Status",
                      "format": "text"
                    },
                    "scrapedAt": {
                      "label": "Scraped At",
                      "format": "date"
                    },
                    "isLive": {
                      "label": "Is Live",
                      "format": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "changelog": "# Changelog\n\n## October 2026\n\n- Fixed result billing so only successful metric rows incur a result charge.\n- Added Unbilled results for invalid, unsupported, unavailable, and failed inputs.\n\n## 1.0.1\n\n- Improved metric matching for direct YouTube video and Shorts URLs so public\n  counts are tied more reliably to the requested post.\n\n## 1.0.0 - Initial Public Release\n\n- Launched YouTube Metrics Scraper for public videos, Shorts, live posts, and\n  channel uploads.\n- Added mixed-input support for direct post URLs, video IDs, channel URLs,\n  channel IDs, and `@handles`.\n- Added channel discovery with recent, popular, and oldest ordering.\n- Added channel discovery filters for publish date, max age, and title text.\n- Added public metric rows for views, likes, comments, subscriber counts, and\n  Shorts remix counts when available.\n- Added public post and channel metric status fields so users can distinguish\n  exact, rounded, unavailable, and not-attempted metrics.\n- Added public owner and collaborator channel fields when YouTube identifies\n  them publicly.\n- Added a compact run summary in the actor output.\n",
      "readme": "# YouTube Metrics Scraper\n\n## 📊 What does YouTube Metrics Scraper do?\n\nYouTube Metrics Scraper collects public metrics for YouTube videos, Shorts, live\nposts, and channel uploads. Paste known post URLs to measure them directly, or\npaste channel URLs, channel IDs, and `@handles` to discover public uploads\nfirst.\n\nUse it when you need clean YouTube data for creator research, influencer\nreporting, campaign tracking, competitor monitoring, social analytics,\ndashboards, warehouse loads, and scheduled metric snapshots.\n\nThe Actor returns flat CSV/API-friendly rows with views, likes, comments, Shorts\nremixes, subscriber counts, IDs, titles, descriptions, publish dates,\ncollaboration channels, row statuses, and per-metric quality labels.\n\nThis Actor does not log in, use cookies, scrape private YouTube content, collect\ncomment text, download videos, return dislikes, or access YouTube Studio\nanalytics. It only returns data that is publicly available at run time.\n\nWith YouTube Metrics Scraper, you can:\n\n- 📈 Track public performance for known YouTube videos, Shorts, and live posts.\n- 🎬 Measure videos and Shorts side by side in one normalized dataset.\n- 👤 Discover public uploads from channel URLs, channel IDs, and `@handles`.\n- 🔥 Sort discovered channel posts by newest, most popular, or oldest.\n- 💬 Collect public views, likes, comments, and Shorts remix counts when\n  available.\n- 👥 Add public channel subscriber counts and channel identity fields.\n- 🤝 Capture owner and collaborator channels when YouTube identifies them\n  publicly.\n- 🧭 Keep unavailable metrics as unavailable instead of turning them into fake\n  zeroes.\n- 📦 Export results as JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n\n## ✨ What You Get\n\nEach dataset row represents one YouTube video, Short, live post, or discovered\nchannel post.\n\n| Data group         | Example fields                                                              |\n| ------------------ | --------------------------------------------------------------------------- |\n| 🔗 URL identity    | `inputUrl`, `postUrl`                                                       |\n| 🆔 YouTube IDs     | `postId`, `postType`, `isShort`, `channelId`, `channelHandle`, `channelUrl` |\n| 🧾 Post details    | `title`, `description`, `publishedAt`, `isLive`                             |\n| 📊 Post metrics    | `views`, `likes`, `comments`, `remixes`                                     |\n| 👥 Channel metrics | `channelSubscribersCount`                                                   |\n| 🎯 Metric quality  | `postMetricStatus`, `channelMetricStatus`                                   |\n| 🤝 Collaborations  | `collaborationCount`, `collaborationChannels`                               |\n| 🚦 Row status      | `status`, `scrapedAt`                                                       |\n\nMetric availability depends on what YouTube exposes publicly for each post or\nchannel. Some public counters are exact, some are rounded, and some are hidden\nor delayed. Missing counts stay missing; they are not guessed and they are not\nreplaced with `0`.\n\n## ⚙️ Can I use this Actor through an API?\n\nYes. You can run YouTube Metrics Scraper manually in Apify Console or use it\nthrough:\n\n- Apify API\n- Python SDK\n- Node.js SDK\n- Webhooks\n- Scheduled runs\n- Apify integrations\n\nThis makes it useful for social media dashboards, influencer lists, competitive\nintelligence, creator databases, campaign reporting, content audits, data\nwarehouses, and automated market research workflows.\n\n## 🎯 Why scrape YouTube video, Shorts, and channel metrics?\n\nYouTube public metrics help you understand which creators, channels, videos,\nShorts, campaigns, and competitors are gaining traction.\n\n| Use case                     | How YouTube metric data helps                                                        |\n| ---------------------------- | ------------------------------------------------------------------------------------ |\n| 📈 Track creator performance | Monitor public views, likes, comments, and subscriber context over time.             |\n| 🎬 Compare content formats   | Compare videos, Shorts, and live posts in one flat export.                           |\n| 📣 Measure campaigns         | Collect repeatable snapshots for sponsored videos, creator deliverables, and drops.  |\n| 🕵️ Monitor competitors       | Track known competitor videos or discover channel uploads before collecting metrics. |\n| 🔥 Research top content      | Pull popular channel posts and compare the strongest public performers.              |\n| 🧱 Build reporting workflows | Feed normalized YouTube rows into dashboards, spreadsheets, and BI tools.            |\n| 🔎 Audit metric availability | Separate available, rounded, unavailable, and failed rows cleanly.                   |\n\n## 💵 Pricing Event\n\nYouTube Metrics Scraper uses pay-per-result pricing. One result means one\nYouTube video, Short, live post, or discovered channel post metric row written\nto the default dataset.\n\nEvery direct post input is processed by default. Use the optional `maxItems`\nsetting only when you want a total row cap. Use `maxItemsPerChannel` to control\nchannel discovery. Start with a small batch of 3 to 10 URLs when testing. The\nrun summary and row statuses show which URLs resolved, which returned public\nmetrics, and whether any inputs failed or were unsupported.\n\n## 🚀 How do I use YouTube Metrics Scraper?\n\n1. Create or log in to your Apify account.\n2. Open **YouTube Metrics Scraper**.\n3. Paste YouTube video URLs, Shorts URLs, channel URLs, channel IDs, `@handles`,\n   or a mix of them.\n4. Set an optional total row cap, or leave it blank to process every direct input.\n5. Choose the channel post order if you are using channel discovery.\n6. Leave the default settings for your first run.\n7. Click **Start**.\n8. Open the **Output** tab to inspect the dataset and run summary.\n9. Download your data in JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n\n## ⬇️ Input\n\nThe main input is `startUrls`. Paste at least one YouTube post URL, channel URL,\nchannel ID, raw video ID, or `@handle`. Direct posts and channel inputs can be\nmixed in the same run.\n\n```json\n{\n    \"startUrls\": [\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"],\n    \"proxyConfiguration\": {\n        \"useApifyProxy\": true\n    }\n}\n```\n\n### 🔗 YouTube URLs and handles\n\nSupported input shapes include:\n\n```text\nhttps://www.youtube.com/watch?v=VIDEO_ID\nhttps://youtu.be/VIDEO_ID\nhttps://www.youtube.com/shorts/VIDEO_ID\nhttps://www.youtube.com/embed/VIDEO_ID\nVIDEO_ID\nhttps://www.youtube.com/@handle\nhttps://www.youtube.com/@handle/videos\nhttps://www.youtube.com/@handle/shorts\n@handle\nhttps://www.youtube.com/channel/UC...\nUC...\n```\n\nBest results usually come from public post URLs and public channel pages that\nopen in a logged-out browser.\n\n### 📺 Channel discovery\n\nUse channel discovery when you want the Actor to find public posts from a\nYouTube channel before collecting metrics.\n\n```json\n{\n    \"startUrls\": [\"@MrBeast\"],\n    \"channelSort\": \"popular\",\n    \"maxItemsPerChannel\": 25\n}\n```\n\nChannel inputs discover public videos, Shorts, and live replays, then return the\nsame row shape as direct post URLs.\n\n### 🎛️ Settings\n\n| Option               | What it does                                                                              |\n| -------------------- | ----------------------------------------------------------------------------------------- |\n| `startUrls`          | YouTube post URLs, raw video IDs, channel URLs, channel IDs, `@handles`, or mixed inputs. |\n| `maxItems`           | Optional total row cap. Leave blank to process every direct post input.                   |\n| `maxItemsPerChannel` | Maximum public posts to discover from each channel input.                                 |\n| `channelSort`        | `recent`, `popular`, or `oldest` channel discovery order.                                 |\n| `publishedAfter`     | Only keep discovered channel posts published on or after a `YYYY-MM-DD` date.             |\n| `publishedBefore`    | Only keep discovered channel posts published on or before a `YYYY-MM-DD` date.            |\n| `maxAgeDays`         | Only keep discovered channel posts from the last N days.                                  |\n| `titleIncludes`      | Only keep discovered channel posts whose public title contains one of these phrases.      |\n| `titleExcludes`      | Skip discovered channel posts whose public title contains any of these phrases.           |\n| `maxConcurrency`     | Controls how many YouTube posts are resolved at the same time.                            |\n| `requestTimeoutSecs` | Maximum wait time for each public YouTube request.                                        |\n| `failOnNoMetrics`    | Fails the run if none of the input URLs expose public metrics.                            |\n\n## ⬆️ Output sample\n\nUseful metric results are stored in the default dataset. Each result is one YouTube metric\nrow.\n\n```json\n{\n    \"inputUrl\": \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\n    \"postUrl\": \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\n    \"postId\": \"dQw4w9WgXcQ\",\n    \"postType\": \"video\",\n    \"isShort\": false,\n    \"title\": \"Example YouTube video title\",\n    \"description\": \"Example public description\",\n    \"publishedAt\": \"2009-10-25\",\n    \"channelId\": \"UCuAXFkgsw1L7xaCfnd5JJOw\",\n    \"channelHandle\": \"@Example\",\n    \"channelUrl\": \"https://www.youtube.com/@Example\",\n    \"views\": 123456789,\n    \"likes\": 1234567,\n    \"comments\": 12345,\n    \"remixes\": null,\n    \"postMetricStatus\": [\n        {\n            \"metric\": \"views\",\n            \"value\": 123456789,\n            \"status\": \"present\",\n            \"precision\": \"exact\"\n        },\n        {\n            \"metric\": \"likes\",\n            \"value\": 1234567,\n            \"status\": \"present\",\n            \"precision\": \"exact\"\n        },\n        {\n            \"metric\": \"comments\",\n            \"value\": 12345,\n            \"status\": \"present\",\n            \"precision\": \"display_rounded\"\n        }\n    ],\n    \"collaborationCount\": 1,\n    \"collaborationChannels\": [\n        {\n            \"id\": \"UCuAXFkgsw1L7xaCfnd5JJOw\",\n            \"handle\": \"@Example\",\n            \"url\": \"https://www.youtube.com/@Example\",\n            \"role\": \"owner\"\n        }\n    ],\n    \"channelSubscribersCount\": 4510000,\n    \"channelMetricStatus\": [\n        {\n            \"metric\": \"channelSubscribersCount\",\n            \"value\": 4510000,\n            \"status\": \"present\",\n            \"precision\": \"display_rounded\"\n        }\n    ],\n    \"status\": \"ok\",\n    \"scrapedAt\": \"2026-06-24T00:00:00.000Z\",\n    \"isLive\": false\n}\n```\n\n`inputUrl` preserves the input that produced the row. `postUrl` is the resolved\npublic YouTube post URL. For Shorts, `postUrl` uses the public Shorts URL shape.\n\n## 🎯 Metric status\n\nYouTube can expose exact, rounded, delayed, or unavailable counters depending on\nthe post type, channel settings, geography, and current public page state.\n\nThe status fields help you separate:\n\n- `present` metrics that were found,\n- `unavailable` metrics that YouTube did not expose publicly,\n- `not_attempted` metrics that do not apply to that row,\n- `exact` values that appeared as full public integers,\n- `display_rounded` or `likely_rounded` values that appeared as rounded public\n  display counts.\n\nMissing counts stay missing. This lets you filter rows without guessing whether\na blank value means zero.\n\n## 🚦 Status values\n\nRows use explicit statuses so partial, unavailable, or failed inputs are still\nauditable. Only `ok` rows enter the default dataset and incur a result charge.\nAll other rows enter the **Unbilled results** dataset. Both datasets use the\nsame row fields. Each attempted input has one row across these two datasets.\n\n| Status                       | Meaning                                                                                             |\n| ---------------------------- | --------------------------------------------------------------------------------------------------- |\n| `ok`                         | The public YouTube post resolved and at least one useful public metric or metadata field was found. |\n| `resolved_no_public_metrics` | The input resolved, but public metric fields were not exposed for that item.                        |\n| `invalid_input`              | The input was not a valid YouTube URL, video ID, channel ID, or `@handle`.                          |\n| `unsupported_url`            | The URL is a YouTube surface this Actor does not support.                                           |\n| `blocked_or_challenged`      | YouTube returned a challenge, unavailable page, or blocked response.                                |\n| `failed`                     | The input could not be resolved after retry.                                                        |\n\n## 🧾 Output summary\n\nThe `OUTPUT` record contains a compact run summary with input counts, discovered\nURL counts, status counts, metric coverage counts, skipped-input counts, and\npost-type counts. `datasetRows` counts paid metric rows. `unbilledRows` counts\nrows in **Unbilled results**.\n\nUse it to audit a run quickly before downloading the full dataset.\n\n## ⚠️ Notes and limitations\n\n- Public pages can hide, round, delay, or omit metrics.\n- Comment bodies are not collected. The Actor only returns public comment\n  counts when available.\n- Search result scraping, playlist scraping, hashtag discovery, transcripts,\n  subtitles, and media downloads are not part of this Actor.\n- Dislikes are not public and are not returned.\n- Channel discovery is best-effort and depends on public channel pages.\n- Apify Proxy is enabled by default because direct cloud requests to YouTube are\n  commonly challenged.\n\n## 🔗 Related social media scrapers\n\nContinue the same workflow on this platform or compare public data across\nplatforms.\n\n### Continue on YouTube\n\n- [YouTube Channel Scraper](https://apify.com/chronometrica/youtube-channel-scraper)\n  — collect public channel details, links, and audience stats.\n- [YouTube Search Scraper](https://apify.com/chronometrica/youtube-search-scraper)\n  — find public videos, Shorts, channels, and metrics by keyword.\n- [YouTube Comments Scraper](https://apify.com/chronometrica/youtube-comments-scraper)\n  — collect public comments, replies, authors, likes, pins, and creator\n  hearts.\n- [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)\n  — extract public captions as text, timestamps, SRT, VTT, or JSON.\n\n### Compare metrics across platforms\n\n- [Facebook Metrics Scraper](https://apify.com/chronometrica/facebook-metrics-scraper)\n  — collect public post, Reel, video, photo, and profile metrics.\n- [Instagram Metrics Scraper](https://apify.com/chronometrica/instagram-metrics-scraper)\n  — collect public post, Reel, carousel, profile, and collaboration metrics.\n- [TikTok Metrics Scraper](https://apify.com/chronometrica/tiktok-metrics-scraper)\n  — collect public video, profile, engagement, hashtag, and music data.\n- [Snapchat Spotlight Metrics Scraper](https://apify.com/chronometrica/snapchat-metrics-scraper)\n  — collect public Spotlight post views, engagement, creator, and media data.\n- [X Post Metrics Scraper](https://apify.com/chronometrica/x-post-metrics)\n  — collect public post views, engagement, media, and author details.\n"
    },
    "buildNumber": "1.1.2",
    "imageDigest": "8bbead666e61b1284ccbb70ee00584eba37952f227979269ef29ac98906d99f9",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "release-candidate",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.025505555555555556
    }
  }
}