# Kick Chat Replay Scraper - VOD & Clip Chat Logs (`hgservices/kick-chat-replay-scraper`) Actor

Scrape the full chat replay of Kick.com VODs and clips by URL: every message with username, badges, subscriber months, emotes, replies and video timestamp. Pick a time range or cap the messages per video. No login needed.

- **URL**: https://apify.com/hgservices/kick-chat-replay-scraper.md
- **Developed by:** [Harish Garg](https://apify.com/hgservices) (community)
- **Stats:** 5 total users, 2 monthly users, 96.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 chat messages

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Download the **full chat replay** of any [Kick.com](https://kick.com) VOD or clip. Paste a video URL, and get **every chat message** that viewers sent during that part of the stream, with the **username, badges, subscriber months, emotes, replies and the exact video timestamp** of each message.

Kick videos have no comment section. The live chat is where viewers react, so the chat replay is the "comments" of a Kick video. This scraper gets all of it, in time order, as clean structured data.

Export the Kick chat log as **JSON, CSV, Excel or HTML**, or read it from the API. **No Kick account, no login and no coding needed.** Run it in Apify Console, call it from your code, schedule it, or let an AI assistant such as Claude or ChatGPT run it for you.

### What does Kick Chat Replay Scraper do?

- **Full Kick chat logs** — every message of a VOD, from the first to the last, including streams with more than 100,000 messages.
- **Clip chat** — the chat that was on screen during a Kick clip.
- **Video timestamps** — the position of each message in the video, in seconds and as `H:MM:SS`.
- **Chatter details** — username, user ID, name color, badges (Subscriber, Sub Gifter, Moderator and others) and subscription months.
- **Emotes** — the emotes in each message, and a clean text version of the message with emote names.
- **Replies** — for a reply, the original message and its author.
- **Time ranges** — get only one part of a long stream, for example from 1:00:00 to 1:30:00.
- **Many videos in one run** — add as many VOD and clip URLs as you need.

### Why scrape Kick chat replays?

- **Highlight detection** — find chat spikes with `offsetSeconds` and jump to the best moments of a VOD.
- **Audience research** — see what viewers talk about, which moments get reactions and which emotes they use.
- **Sentiment and moderation analysis** — send the full chat to a spreadsheet, a database or an AI model.
- **Clip context** — get exactly the chat that viewers saw during a clip.
- **Creator and brand analytics** — measure chat activity during sponsored segments, and compare streams over time.
- **Community analysis** — find the most active chatters, subscribers and gifters of a channel.
- **Archives and research datasets** — keep a permanent copy of the chat before the VOD is deleted.

### Input

Fill in the **Input** tab, or send the same fields as JSON through the API.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `videoUrls` | string\[] | — | **Required.** Kick VOD URLs (`https://kick.com/<channel>/videos/<id>`, where `<id>` is the VOD ID, the livestream ID or the livestream slug) or clip URLs (`https://kick.com/<channel>/clips/<id>`). |
| `maxMessagesPerVideo` | integer | `0` | The maximum number of messages for each video, counted from the start of the time range. `0` gives all messages. |
| `startOffsetSeconds` | integer | — | Start the chat at this point of the video, in seconds. For example, `3600` starts at 1:00:00. |
| `endOffsetSeconds` | integer | — | Stop the chat at this point of the video, in seconds. Must be greater than the start offset. |

The start and end offsets apply to every video in the run. Duplicate URLs are scraped only once, also when two URLs name the same VOD in different forms. A livestream ID or slug works only for VODs of about the last 30 days, which Kick lists on the channel. Channel pages are not supported: open a VOD or a clip and copy its URL.

#### Input examples

**The full chat of a VOD**

```json
{
    "videoUrls": ["https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba"]
}
```

**The chat of a clip**

```json
{
    "videoUrls": ["https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"]
}
```

**Minutes 10 to 20 of a VOD, at most 5,000 messages**

```json
{
    "videoUrls": ["https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba"],
    "startOffsetSeconds": 600,
    "endOffsetSeconds": 1200,
    "maxMessagesPerVideo": 5000
}
```

### Output

You get **one row for each chat message**, in time order for each video. You can download the dataset in various formats such as **JSON, HTML, CSV, or Excel**. This is an example of a reply:

```json
{
    "videoType": "vod",
    "videoId": "e8885172-7587-4fa8-80a2-ec2f140159ba",
    "videoUrl": "https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba",
    "videoTitle": "🦖LIVE🦖LOCK IN🦖GTA V🦖NOPIXEL V🦖BIG DRAMA🦖MEGA DAY🦖HEIST DAY🦖",
    "channel": "xqc",
    "messageId": "52a2edfc-c79b-444e-95aa-86eb25760208",
    "messageType": "reply",
    "content": "eheheheheeeeEee CatSmile yeee [emote:5747912:collectiblesuwu]",
    "contentText": "eheheheheeeeEee CatSmile yeee collectiblesuwu",
    "emotes": [{ "id": "5747912", "name": "collectiblesuwu" }],
    "createdAt": "2026-10-09T18:52:37Z",
    "offsetSeconds": 600,
    "videoTimestamp": "0:10:00",
    "userId": 8816216,
    "username": "QunKe",
    "userSlug": "qunke",
    "userColor": "#FFC466",
    "badges": ["Sub Gifter"],
    "subscriberMonths": null,
    "replyTo": {
        "messageId": "b496df58-0467-4d8f-b793-da9521b60f65",
        "content": "agahi Hope you're well Qun!",
        "username": "Flabbz",
        "userId": 1689452
    },
    "scrapedAt": "2026-10-10T05:15:59.337289+00:00"
}
```

#### Output fields

| Field | Description |
|-------|-------------|
| `videoType` | `vod` or `clip` |
| `videoId`, `videoUrl`, `videoTitle`, `channel` | The video of the message |
| `messageId` | The Kick ID of the message |
| `messageType` | `message` or `reply` |
| `content` | The message text, with Kick emote codes |
| `contentText` | The message text, with emote names in place of the emote codes |
| `emotes` | The emotes in the message (ID and name) |
| `createdAt` | When the message was sent (UTC) |
| `offsetSeconds`, `videoTimestamp` | The position of the message in the video (for a clip, from the start of the clip) |
| `userId`, `username`, `userSlug`, `userColor` | The chatter |
| `badges`, `subscriberMonths` | The chat badges of the chatter, and the length of the subscription in months |
| `replyTo` | For a reply: the original message and its author. `null` for other messages |
| `scrapedAt` | When the message was scraped (UTC) |

#### Run summary

Every run also saves a `SUMMARY` record in the key-value store (**Storage** tab), with one entry per video:

- `videoUrl`, `videoType`, `videoId`, `videoTitle`, `channel`, `channelId` — the video
- `chatFrom` and `chatTo` — the time range of the chat (UTC)
- `messagesSaved` — the number of messages saved
- `stoppedAtLimit` — `true` when **Max messages per video** stopped the video
- `failedTimeRanges` — the parts of the video that could not be read, if any
- `error` — why a video gave no messages, for example `Video not found.`

### How to use Kick Chat Replay Scraper

You can use the scraper in three ways: in Apify Console, through the Apify API, or from an AI assistant. All three give the same data.

#### 1. Scrape a Kick chat replay in Apify Console (no code)

1. Click **Try for free** and sign in to Apify. A free account is enough.
2. In **Video URLs**, add one or more Kick VOD or clip URLs, one per line. For example: `https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2`
3. Optional: set **Max messages per video**.
4. Optional: set a **Start offset** and an **End offset** in seconds to get only one part of the video.
5. Click **Start**.
6. Open the **Output** tab. View the chat as a table, or download it as JSON, CSV, Excel or HTML.

#### 2. Get Kick chat data with the Apify API

Run the scraper and read the results from any programming language with the [Apify API](https://docs.apify.com/api/v2). Get your API token in Apify Console under **Settings → API & Integrations**, and replace `<YOUR_API_TOKEN>` in the examples below.

**HTTP (cURL)** — run the scraper and get the chat of a clip in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/hgservices~kick-chat-replay-scraper/run-sync-get-dataset-items?format=json" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "videoUrls": ["https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"] }'
```

Change `format=json` to `format=csv` or `format=xlsx` to get a spreadsheet.

A synchronous call waits at most 5 minutes, and a full VOD can take longer. For a VOD, start the run, and read the dataset when the run finishes:

```bash
## Start the run. The response contains data.id (the run ID) and data.defaultDatasetId.
curl -X POST "https://api.apify.com/v2/acts/hgservices~kick-chat-replay-scraper/runs" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "videoUrls": ["https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba"] }'

## Check the run. Wait until data.status is SUCCEEDED.
curl "https://api.apify.com/v2/actor-runs/<RUN_ID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

## Download the chat as CSV.
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" -o kick-chat.csv
```

**JavaScript / Node.js** (`npm install apify-client`) — get 30 minutes of a VOD chat:

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

// call() starts the run and waits until it finishes.
const run = await client.actor('hgservices/kick-chat-replay-scraper').call({
    videoUrls: ['https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba'],
    startOffsetSeconds: 3600,
    endOffsetSeconds: 5400,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const message of items) {
    console.log(message.videoTimestamp, message.username, message.contentText);
}
```

**Python** (`pip install apify-client`, version 3.0 or later) — find the busiest minutes of a VOD:

```python
from collections import Counter

from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

## call() starts the run and waits until it finishes.
run = client.actor("hgservices/kick-chat-replay-scraper").call(run_input={
    "videoUrls": ["https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba"],
})
if run is None:
    raise RuntimeError("The run was not found.")

## Count the messages in each minute of the stream to find the highlights.
per_minute = Counter()
for message in client.dataset(run.default_dataset_id).iterate_items():
    per_minute[message["offsetSeconds"] // 60] += 1

for minute, count in per_minute.most_common(5):
    print(f"Minute {minute}: {count} messages")
```

#### 3. Use Kick chat data in Claude, ChatGPT and other AI assistants (MCP)

This scraper works as a tool for AI assistants through the [Apify MCP server](https://mcp.apify.com/). Your assistant can find the scraper, read its input options, run it, and use the chat in its answer. You sign in to Apify once, and the runs use your Apify account.

**Claude (claude.ai or Claude Desktop)** — go to **Settings → Connectors**, add a custom connector, and enter `https://mcp.apify.com`. Sign in to Apify when Claude asks.

**Claude Code**

```bash
claude mcp add --transport http apify https://mcp.apify.com
```

**ChatGPT** — turn on **Developer mode** in **Settings → Apps & Connectors → Advanced settings**. Then create a connector with the MCP server URL `https://mcp.apify.com`.

**Cursor, VS Code and other MCP clients** — add the Apify MCP server to your MCP configuration:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=actors,hgservices/kick-chat-replay-scraper"
        }
    }
}
```

The `tools` parameter adds this scraper as a ready-to-use tool. You can also use the [MCP configurator](https://mcp.apify.com/) to make the configuration for your client.

Then ask in plain language:

> Use the Kick Chat Replay Scraper to get the chat of this clip, and summarize how viewers reacted: https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2

> Get the chat from 1:00:00 to 1:30:00 of this Kick VOD and list the 10 most used emotes: https://kick.com/xqc/videos/e8885172-7587-4fa8-80a2-ec2f140159ba

> Which minutes of the first 2 hours of this Kick VOD had the most chat messages? Give me the timestamps.

For the best results with AI assistants, give a time range or a message limit for long VODs. A short run finishes while the assistant waits, and a smaller result fits better in the conversation.

### Integrations and scheduling

Connect the scraper to the tools you already use with [Apify integrations](https://apify.com/integrations): **Google Sheets, Slack, Zapier, Make, n8n, Airbyte, Keboola** and more. Use **webhooks** to call your own endpoint when a run finishes.

Use **Schedules** in Apify Console to run the scraper automatically, for example every day on the newest VOD of a channel.

### Tips for faster Kick chat scraping

- **Use a time range.** If you need only one part of a stream, set **Start offset** and **End offset**. The run reads only that part.
- **Set a message limit for a quick sample.** **Max messages per video** stops each video at that number of messages.
- **Expect long runs for busy VODs.** A clip or a quiet 2-hour VOD finishes in less than a minute. A busy VOD with about 127,000 messages took 22 to 40 minutes in tests.
- **Long runs are safe.** If a run is interrupted by the platform, it continues from the last saved part of the video.
- **Keep the default memory.** The default memory is enough for every run.

### FAQ

**Do Kick videos have comments?**
No. Kick VODs and clips have no comment section. The chat replay is the only viewer discussion of a video, and this scraper gets it.

**Do I need a Kick account?**
No. You need only an Apify account. The scraper reads the public chat that every visitor can see in the replay.

**How old can a VOD be?**
Kick keeps chat history for about one year. Kick usually deletes VODs before that, and the URL of a deleted VOD does not work. A deleted or private video shows `Video not found.` in the `SUMMARY` record.

**Can I scrape the chat of a stream that is still live?**
Yes. Use the VOD URL of the live stream. You get the chat from the start of the stream to the time of the run.

**Why is a part of a video missing?**
If Kick does not answer for a time range, the run log shows a warning, and the `SUMMARY` record shows the range under `failedTimeRanges`. Run the scraper again with a start and end offset for that range.

**Why did I get no messages?**
Some streams have no chat, and some videos are deleted. Check the `SUMMARY` record and the warnings in the run log.

**Can I get the chat of a whole channel?**
Yes. Copy the VOD URLs from the **Videos** page of the channel on Kick, and add all of them to **Video URLs**.

**Is it legal to scrape Kick chat?**
The scraper collects only public chat messages and never signs in. Chat messages contain usernames, which can be personal data. Make sure that your use of the data obeys the GDPR and other laws in your country, and the Kick Terms of Service. If you are not sure, ask a lawyer.

### Support and feedback

Did you find a bug, or do you need a field that is not here? Open an issue on the **Issues** tab. Custom solutions, such as whole-channel chat archives or live chat monitoring, are available on request.

This scraper is not affiliated with or endorsed by Kick.com.

# Actor input Schema

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

Kick.com VOD or clip URLs, one per line. Supported: VOD pages (https://kick.com/<channel>/videos/<uuid>), VOD URLs with the livestream ID or slug in place of the UUID (https://kick.com/<channel>/videos/134850792) and clip URLs (https://kick.com/<channel>/clips/<id>). For a clip, the Actor returns the chat of the clipped part of the stream.

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

The maximum number of chat messages to save for each video, counted from the start of the selected time range. Use 0 for all messages. Large streams can have more than one million messages.

## `startOffsetSeconds` (type: `integer`):

Optional. Skip the chat before this point of the video, in seconds from the video start. For example, 3600 starts at 1:00:00. Leave empty to start at the beginning.

## `endOffsetSeconds` (type: `integer`):

Optional. Stop at this point of the video, in seconds from the video start. Leave empty to continue to the end of the video.

## Actor input object example

```json
{
  "videoUrls": [
    "https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"
  ],
  "maxMessagesPerVideo": 0
}
```

# Actor output Schema

## `messages` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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": [
        "https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hgservices/kick-chat-replay-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": ["https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"] }

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    "https://kick.com/xqc/clips/clip_01M4HN69RXAY9BJQXC35EQ3VA2"
  ]
}' |
apify call hgservices/kick-chat-replay-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hgservices/kick-chat-replay-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ciUKeVWYE1AJFCJOb/builds/qc98cbbYYocxJe2O0/openapi.json
