YouTube Live Stream & Replay Chat Extractor
Collect chat messages, Super Chats, Super Stickers, and membership events from an active YouTube livestream or an ended stream's saved chat replay, with author and timestamp detail.
Input schema
Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.
| Field | Type | Required | Description |
|---|---|---|---|
videoRefs | array | optional | YouTube watch, live, shorts or youtu.be links, 11-character video IDs, or a channel live link such as @handle/live. |
channelRefs | array | optional | Channel handles (@name), channel URLs or UC… channel IDs. The actor discovers current live streams and recent stream replays from each channel. |
mode | string | optional | Auto detects live versus replay. Active captures an ongoing live chat. Replay reads the saved chat of an ended stream. |
Show all input fields
| Field | Type | Required | Description |
|---|---|---|---|
videoRefs | array | optional | YouTube watch, live, shorts or youtu.be links, 11-character video IDs, or a channel live link such as @handle/live. |
channelRefs | array | optional | Channel handles (@name), channel URLs or UC… channel IDs. The actor discovers current live streams and recent stream replays from each channel. |
mode | string | optional | Auto detects live versus replay. Active captures an ongoing live chat. Replay reads the saved chat of an ended stream. |
channelDiscoveryMode | string | optional | Which streams to pick from each channel. Used with channel references. |
maxVideosPerChannel | integer | optional | Maximum streams to process from each channel. |
lookbackDays | integer | optional | How far back to include ended streams from a channel. Use 0 for no limit. |
includeUpcomingLives | boolean | optional | Emit an upcoming status row for scheduled channel streams instead of skipping them. |
maxMessagesPerVideo | integer | optional | Maximum unique chat events collected from each video. Use 0 to collect every available event. |
maxTotalItems | integer | optional | Whole-run cap across all videos and summary rows. Use 0 for no limit. |
maxTimePerVideoSecs | integer | optional | Safety limit for replay pagination on one video, in seconds. A run that reaches it reports partial_capture. |
includeNormalMessages | boolean | optional | Include standard text chat messages. |
includeSuperChats | boolean | optional | Include paid Super Chat messages and paid Super Stickers. |
includeMembershipEvents | boolean | optional | Include new and renewed channel membership events. |
includeGiftEvents | boolean | optional | Include gift membership purchases, gift membership redemptions and paid gift messages. |
includeSystemEvents | boolean | optional | Include engagement notices, slow-mode changes, restricted participation and other system rows. |
includePlaceholders | boolean | optional | Include raw placeholder rows that contain only an ID and timestamp. |
includeSummary | boolean | optional | Add one stream_summary row per video with event counts, per-currency totals, top supporters and completeness. |
startOffsetSecs | integer | optional | Replay only. Skip events before this video offset. Use 0 to start at the beginning. |
endOffsetSecs | integer | optional | Replay only. Stop after this video offset. Use 0 to read to the end. |
liveCollectSecs | integer | optional | How long to keep polling an active chat before stopping. Live captures are always partial. |
pollIntervalMs | integer | optional | Minimum delay between live chat polls. YouTube's own timeout is honoured when it is longer. |
language | string | optional | Interface language used when requesting YouTube pages and chat. |
regionCode | string | optional | Region used for YouTube page and chat requests. |
includeMetadata | boolean | optional | Repeat video and stream metadata on each chat row. |
Download the published input schema
View complete JSON
{
"description": "Read public live chat from videos, live streams or channels. No cookies, login or proxy setup required.",
"properties": {
"channelDiscoveryMode": {
"default": "current_live_then_replays",
"description": "Which streams to pick from each channel. Used with channel references.",
"editor": "select",
"enum": [
"current_live",
"current_live_then_replays",
"latest_replays"
],
"enumTitles": [
"Current live only",
"Current live, then recent replays",
"Recent stream replays only"
],
"prefill": "current_live",
"title": "Channel discovery",
"type": "string"
},
"channelRefs": {
"description": "Channel handles (@name), channel URLs or UC… channel IDs. The actor discovers current live streams and recent stream replays from each channel.",
"editor": "stringList",
"items": {
"type": "string"
},
"title": "Channels",
"type": "array"
},
"endOffsetSecs": {
"default": 0,
"description": "Replay only. Stop after this video offset. Use 0 to read to the end.",
"maximum": 604800,
"minimum": 0,
"prefill": 0,
"title": "End offset (seconds)",
"type": "integer"
},
"includeGiftEvents": {
"default": true,
"description": "Include gift membership purchases, gift membership redemptions and paid gift messages.",
"prefill": true,
"title": "Include gifts",
"type": "boolean"
},
"includeMembershipEvents": {
"default": true,
"description": "Include new and renewed channel membership events.",
"prefill": true,
"title": "Include memberships",
"type": "boolean"
},
"includeMetadata": {
"default": true,
"description": "Repeat video and stream metadata on each chat row.",
"prefill": true,
"title": "Include stream metadata",
"type": "boolean"
},
"includeNormalMessages": {
"default": true,
"description": "Include standard text chat messages.",
"prefill": true,
"title": "Include normal messages",
"type": "boolean"
},
"includePlaceholders": {
"default": false,
"description": "Include raw placeholder rows that contain only an ID and timestamp.",
"prefill": false,
"title": "Include placeholders",
"type": "boolean"
},
"includeSummary": {
"default": false,
"description": "Add one stream_summary row per video with event counts, per-currency totals, top supporters and completeness.",
"prefill": false,
"title": "Include stream summary",
"type": "boolean"
},
"includeSuperChats": {
"default": true,
"description": "Include paid Super Chat messages and paid Super Stickers.",
"prefill": true,
"title": "Include Super Chats and Stickers",
"type": "boolean"
},
"includeSystemEvents": {
"default": true,
"description": "Include engagement notices, slow-mode changes, restricted participation and other system rows.",
"prefill": true,
"title": "Include system events",
"type": "boolean"
},
"includeUpcomingLives": {
"default": false,
"description": "Emit an upcoming status row for scheduled channel streams instead of skipping them.",
"prefill": false,
"title": "Include upcoming streams",
"type": "boolean"
},
"language": {
"default": "en",
"description": "Interface language used when requesting YouTube pages and chat.",
"editor": "select",
"enum": [
"en",
"es",
"pt",
"de",
"fr",
"it",
"ja",
"ko",
"hi",
"id"
],
"enumTitles": [
"English",
"Spanish",
"Portuguese",
"German",
"French",
"Italian",
"Japanese",
"Korean",
"Hindi",
"Indonesian"
],
"prefill": "en",
"title": "Language",
"type": "string"
},
"liveCollectSecs": {
"default": 60,
"description": "How long to keep polling an active chat before stopping. Live captures are always partial.",
"maximum": 86400,
"minimum": 10,
"prefill": 10,
"title": "Live capture seconds",
"type": "integer"
},
"lookbackDays": {
"default": 30,
"description": "How far back to include ended streams from a channel. Use 0 for no limit.",
"maximum": 365,
"minimum": 0,
"prefill": 30,
"title": "Replay lookback days",
"type": "integer"
},
"maxMessagesPerVideo": {
"default": 5000,
"description": "Maximum unique chat events collected from each video. Use 0 to collect every available event.",
"maximum": 200000,
"minimum": 0,
"prefill": 3,
"title": "Messages per video",
"type": "integer"
},
"maxTimePerVideoSecs": {
"default": 600,
"description": "Safety limit for replay pagination on one video, in seconds. A run that reaches it reports partial_capture.",
"maximum": 86400,
"minimum": 30,
"prefill": 120,
"title": "Time budget per video",
"type": "integer"
},
"maxTotalItems": {
"default": 0,
"description": "Whole-run cap across all videos and summary rows. Use 0 for no limit.",
"maximum": 1000000,
"minimum": 0,
"prefill": 3,
"title": "Maximum dataset items",
"type": "integer"
},
"maxVideosPerChannel": {
"default": 5,
"description": "Maximum streams to process from each channel.",
"maximum": 50,
"minimum": 1,
"prefill": 1,
"title": "Videos per channel",
"type": "integer"
},
"mode": {
"default": "auto",
"description": "Auto detects live versus replay. Active captures an ongoing live chat. Replay reads the saved chat of an ended stream.",
"editor": "select",
"enum": [
"auto",
"active",
"replay"
],
"enumTitles": [
"Detect automatically",
"Live chat",
"Chat replay"
],
"prefill": "auto",
"title": "Chat mode",
"type": "string"
},
"pollIntervalMs": {
"default": 2000,
"description": "Minimum delay between live chat polls. YouTube's own timeout is honoured when it is longer.",
"maximum": 30000,
"minimum": 2000,
"prefill": 2000,
"title": "Live poll interval (ms)",
"type": "integer"
},
"regionCode": {
"default": "US",
"description": "Region used for YouTube page and chat requests.",
"editor": "select",
"enum": [
"US",
"GB",
"CA",
"AU",
"IN",
"BR",
"DE",
"FR",
"JP",
"KR",
"MX",
"ID"
],
"enumTitles": [
"United States",
"United Kingdom",
"Canada",
"Australia",
"India",
"Brazil",
"Germany",
"France",
"Japan",
"South Korea",
"Mexico",
"Indonesia"
],
"prefill": "US",
"title": "Region",
"type": "string"
},
"startOffsetSecs": {
"default": 0,
"description": "Replay only. Skip events before this video offset. Use 0 to start at the beginning.",
"maximum": 604800,
"minimum": 0,
"prefill": 0,
"title": "Start offset (seconds)",
"type": "integer"
},
"videoRefs": {
"description": "YouTube watch, live, shorts or youtu.be links, 11-character video IDs, or a channel live link such as @handle/live.",
"editor": "stringList",
"items": {
"type": "string"
},
"prefill": [
"https://www.youtube.com/watch?v=FQbNtLOVlwU"
],
"title": "Video URLs or IDs",
"type": "array"
}
},
"schemaVersion": 1,
"title": "YouTube Live Chat Input",
"type": "object"
}
Output schema
Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.
| Field | Type | Required | Description |
|---|---|---|---|
messages | string | optional | Dataset containing chat messages, paid events, memberships, gifts, system rows and stream summaries. |
Download the published output schema
View complete JSON
{
"actorOutputSchemaVersion": 1,
"description": "Chat events with authors, replay offsets, Super Chat and gift amounts, membership detail, badges, stream metadata and optional summaries.",
"properties": {
"messages": {
"description": "Dataset containing chat messages, paid events, memberships, gifts, system rows and stream summaries.",
"template": "{{links.apiDefaultDatasetUrl}}/items",
"title": "YouTube chat events",
"type": "string"
}
},
"title": "YouTube Live Stream & Replay Chat Extractor Output"
}
Dataset schema
Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.
Download the published dataset schema
View complete JSON
{
"actorSpecification": 1,
"views": {
"chatEvents": {
"display": {
"component": "table",
"properties": {}
},
"title": "Chat events",
"transformation": {
"fields": [
"videoId",
"eventType",
"authorName",
"messageText",
"videoOffsetText",
"amountText",
"currency"
]
}
},
"paidEvents": {
"display": {
"component": "table",
"properties": {}
},
"title": "Super Chats, Stickers & gifts",
"transformation": {
"fields": [
"videoId",
"eventType",
"authorName",
"amountText",
"amountValue",
"currency",
"giftCount"
]
}
},
"streamSummaries": {
"display": {
"component": "table",
"properties": {}
},
"title": "Stream summaries",
"transformation": {
"fields": [
"videoId",
"videoTitle",
"messageCount",
"superChatCount",
"membershipGiftCount",
"totalAmountByCurrency",
"chatComplete"
]
}
}
}
}
Key-value schema
Published key-value store definitions, when provided by this build.
This definition is not present in the default published build. See the published README for available documentation.
Published README
Read the full published documentation
YouTube Live Stream & Replay Chat Extractor
Read the chat behind a YouTube live stream — while it is running or from the saved replay after it ends. Give the actor a video link, a video ID or a channel, and it returns the chat timeline as structured records: text messages, Super Chats, Super Stickers, memberships, gift memberships and paid gift messages.
No cookies, login, API key or proxy setup is required.
What you get
- Replay chat in full — pages through the saved chat to the end of the stream instead of stopping after a fixed number of pages.
- Live chat capture — opens the live chat feed, emits the recent history already on screen, then polls at YouTube's own interval until your time window ends.
- Channel discovery — finds the current live stream and recent stream replays from an
@handle, channel URL orUC…channel ID. - Every visible event type — normal messages, Super Chats, Super Stickers, memberships, gift purchases, gift redemptions, paid gift messages, engagement notices and slow-mode/system notices.
- Replay offsets — each replay event carries
videoOffsetMsecand a readablevideoOffsetTextsuch as0:05:06. - Numeric money —
amountTextplusamountValueandcurrencywhen the amount is unambiguous. - Author detail — display name, channel ID, avatar, badges, handle, profile URL, and owner / moderator / member / verified flags.
- Stream context — title, channel, live status, start/end time, publish date, duration, views, likes and category.
- Type filters and caps — include or exclude event families, cap messages per video and total items, and restrict replay output to a time range.
- Optional summary — one
stream_summaryrecord per video with event counts, per-currency totals, top supporters and a completeness note.
Inputs
| Field | Default | What it does |
|---|---|---|
videoRefs |
— | Watch, live, shorts or youtu.be links, bare 11-character IDs, or channel live links such as @handle/live. |
channelRefs |
— | @handle, channel URL or UC… ID. Each channel is searched for streams. |
mode |
auto |
auto detects live versus replay. active forces live chat. replay forces saved replay chat. |
channelDiscoveryMode |
current_live_then_replays |
current_live, current_live_then_replays or latest_replays. |
maxVideosPerChannel |
5 |
How many streams to take from each channel. |
lookbackDays |
30 |
How far back to include ended streams from a channel. 0 means no limit. |
includeUpcomingLives |
false |
Emit an upcoming status row for scheduled channel streams. |
maxMessagesPerVideo |
5000 |
Chat events per video. 0 collects every available event. |
maxTotalItems |
0 |
Whole-run dataset cap. 0 means no limit. |
maxTimePerVideoSecs |
600 |
Safety budget for replay pagination on one video. |
includeNormalMessages |
true |
Include standard text messages. |
includeSuperChats |
true |
Include Super Chats and Super Stickers. |
includeMembershipEvents |
true |
Include memberships. |
includeGiftEvents |
true |
Include gift purchases, redemptions and paid gift messages. |
includeSystemEvents |
true |
Include engagement, slow-mode and other system notices. |
includePlaceholders |
false |
Include empty placeholder rows. |
includeSummary |
false |
Add a stream summary row per video. |
startOffsetSecs / endOffsetSecs |
0 / 0 |
Replay-only time window inside the video. |
liveCollectSecs |
60 |
How long to poll an active chat. |
pollIntervalMs |
2000 |
Minimum live poll delay; YouTube's longer timeout is honoured. |
language / regionCode |
en / US |
Page and chat request locale. |
includeMetadata |
true |
Repeat stream metadata on each chat row. |
Output
Every chat record has recordType: "live_chat_message" and:
- identity and timing:
videoId,videoUrl,chatType,messageId,eventType,messageType,timestamp,timestampUsec,publishedAt,videoOffsetMsec,videoOffsetText,scrapedAt - author:
authorName,authorChannelId,authorHandle,authorPhotoUrl,authorProfileUrl,authorBadges,memberBadge,isOwner,isModerator,isMember,isVerified - content:
messageText,messageParts[](text and emoji runs) - money and membership:
amountText,amountValue,currency,superChatColor,stickerName,stickerUrl,membershipText,membershipLevel,memberMonths - gifts:
giftCount,giftName,giftImageUrl,giftedBy - system:
systemAction,systemText - stream context when
includeMetadatais on:videoTitle,channelName,channelId,channelUrl,channelHandle,isLiveContent,isLiveNow,streamStatus,streamStartedAt,streamEndedAt,videoPublishedAt,videoDurationSeconds,videoViewCount,videoLikeCount,videoCategory - channel discovery context when the target came from a channel:
discoverySource,channelRef,isDiscoveredLive,isDiscoveredUpcoming,discoveredAt
Event values include message, super_chat, super_sticker, membership, membership_gift, gift_received, gift, system and placeholder.
When chat cannot be read, the actor emits a recordType: "status" row with a specific status such as chat_disabled, upcoming, no_replay, stream_ended, stream_live, channel_not_live, rate_limited or partial_capture, plus a plain-language error.
Examples
Read a complete replay:
{
"videoRefs": ["https://www.youtube.com/watch?v=FQbNtLOVlwU"],
"mode": "replay",
"maxMessagesPerVideo": 0
}
Capture 60 seconds of a live chat:
{
"videoRefs": ["https://www.youtube.com/live/74WjpIH4jeE"],
"mode": "active",
"liveCollectSecs": 60
}
Find a channel's current live stream and its two most recent replays:
{
"channelRefs": ["@CBSNews"],
"channelDiscoveryMode": "current_live_then_replays",
"maxVideosPerChannel": 2,
"lookbackDays": 30,
"includeSummary": true
}
Read only paid events from a replay between two offsets:
{
"videoRefs": ["1vvDbx3nYpg"],
"mode": "replay",
"includeNormalMessages": false,
"includeMembershipEvents": false,
"includeGiftEvents": false,
"includeSystemEvents": false,
"startOffsetSecs": 60,
"endOffsetSecs": 600
}
FAQ
Do I need cookies, an API key or a proxy? No. The actor reads public chat data without cookies or credentials. It connects directly and switches proxy automatically only when a request is blocked.
Why is a live run shorter than the whole chat?
A live read only sees what appears while the actor is collecting. The actor emits the recent history already on screen, then polls until liveCollectSecs ends. Run replay mode after the stream ends for the full timeline.
How much replay chat can I get?
As much as YouTube exposes. Pagination stops only at the end of the replay, maxMessagesPerVideo, maxTotalItems, maxTimePerVideoSecs, or a real error. There is no fixed page cap.
What is the difference between active and auto?
auto checks the video and chooses live or replay. active insists on live chat and reports stream_ended if the stream is already over. replay insists on saved chat and reports stream_live if the stream is still running.
Why is amountValue sometimes missing?
Only unambiguous amounts are converted to a number and currency. The original amountText is always kept. Unusual formats are counted in amountsNotRead on the summary row instead of being guessed.
Are gift memberships the same as memberships?
No. A purchase is membership_gift (the buyer sent memberships), a redemption is gift_received (someone received one), and a paid gift message is gift. The summary keeps separate counts.
Why are some messages missing from a channel result?
Channel discovery only returns streams that match channelDiscoveryMode, lookbackDays and maxVideosPerChannel. Some streams have chat disabled, no saved replay, or are members-only. Each of those cases produces a status row instead of fabricated data.
Does the actor convert currencies or provide a single total?
No. Totals stay per currency in totalAmountByCurrency; no exchange-rate service is used. Top supporters are ranked by numeric amount and keep their own currency.
Can it read members-only chat or deleted-message moderation details? No. Those require an authenticated channel session. The actor reads public chat, reports unavailable paths as status rows, and never fakes restricted data.
Limits
- Live captures are partial by design; replay is the complete path.
- Members-only chat, age/region-gated videos and moderation logs are not available without authentication.
- Reply-thread parent IDs and a numeric concurrent-viewer count are not exposed in the public chat payload, so they are not returned.
- Currency conversion is intentionally not performed.
- Chat availability is controlled by the creator. A stream can be public while its chat or replay is disabled.
Data source
The actor reads YouTube's public watch pages and its public InnerTube live-chat endpoints. It does not log in, post messages, or perform moderation actions.
Python quickstart
Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.
Source build RX1LgB29gltcaO0El. Documentation is regenerated from the default published build; private drafts are not included.