# Twitch VOD Chat Scraper — Full Chat Replay Export (`haketa/twitch-vod-chat-scraper`) Actor

Export the complete chat replay of any Twitch VOD — every message with its timestamp, username, badges and emotes. Analyze sentiment, find hype moments, and study communities. Just paste a VOD URL, no code or token needed.

- **URL**: https://apify.com/haketa/twitch-vod-chat-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Social media, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

<h1>💬 Twitch VOD Chat Scraper</h1>

<p><strong>Export the complete chat replay of any Twitch VOD — every message, timestamped.</strong></p>

![ChatReplay](https://img.shields.io/badge/💬-Full%20Chat%20Replay-9146FF) ![Timestamped](https://img.shields.io/badge/⏱️-Timestamped%20Messages-6f42c1) ![Emotes](https://img.shields.io/badge/😂-Emotes·Badges-1f6feb) ![NoToken](https://img.shields.io/badge/🔓-No%20Token%20Needed-2da44e) ![Export](https://img.shields.io/badge/⬇️-Excel·CSV·JSON-24292f)

Paste any Twitch **VOD** (past broadcast or highlight) and this Actor exports its **entire chat replay** — every message with its **timestamp, username, badges, emotes and color** — as a clean spreadsheet. It's the fastest way to analyze a stream's chat: find the hype moments, measure sentiment, study a community, or build a dataset.

> 🔓 **No token, no login, no code.** Paste a VOD URL and press **Start**.

---

### ✨ Why you'll love it

- 💬 **The full chat, in order** — every message from a broadcast, with its exact stream timestamp.
- ⏱️ **Timestamped** — jump straight to the moments where chat popped off.
- 😂 **Emotes & badges** — see which emotes were spammed and who's a sub, mod or VIP.
- 🔥 **Find the hype** — spikes in chat volume reveal a stream's best moments (clip-worthy).
- 🔓 **Works without a token** — no Twitch account or API keys.
- 🧹 **Clean, deduplicated output** — spreadsheet-ready.

---

### 👥 Who it's for

| You are… | Use it to… |
| :-- | :-- |
| ✂️ **Clipper / editor** | Find chat-hype spikes to locate the most clip-worthy moments in a long VOD. |
| 📊 **Streamer / analyst** | Measure engagement, top chatters, emote usage and sentiment over a stream. |
| 🧪 **Researcher** | Study online communities, toxicity, or fan behavior at scale. |
| 🤖 **AI / ML engineer** | Build conversational or sentiment datasets from real chat. |
| 📈 **Agency / esports** | Report on audience engagement for sponsors and post-mortems. |

---

### ⚡ Quick start

1. Open the Actor.
2. Paste one or more **VOD URLs** into **Twitch VOD URLs** — e.g. `https://www.twitch.tv/videos/2123456789`. *(Or enter channel names in **Channels** to grab their most recent broadcasts automatically.)*
3. Set **Max messages per VOD** (or `0` for the entire chat replay).
4. Press **Start**, then open the **Output** tab to preview.
5. Hit **Export** → **Excel / CSV / JSON**, or send to **Google Sheets**, **Zapier**, **Make**, or your app via API.

---

### 🧩 Input options

#### 🎬 Twitch VOD URLs · `videoUrls`
The VODs whose chat you want. Paste VOD URLs (`https://www.twitch.tv/videos/2123456789`) or bare video IDs. Add as many as you like.

#### 📺 Channels · `channels` *(optional)*
Enter channel names (`kaicenat`, `pokimane`) to automatically grab the chat of their most recent past broadcasts — handy when you don't have a specific VOD link.

#### 🔢 Recent VODs per channel · `maxVideosPerChannel`
When using **Channels**, how many of each channel's most recent VODs to collect chat from.

#### 💬 Max messages per VOD · `maxMessagesPerVideo`
Cap the messages collected per VOD (from the start of the stream). Set **0** to collect the **entire** chat replay — the full VOD, start to finish.

#### 🌐 Proxy · `proxyConfiguration`
Recommended and on by default. Standard **datacenter proxies** are enough.

---

### 🧪 Example inputs

<details open>
<summary>💬 <strong>First 3,000 messages of a VOD</strong></summary>

```json
{ "videoUrls": ["https://www.twitch.tv/videos/2123456789"], "maxMessagesPerVideo": 3000 }
````

</details>

<details>
<summary>🔥 <strong>The entire chat replay (full VOD)</strong></summary>

```json
{ "videoUrls": ["https://www.twitch.tv/videos/2123456789"], "maxMessagesPerVideo": 0 }
```

</details>

<details>
<summary>📺 <strong>Latest broadcasts of several channels</strong></summary>

```json
{ "channels": ["kaicenat", "pokimane", "xqc"], "maxVideosPerChannel": 1, "maxMessagesPerVideo": 5000 }
```

</details>

***

### 📤 Output

Every chat message is one row, in stream order. Only the fields that exist are included, so your export stays clean.

#### 📋 Field reference

| Field | 📖 Description |
| :-- | :-- |
| `timestamp` | ⏱️ Time within the stream (`HH:MM:SS`). |
| `offsetSeconds` | The message's offset from stream start, in seconds. |
| `createdAt` | When the message was sent (absolute time). |
| `username` | 🧑 The chatter's username. |
| `displayName` | Their display name. |
| `message` | 💬 The message text. |
| `emotes` | 😂 Emotes used in the message. |
| `userColor` | 🎨 The chatter's name color. |
| `badges` | 🏷️ Chat badges (subscriber, moderator, vip, …). |
| `isSubscriber` / `isModerator` / `isVip` | Quick flags derived from badges. |
| `channel` | 📺 The channel (broadcaster). |
| `channelName` | Channel display name. |
| `videoTitle` | 🎬 The VOD title. |
| `videoId` | The VOD's ID. |
| `game` | 🎮 The category/game of the VOD. |

#### 💬 Sample rows

```json
[
  { "timestamp": "00:22", "username": "7ussain", "message": "live PagChomp", "emotes": "PagChomp", "badges": "subscriber", "isSubscriber": true, "channel": "pokimane", "videoTitle": "just chatting <3" },
  { "timestamp": "01:06", "username": "mod_dave", "message": "welcome everyone", "badges": "moderator", "isModerator": true, "channel": "pokimane", "videoTitle": "just chatting <3" }
]
```

***

### 💡 Use cases in detail

**✂️ Find the most clip-worthy moments**
Count messages per minute (using `offsetSeconds`) to find chat-hype spikes — the exact timestamps where the stream popped off. Perfect for clippers and highlight editors.

**📊 Analyze engagement & sentiment**
Export the full chat and run sentiment or emote-frequency analysis to understand how the audience reacted, minute by minute.

**🧑‍🤝‍🧑 Study a community**
See who the top chatters are, the balance of subscribers vs non-subs, and how conversation flows across a broadcast.

**🤖 Build datasets**
Turn real Twitch chat into training or research data, with timestamps, users and emotes intact.

***

### 🧠 Tips for best results

- 🔥 **Group by minute** (`offsetSeconds` ÷ 60) to plot chat volume and spot hype spikes.
- 💬 **Set `maxMessagesPerVideo` to 0** to guarantee the complete chat replay.
- 🎬 **VODs expire** — grab a broadcast's chat while the VOD is still available on the channel.
- 🧹 **Deduplication is automatic** — every message appears once.

***

### 🔌 Export & integrations

⬇️ **Excel · CSV · JSON · XML** · 📊 **Google Sheets & Airtable** · 🔔 **Webhooks & API** · 🤖 **Make, Zapier, n8n**

***

### ❓ FAQ

**Do I need a token or Twitch account?** — No. The Actor collects public chat replay without any login.

**Can I get the entire chat of a long stream?** — Yes. Set **Max messages per VOD** to `0` and the Actor walks the whole VOD from start to finish.

**Why can't it find a VOD?** — VODs expire after a set time (often 7–60 days). Once a broadcast's VOD is gone from the channel, its chat replay is no longer available.

**Does it include emotes and badges?** — Yes — emotes used in each message, plus badges (subscriber, moderator, VIP) and the chatter's color.

**Will I get duplicates?** — No. Messages are deduplicated within each run.

**Can I schedule it?** — Yes. Use Apify Schedules to capture chat from new broadcasts automatically.

***

### ⚖️ Legal & responsible use

This Actor collects only publicly available chat information for legitimate research, analytics and content purposes. You are responsible for how you use the data, including compliance with applicable laws (such as GDPR and CCPA) and platform terms. Do not use the data to harass, dox or profile individuals, and always respect the privacy and preferences of the people in your results.

# Actor input Schema

## `videoUrls` (type: `array`):

The VODs (past broadcasts / highlights) whose chat you want. Paste VOD URLs (e.g. https://www.twitch.tv/videos/2123456789) or just the video IDs. Add as many as you like.

## `channels` (type: `array`):

Optionally, enter channel names (e.g. "kaicenat", "pokimane") to automatically grab the chat of their most recent past broadcasts.

## `maxVideosPerChannel` (type: `integer`):

When using the Channels field, how many of each channel's most recent VODs to collect chat from.

## `maxMessagesPerVideo` (type: `integer`):

Cap the number of chat messages collected per VOD (from the start of the stream). Set 0 to collect the entire chat replay — the full VOD.

## `proxyConfiguration` (type: `object`):

Recommended for reliable collection. Datacenter proxies are enough for this Actor.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.twitch.tv/videos/2123456789"
  ],
  "channels": [
    "kaicenat",
    "pokimane"
  ],
  "maxVideosPerChannel": 1,
  "maxMessagesPerVideo": 3000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open to view, filter and export all collected chat messages (JSON, CSV, Excel).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [],
    "channels": [],
    "maxMessagesPerVideo": 3000,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/twitch-vod-chat-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "videoUrls": [],
    "channels": [],
    "maxMessagesPerVideo": 3000,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/twitch-vod-chat-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [],
  "channels": [],
  "maxMessagesPerVideo": 3000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/twitch-vod-chat-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=haketa/twitch-vod-chat-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Twitch VOD Chat Scraper — Full Chat Replay Export",
        "description": "Export the complete chat replay of any Twitch VOD — every message with its timestamp, username, badges and emotes. Analyze sentiment, find hype moments, and study communities. Just paste a VOD URL, no code or token needed.",
        "version": "0.1",
        "x-build-id": "Mc2uLksbaWohO78U9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/haketa~twitch-vod-chat-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-haketa-twitch-vod-chat-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/haketa~twitch-vod-chat-scraper/runs": {
            "post": {
                "operationId": "runs-sync-haketa-twitch-vod-chat-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/haketa~twitch-vod-chat-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-haketa-twitch-vod-chat-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "videoUrls": {
                        "title": "Twitch VOD URLs",
                        "type": "array",
                        "description": "The VODs (past broadcasts / highlights) whose chat you want. Paste VOD URLs (e.g. https://www.twitch.tv/videos/2123456789) or just the video IDs. Add as many as you like.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "channels": {
                        "title": "Channels (optional)",
                        "type": "array",
                        "description": "Optionally, enter channel names (e.g. \"kaicenat\", \"pokimane\") to automatically grab the chat of their most recent past broadcasts.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxVideosPerChannel": {
                        "title": "Recent VODs per channel",
                        "minimum": 1,
                        "type": "integer",
                        "description": "When using the Channels field, how many of each channel's most recent VODs to collect chat from.",
                        "default": 1
                    },
                    "maxMessagesPerVideo": {
                        "title": "Max messages per VOD",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap the number of chat messages collected per VOD (from the start of the stream). Set 0 to collect the entire chat replay — the full VOD.",
                        "default": 3000
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Recommended for reliable collection. Datacenter proxies are enough for this Actor.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
