{
  "data": {
    "id": "RQ0JBxm63hdzUYFf3",
    "actId": "z0s6TC1YoFaRHOdjO",
    "userId": "zq8lKbpLzTjGDayPC",
    "startedAt": "2026-10-25T01:25:10.042Z",
    "finishedAt": "2026-10-25T01:25:15.698Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 5583,
      "runTimeSecs": 5.583,
      "computeUnits": 0.006203333333333333,
      "imageSizeBytes": 339204096
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "GK9YjZRyQZVzOdoH5",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Twitter (X) Broadcast Scraper\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"broadcastIds\": {\n      \"title\": \"Broadcast links, IDs or broadcast posts\",\n      \"type\": \"array\",\n      \"description\": \"Paste broadcast links such as https://x.com/i/broadcasts/1YGNrbPLejQGw, bare broadcast IDs, post links that announce a broadcast, or legacy Periscope links (/v/<id> or /<user>/<id>). Old pscp.tv/w share links cannot be resolved and return a status row.\",\n      \"editor\": \"stringList\",\n      \"minItems\": 1,\n      \"prefill\": [\n        \"https://x.com/i/broadcasts/1YGNrbPLejQGw\"\n      ],\n      \"example\": [\n        \"https://x.com/i/broadcasts/1YGNrbPLejQGw\",\n        \"1YGNrbPLejQGw\",\n        \"https://x.com/SpaceX/status/1649033533846097927\"\n      ]\n    },\n    \"includeViewerStats\": {\n      \"title\": \"Include viewer statistics\",\n      \"type\": \"boolean\",\n      \"description\": \"Include current/total viewers, the viewer-history graph when X exposes it, and derived peak/average viewers. Turn off for a lighter output.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeViewerTimeline\": {\n      \"title\": \"Emit viewer timeline points as rows\",\n      \"type\": \"boolean\",\n      \"description\": \"Push one \\\"viewer timeline point\\\" row per point of the broadcast's viewer-history graph. No rows are emitted when X provides no graph.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"maxViewerTimelinePoints\": {\n      \"title\": \"Max viewer timeline points per broadcast\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum timeline rows per broadcast. 0 means all points. When capped, points are evenly sampled across the full broadcast and each row keeps its original index.\",\n      \"default\": 0,\n      \"prefill\": 0,\n      \"minimum\": 0,\n      \"maximum\": 50000\n    },\n    \"includeReplayVideo\": {\n      \"title\": \"Include replay video link\",\n      \"type\": \"boolean\",\n      \"description\": \"Resolve the HLS playback URL and stream status. For a live broadcast the URL is the live stream; for an ended broadcast it is the replay.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"includeChatHistory\": {\n      \"title\": \"Include public chat replay\",\n      \"type\": \"boolean\",\n      \"description\": \"Collect text messages from the broadcast's public chat replay after it ends. Live chat and private chats are not collected. No text is emitted when the chat only contains join/heart events.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"maxChatMessages\": {\n      \"title\": \"Max chat messages per broadcast\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum public chat text messages per broadcast. Older events and join/heart events are not counted.\",\n      \"default\": 1000,\n      \"prefill\": 100,\n      \"minimum\": 1,\n      \"maximum\": 100000\n    },\n    \"includeThumbnail\": {\n      \"title\": \"Include thumbnail image\",\n      \"type\": \"boolean\",\n      \"description\": \"Store the broadcast cover image in the run's key-value store and return its stable URL plus the original X image URL.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeBroadcasterProfile\": {\n      \"title\": \"Include broadcaster profile\",\n      \"type\": \"boolean\",\n      \"description\": \"Add the broadcaster's public profile (followers, bio, location, account creation date, pinned posts). Falls back to the compact broadcaster record if the profile is unavailable.\",\n      \"default\": true,\n      \"prefill\": true\n    }\n  },\n  \"required\": [\n    \"broadcastIds\"\n  ]\n}",
    "readme": "# X Broadcast Viewer History & Replay Link Scraper\n\nCollect public X broadcasts from a broadcast link, a bare broadcast ID, an announcement post, or a legacy Periscope link. Get the title, state, timing, viewer counts and viewer-history graph, an HLS playback link, a stable cover image, the broadcaster's public profile, and — when the broadcast has ended and its chat is public — the chat replay text. No X account, cookies, or API key required.\n\n## What this actor does\n\n- **One target list, many link forms:** `x.com/i/broadcasts/...`, `twitter.com/i/broadcasts/...`, bare IDs, post links that announce a broadcast, and legacy Periscope `/v/<id>` or `/<user>/<id>` links.\n- **Metadata and timing:** title, state, creation/start/end times, duration, dimensions, media key, language, tags, and the announcement post.\n- **Viewer statistics:** current/total counters, the viewer-history graph **when X exposes it**, and derived peak/average viewers. The graph is sample counts, not a fabricated timeline.\n- **Replay and playback:** an HLS playback URL and stream status. Live broadcasts return the live HLS URL; ended broadcasts return the replay URL.\n- **Public chat replay:** optional text messages from an ended, public chat. Live and private chats are not collected; join/heart events are ignored.\n- **Broadcaster profile:** followers, bio, location, account creation date, pinned posts, and verification details, with a compact fallback.\n- **Stable cover image:** the expiring X thumbnail is stored in the run's key-value store; the original X URL is kept beside it.\n- **Honest status rows:** invalid links, old `pscp.tv/w` share links, Spaces, deleted broadcasts, and rate limits each get a clear message instead of a silent failure.\n- **Empty fields are omitted** — no `null` values or placeholder strings.\n\n## Output per record\n\nEach row has a `type`:\n\n| `type` | Meaning |\n|---|---|\n| `broadcast` | One broadcast's metadata, viewer statistics, playback, chat summary and broadcaster |\n| `viewer timeline point` | One sampled point of the viewer-history graph (only when timeline rows are enabled) |\n| `chat message` | One public chat text message (only when chat replay is enabled and available) |\n| `status` | A problem row with a `status` and a human-readable `message` |\n\n### Broadcast fields\n\n- **Identity:** `id`, `url`, `title`, `state`, `status` (X's machine state when it publishes one)\n- **Timing:** `createdAt`, `updatedAt`, `startedAt`, `endedAt`, `durationSeconds`\n- **Viewers:** `viewersNow`, `viewersTotal`, `viewCountGraph[]`, `viewerHistoryAvailable`, `viewerGraphPoints`, `peakViewers`, `averageViewers`, `viewerTimelineSampled`\n- **Media:** `thumbnailUrl` (stable), `thumbnailUrlOriginal`, `width`, `height`, `mediaKey`, `cameraRotation`, `isHighLatency`\n- **Replay:** `replayAvailable`, `playbackKind` (`live` / `replay` / `upcoming`), `streamStatus`, `replayVideoUrl`, `replayVideoFormat`\n- **Chat:** `chatHistoryStatus`, `chatMessageCount`, `chatEventCount`, `chatHistoryTruncated`\n- **Broadcaster:** `broadcaster` (public profile; compact fallback)\n- **Context:** `language`, `tags[]`, `announcementTweetId`, `announcementTweetUrl`, `sourceTweetId`, `sourceTweetUrl` (when the input was a post), `chatOption`, `privateChat`, `isLocked`, `noHearts`, `hasModeration`, `source`, `collectedAt`\n\n### Viewer timeline fields\n\n`broadcastId`, `broadcastUrl`, `title`, `pointIndex` (original graph position), `viewers`, `elapsedSeconds`, `timestamp`, `timeEstimated`, `collectedAt`.\n\n### Chat message fields\n\n`broadcastId`, `broadcastUrl`, `title`, `messageId`, `username`, `displayName`, `text`, `timestamp`, `elapsedSeconds`, `profileImageUrl`, `twitterId`, `verified`, `participantIndex`, `collectedAt`.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `broadcastIds` | array | – | Broadcast links, bare IDs, announcement posts, or legacy Periscope `/v/<id>` / `/<user>/<id>` links (required) |\n| `includeViewerStats` | boolean | `true` | Current/total viewers, viewer-history graph and derived peak/average |\n| `includeViewerTimeline` | boolean | `false` | Emit one row per viewer-history point |\n| `maxViewerTimelinePoints` | integer | `0` | Max timeline rows per broadcast; `0` = all; capped runs sample evenly |\n| `includeReplayVideo` | boolean | `false` | Resolve the HLS playback URL and stream status |\n| `includeChatHistory` | boolean | `false` | Collect public chat replay text after the broadcast ends |\n| `maxChatMessages` | integer | `1000` | Max public chat text messages per broadcast |\n| `includeThumbnail` | boolean | `true` | Store the cover image and return a stable URL plus the original |\n| `includeBroadcasterProfile` | boolean | `true` | Add the broadcaster's public profile; falls back to the compact record |\n\n### Example: broadcast metadata\n\n```json\n{\n  \"broadcastIds\": [\"https://x.com/i/broadcasts/1YGNrbPLejQGw\"]\n}\n```\n\n### Example: viewer history plus replay\n\n```json\n{\n  \"broadcastIds\": [\"1YGNrbPLejQGw\"],\n  \"includeViewerTimeline\": true,\n  \"includeReplayVideo\": true\n}\n```\n\n### Example: public chat replay\n\n```json\n{\n  \"broadcastIds\": [\"https://x.com/i/broadcasts/1BdGYEQPeDNGX\"],\n  \"includeChatHistory\": true,\n  \"maxChatMessages\": 200\n}\n```\n\n### Example: mixed links and a deleted broadcast\n\n```json\n{\n  \"broadcastIds\": [\n    \"https://x.com/i/broadcasts/1YGNrbPLejQGw\",\n    \"https://www.periscope.tv/v/1kvJpmapzboxE\",\n    \"https://x.com/i/broadcasts/1AAAAAAAAAAAA\"\n  ],\n  \"includeReplayVideo\": true\n}\n```\n\n## Use cases\n\n- **Live-event monitoring:** track audience size during and after a public broadcast.\n- **Newsroom verification:** confirm viewer counts, timing and the announcement post for a public statement.\n- **Archival:** preserve broadcast metadata, a stable cover image and a replay URL while they are still available.\n- **Creator comparison:** compare audience, duration and chat activity across broadcasters.\n- **Dashboard feeds:** load the viewer timeline or chat rows directly into a chart or spreadsheet.\n- **Chat research:** study public chat replay around an event without collecting private or live chat.\n\n## FAQ\n\n**Do I need an X account, cookies or a proxy?**\nNo. The actor reads publicly visible broadcast data and selects a working connection automatically. Just add one or more targets and run it.\n\n**What counts as an X broadcast?**\nX live video, the product that replaced Periscope. Its canonical link is `x.com/i/broadcasts/<id>`; `twitter.com` links redirect there. Legacy Periscope replay pages no longer exist, but their broadcast IDs can still resolve at x.com when the broadcast survives. If X returns an upcoming broadcast, the row reports the state X publishes and `playbackKind: \"upcoming\"`; X's guest payload does not expose reliable scheduled start times or pre-live slate URLs, so those fields are omitted rather than guessed.\n\n**Why is the viewer-history graph missing for some broadcasts?**\nX exposes `view_count_graph` for only a subset of broadcasts: 26 of 50 (52%) in our October 2026 sample, and rarely for older ones. The actor never invents points; when X has no graph it reports `viewerHistoryAvailable: false` and omits peak/average.\n\n**Are the viewer timeline timestamps exact?**\nX returns viewer counts only, without per-point times. Timestamps are derived evenly from the broadcast's real start/end (or the collection time for a live broadcast) and flagged `timeEstimated: true`. `averageViewers` is the mean of X's sampled points.\n\n**What do `viewersTotal` and `viewersNow` mean?**\nThey are X's own counters. `viewersTotal` is not a unique-viewer count, and on an ended broadcast `viewersNow` is the last concurrent count X reported, not a live figure.\n\n**Is the replay a downloadable video?**\nNo. `replayVideoUrl` is an HLS playback URL for a standard player or your own pipeline. For a live broadcast it is the live HLS URL (`playbackKind: \"live\"`); the replay appears after the broadcast ends. Some regional CDN edges return 403 unless the request carries `Referer: https://x.com/`; add that header if your player is refused.\n\n**Why is a replay or chat missing?**\nA deleted or non-public broadcast has no replay. A live broadcast has no replay yet. Chat replay is collected only after a broadcast ends, only for public chats, and only when X still serves the chat history; many chats contain only join/heart events, so `chatMessageCount` can be 0. History is read in pages of up to 1,000 events with a 50-page cap per broadcast; `maxChatMessages` caps text rows, and `chatHistoryTruncated` marks a capped result.\n\n**Do legacy Periscope links work?**\n`/v/<id>` and `/<user>/<id>` links resolve by their trailing broadcast ID. Old `pscp.tv/w/...` share links are not broadcast IDs and return a `legacyShareLinkUnsupported` status row.\n\n**Does this work on X Spaces?**\nNo. Spaces are audio rooms; they return a `spacesNotSupported` status row.\n\n**Is this affiliated with X?**\nNo. This is an independent, third-party actor that reads publicly visible broadcast data and is not operated by or affiliated with X Corp.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "x-broadcast-viewer-history-and-replay-link-scraper",
      "title": "X Broadcast Viewer History & Replay Link Scraper",
      "description": "Get a public X broadcast's metadata, viewer counts and history, HLS replay link, public chat replay, broadcaster profile and thumbnail from a link, ID or post — no login.",
      "seoTitle": "X Broadcast Viewer History, Replay & Chat Data",
      "seoDescription": "Collect public X broadcasts by link, ID or post: viewer history, HLS replay, public chat replay, broadcaster profile and a stable thumbnail. No login or proxy setup.",
      "version": "1.0",
      "buildTag": "latest",
      "dockerfile": "./Dockerfile",
      "readme": "# X Broadcast Viewer History & Replay Link Scraper\n\nCollect public X broadcasts from a broadcast link, a bare broadcast ID, an announcement post, or a legacy Periscope link. Get the title, state, timing, viewer counts and viewer-history graph, an HLS playback link, a stable cover image, the broadcaster's public profile, and — when the broadcast has ended and its chat is public — the chat replay text. No X account, cookies, or API key required.\n\n## What this actor does\n\n- **One target list, many link forms:** `x.com/i/broadcasts/...`, `twitter.com/i/broadcasts/...`, bare IDs, post links that announce a broadcast, and legacy Periscope `/v/<id>` or `/<user>/<id>` links.\n- **Metadata and timing:** title, state, creation/start/end times, duration, dimensions, media key, language, tags, and the announcement post.\n- **Viewer statistics:** current/total counters, the viewer-history graph **when X exposes it**, and derived peak/average viewers. The graph is sample counts, not a fabricated timeline.\n- **Replay and playback:** an HLS playback URL and stream status. Live broadcasts return the live HLS URL; ended broadcasts return the replay URL.\n- **Public chat replay:** optional text messages from an ended, public chat. Live and private chats are not collected; join/heart events are ignored.\n- **Broadcaster profile:** followers, bio, location, account creation date, pinned posts, and verification details, with a compact fallback.\n- **Stable cover image:** the expiring X thumbnail is stored in the run's key-value store; the original X URL is kept beside it.\n- **Honest status rows:** invalid links, old `pscp.tv/w` share links, Spaces, deleted broadcasts, and rate limits each get a clear message instead of a silent failure.\n- **Empty fields are omitted** — no `null` values or placeholder strings.\n\n## Output per record\n\nEach row has a `type`:\n\n| `type` | Meaning |\n|---|---|\n| `broadcast` | One broadcast's metadata, viewer statistics, playback, chat summary and broadcaster |\n| `viewer timeline point` | One sampled point of the viewer-history graph (only when timeline rows are enabled) |\n| `chat message` | One public chat text message (only when chat replay is enabled and available) |\n| `status` | A problem row with a `status` and a human-readable `message` |\n\n### Broadcast fields\n\n- **Identity:** `id`, `url`, `title`, `state`, `status` (X's machine state when it publishes one)\n- **Timing:** `createdAt`, `updatedAt`, `startedAt`, `endedAt`, `durationSeconds`\n- **Viewers:** `viewersNow`, `viewersTotal`, `viewCountGraph[]`, `viewerHistoryAvailable`, `viewerGraphPoints`, `peakViewers`, `averageViewers`, `viewerTimelineSampled`\n- **Media:** `thumbnailUrl` (stable), `thumbnailUrlOriginal`, `width`, `height`, `mediaKey`, `cameraRotation`, `isHighLatency`\n- **Replay:** `replayAvailable`, `playbackKind` (`live` / `replay` / `upcoming`), `streamStatus`, `replayVideoUrl`, `replayVideoFormat`\n- **Chat:** `chatHistoryStatus`, `chatMessageCount`, `chatEventCount`, `chatHistoryTruncated`\n- **Broadcaster:** `broadcaster` (public profile; compact fallback)\n- **Context:** `language`, `tags[]`, `announcementTweetId`, `announcementTweetUrl`, `sourceTweetId`, `sourceTweetUrl` (when the input was a post), `chatOption`, `privateChat`, `isLocked`, `noHearts`, `hasModeration`, `source`, `collectedAt`\n\n### Viewer timeline fields\n\n`broadcastId`, `broadcastUrl`, `title`, `pointIndex` (original graph position), `viewers`, `elapsedSeconds`, `timestamp`, `timeEstimated`, `collectedAt`.\n\n### Chat message fields\n\n`broadcastId`, `broadcastUrl`, `title`, `messageId`, `username`, `displayName`, `text`, `timestamp`, `elapsedSeconds`, `profileImageUrl`, `twitterId`, `verified`, `participantIndex`, `collectedAt`.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `broadcastIds` | array | – | Broadcast links, bare IDs, announcement posts, or legacy Periscope `/v/<id>` / `/<user>/<id>` links (required) |\n| `includeViewerStats` | boolean | `true` | Current/total viewers, viewer-history graph and derived peak/average |\n| `includeViewerTimeline` | boolean | `false` | Emit one row per viewer-history point |\n| `maxViewerTimelinePoints` | integer | `0` | Max timeline rows per broadcast; `0` = all; capped runs sample evenly |\n| `includeReplayVideo` | boolean | `false` | Resolve the HLS playback URL and stream status |\n| `includeChatHistory` | boolean | `false` | Collect public chat replay text after the broadcast ends |\n| `maxChatMessages` | integer | `1000` | Max public chat text messages per broadcast |\n| `includeThumbnail` | boolean | `true` | Store the cover image and return a stable URL plus the original |\n| `includeBroadcasterProfile` | boolean | `true` | Add the broadcaster's public profile; falls back to the compact record |\n\n### Example: broadcast metadata\n\n```json\n{\n  \"broadcastIds\": [\"https://x.com/i/broadcasts/1YGNrbPLejQGw\"]\n}\n```\n\n### Example: viewer history plus replay\n\n```json\n{\n  \"broadcastIds\": [\"1YGNrbPLejQGw\"],\n  \"includeViewerTimeline\": true,\n  \"includeReplayVideo\": true\n}\n```\n\n### Example: public chat replay\n\n```json\n{\n  \"broadcastIds\": [\"https://x.com/i/broadcasts/1BdGYEQPeDNGX\"],\n  \"includeChatHistory\": true,\n  \"maxChatMessages\": 200\n}\n```\n\n### Example: mixed links and a deleted broadcast\n\n```json\n{\n  \"broadcastIds\": [\n    \"https://x.com/i/broadcasts/1YGNrbPLejQGw\",\n    \"https://www.periscope.tv/v/1kvJpmapzboxE\",\n    \"https://x.com/i/broadcasts/1AAAAAAAAAAAA\"\n  ],\n  \"includeReplayVideo\": true\n}\n```\n\n## Use cases\n\n- **Live-event monitoring:** track audience size during and after a public broadcast.\n- **Newsroom verification:** confirm viewer counts, timing and the announcement post for a public statement.\n- **Archival:** preserve broadcast metadata, a stable cover image and a replay URL while they are still available.\n- **Creator comparison:** compare audience, duration and chat activity across broadcasters.\n- **Dashboard feeds:** load the viewer timeline or chat rows directly into a chart or spreadsheet.\n- **Chat research:** study public chat replay around an event without collecting private or live chat.\n\n## FAQ\n\n**Do I need an X account, cookies or a proxy?**\nNo. The actor reads publicly visible broadcast data and selects a working connection automatically. Just add one or more targets and run it.\n\n**What counts as an X broadcast?**\nX live video, the product that replaced Periscope. Its canonical link is `x.com/i/broadcasts/<id>`; `twitter.com` links redirect there. Legacy Periscope replay pages no longer exist, but their broadcast IDs can still resolve at x.com when the broadcast survives. If X returns an upcoming broadcast, the row reports the state X publishes and `playbackKind: \"upcoming\"`; X's guest payload does not expose reliable scheduled start times or pre-live slate URLs, so those fields are omitted rather than guessed.\n\n**Why is the viewer-history graph missing for some broadcasts?**\nX exposes `view_count_graph` for only a subset of broadcasts: 26 of 50 (52%) in our October 2026 sample, and rarely for older ones. The actor never invents points; when X has no graph it reports `viewerHistoryAvailable: false` and omits peak/average.\n\n**Are the viewer timeline timestamps exact?**\nX returns viewer counts only, without per-point times. Timestamps are derived evenly from the broadcast's real start/end (or the collection time for a live broadcast) and flagged `timeEstimated: true`. `averageViewers` is the mean of X's sampled points.\n\n**What do `viewersTotal` and `viewersNow` mean?**\nThey are X's own counters. `viewersTotal` is not a unique-viewer count, and on an ended broadcast `viewersNow` is the last concurrent count X reported, not a live figure.\n\n**Is the replay a downloadable video?**\nNo. `replayVideoUrl` is an HLS playback URL for a standard player or your own pipeline. For a live broadcast it is the live HLS URL (`playbackKind: \"live\"`); the replay appears after the broadcast ends. Some regional CDN edges return 403 unless the request carries `Referer: https://x.com/`; add that header if your player is refused.\n\n**Why is a replay or chat missing?**\nA deleted or non-public broadcast has no replay. A live broadcast has no replay yet. Chat replay is collected only after a broadcast ends, only for public chats, and only when X still serves the chat history; many chats contain only join/heart events, so `chatMessageCount` can be 0. History is read in pages of up to 1,000 events with a 50-page cap per broadcast; `maxChatMessages` caps text rows, and `chatHistoryTruncated` marks a capped result.\n\n**Do legacy Periscope links work?**\n`/v/<id>` and `/<user>/<id>` links resolve by their trailing broadcast ID. Old `pscp.tv/w/...` share links are not broadcast IDs and return a `legacyShareLinkUnsupported` status row.\n\n**Does this work on X Spaces?**\nNo. Spaces are audio rooms; they return a `spacesNotSupported` status row.\n\n**Is this affiliated with X?**\nNo. This is an independent, third-party actor that reads publicly visible broadcast data and is not operated by or affiliated with X Corp.\n",
      "input": {
        "title": "Twitter (X) Broadcast Scraper",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "broadcastIds": {
            "title": "Broadcast links, IDs or broadcast posts",
            "type": "array",
            "description": "Paste broadcast links such as https://x.com/i/broadcasts/1YGNrbPLejQGw, bare broadcast IDs, post links that announce a broadcast, or legacy Periscope links (/v/<id> or /<user>/<id>). Old pscp.tv/w share links cannot be resolved and return a status row.",
            "editor": "stringList",
            "minItems": 1,
            "prefill": [
              "https://x.com/i/broadcasts/1YGNrbPLejQGw"
            ],
            "example": [
              "https://x.com/i/broadcasts/1YGNrbPLejQGw",
              "1YGNrbPLejQGw",
              "https://x.com/SpaceX/status/1649033533846097927"
            ]
          },
          "includeViewerStats": {
            "title": "Include viewer statistics",
            "type": "boolean",
            "description": "Include current/total viewers, the viewer-history graph when X exposes it, and derived peak/average viewers. Turn off for a lighter output.",
            "default": true,
            "prefill": true
          },
          "includeViewerTimeline": {
            "title": "Emit viewer timeline points as rows",
            "type": "boolean",
            "description": "Push one \"viewer timeline point\" row per point of the broadcast's viewer-history graph. No rows are emitted when X provides no graph.",
            "default": false,
            "prefill": false
          },
          "maxViewerTimelinePoints": {
            "title": "Max viewer timeline points per broadcast",
            "type": "integer",
            "description": "Maximum timeline rows per broadcast. 0 means all points. When capped, points are evenly sampled across the full broadcast and each row keeps its original index.",
            "default": 0,
            "prefill": 0,
            "minimum": 0,
            "maximum": 50000
          },
          "includeReplayVideo": {
            "title": "Include replay video link",
            "type": "boolean",
            "description": "Resolve the HLS playback URL and stream status. For a live broadcast the URL is the live stream; for an ended broadcast it is the replay.",
            "default": false,
            "prefill": false
          },
          "includeChatHistory": {
            "title": "Include public chat replay",
            "type": "boolean",
            "description": "Collect text messages from the broadcast's public chat replay after it ends. Live chat and private chats are not collected. No text is emitted when the chat only contains join/heart events.",
            "default": false,
            "prefill": false
          },
          "maxChatMessages": {
            "title": "Max chat messages per broadcast",
            "type": "integer",
            "description": "Maximum public chat text messages per broadcast. Older events and join/heart events are not counted.",
            "default": 1000,
            "prefill": 100,
            "minimum": 1,
            "maximum": 100000
          },
          "includeThumbnail": {
            "title": "Include thumbnail image",
            "type": "boolean",
            "description": "Store the broadcast cover image in the run's key-value store and return its stable URL plus the original X image URL.",
            "default": true,
            "prefill": true
          },
          "includeBroadcasterProfile": {
            "title": "Include broadcaster profile",
            "type": "boolean",
            "description": "Add the broadcaster's public profile (followers, bio, location, account creation date, pinned posts). Falls back to the compact broadcaster record if the profile is unavailable.",
            "default": true,
            "prefill": true
          }
        },
        "required": [
          "broadcastIds"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "X Broadcast Viewer History & Replay Link Scraper Output",
        "description": "One row per X broadcast, viewer-timeline point, public chat message, or status row, with metadata, viewer statistics, HLS replay, broadcaster profile and chat counts.",
        "type": "object",
        "properties": {
          "broadcasts": {
            "type": "string",
            "title": "X broadcasts",
            "description": "Collected broadcast rows and status rows.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "categories": [
        "SOCIAL_MEDIA"
      ],
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Broadcasts",
              "transformation": {
                "fields": [
                  "type",
                  "title",
                  "state",
                  "broadcaster.username",
                  "viewersNow",
                  "viewersTotal",
                  "startedAt",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "environmentVariables": {},
      "defaultMemoryMbytes": 1024,
      "minMemoryMbytes": 1024,
      "maxMemoryMbytes": 2048
    },
    "buildNumber": "1.0.2",
    "imageDigest": "a9cfa8a71e936e75ef6d06d7fd099a28bb942f705a99e7474aa2f98b4d6c39c7",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.006203333333333333
    }
  }
}