Dataspryva

Use X Broadcast Viewer History & Replay Link Scraper with Python

Get a public X broadcast's title, state, start/end times, viewer counts over time, thumbnail, broadcaster profile, and an optional replay stream link, resolved from a broadcast link or ID.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "broadcastIds": [
    "https://x.com/i/broadcasts/1YGNrbPLejQGw"
  ],
  "includeBroadcasterProfile": true,
  "includeChatHistory": false,
  "includeReplayVideo": false,
  "includeThumbnail": true,
  "includeViewerStats": true,
  "includeViewerTimeline": false,
  "maxChatMessages": 100,
  "maxViewerTimelinePoints": 0
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
broadcastIdsarrayrequiredPaste 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.
includeViewerStatsbooleanoptionalInclude current/total viewers, the viewer-history graph when X exposes it, and derived peak/average viewers. Turn off for a lighter output.
includeViewerTimelinebooleanoptionalPush one "viewer timeline point" row per point of the broadcast's viewer-history graph. No rows are emitted when X provides no graph.
maxViewerTimelinePointsintegeroptionalMaximum 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.
includeReplayVideobooleanoptionalResolve 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.
includeChatHistorybooleanoptionalCollect 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.
maxChatMessagesintegeroptionalMaximum public chat text messages per broadcast. Older events and join/heart events are not counted.
includeThumbnailbooleanoptionalStore the broadcast cover image in the run's key-value store and return its stable URL plus the original X image URL.
includeBroadcasterProfilebooleanoptionalAdd 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.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/z0s6TC1YoFaRHOdjO/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

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.

Questions before you run

Which inputs are required?

The published required fields are broadcastIds

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build RQ0JBxm63hdzUYFf3 and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.