# Kick VOD Downloader (`automation-lab/kick-vod-downloader`) Actor

Download authorized public Kick VODs and export stream, channel, HLS source, stored-file, and retrieval-status metadata.

- **URL**: https://apify.com/automation-lab/kick-vod-downloader.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Kick VOD Downloader

Kick VOD Downloader downloads authorized, anonymously reachable public Kick VOD media and exports a structured archive record.
Give it one or more `kick.com/{channel}/videos/{uuid}` URLs.
It resolves the public Kick API record, selects an HLS rendition, stores the MPEG-TS file in the run key-value store, and writes metadata to the default dataset.

Use metadata-only mode when you need a lightweight manifest rather than a copied video.
The output includes the channel, title, timestamps, duration, thumbnail, views, categories, HLS source, stored-file link, byte size, and retrieval status.

### What can you do with this Kick VOD downloader?

- Back up your own public Kick broadcasts before they disappear.
- Archive authorized campaign or creator media with source evidence.
- Build a recurring manifest of supplied VOD URLs.
- Resolve HLS sources and normalized metadata for a media pipeline.
- Export records to JSON, CSV, Excel, a database, or a webhook.
- Check whether previously collected public VOD URLs still resolve.

This Actor accepts supplied VOD URLs.
It does not discover channels, record live streams, bypass access controls, or access subscriber-only media.

### Who is it for?

**Creators and channel teams** can preserve authorized public broadcasts.

**Agencies** can retain campaign evidence for creators they manage.

**Media researchers** can create reproducible archives of public material they are permitted to copy.

**Developers** can feed stable dataset records and stored-file URLs into downstream processing.

**Archive operators** can run metadata-only checks before deciding which VODs to transfer.

### Why use this Actor?

- Uses the public VOD detail and HLS surfaces rather than rendering a heavy browser.
- Supports `best`, 1080p, 720p, 480p, 360p, and smallest-available selection.
- Streams segments through a byte limit instead of loading an entire VOD into memory.
- Charges one item event only after a VOD is successfully resolved.
- Suppresses duplicate VOD UUIDs in one run.
- Returns explicit failed records while failing the run if every supplied VOD fails.
- Needs no account or proxy for supported public VODs.

### Input

| Field | Type | Default | Description |
|---|---|---:|---|
| `startUrls` | array | required | Public Kick VOD URLs in the supported channel/videos/UUID form. |
| `maxItems` | integer | URL count | Maximum unique VODs to process, from 1 to 25. |
| `downloadVideo` | boolean | `true` | Store the selected rendition; disable for metadata only. |
| `quality` | string | `480p` | `best`, `1080p`, `720p`, `480p`, `360p`, or `worst`. |
| `maxVideoSizeMb` | integer | `100` | Stop before the stored file exceeds 1–500 MB. |
| `maxRequestRetries` | integer | `2` | Retry temporary network, rate-limit, and server failures 0–5 times. |

Example download input:

```json
{
  "startUrls": [
    { "url": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4" }
  ],
  "maxItems": 1,
  "downloadVideo": true,
  "quality": "360p",
  "maxVideoSizeMb": 20
}
```

Example metadata-only input:

```json
{
  "startUrls": [
    { "url": "https://kick.com/xqc/videos/9c70ebbe-01d3-48d4-8b8f-b9514ba7d813" }
  ],
  "downloadVideo": false
}
```

### Getting started

1. Open the Actor input page.
2. Add public Kick VOD URLs.
3. Keep **Save video files** enabled to copy media.
4. Choose a quality and a practical byte limit.
5. Click **Start**.
6. Open **Dataset** for normalized records.
7. Follow `storedFileUrl` or open **Key-value store** for copied files.
8. Export or integrate the dataset as needed.

Start with one short VOD.
Long broadcasts can exceed the size limit or run timeout.
Use metadata-only mode to inventory a larger supplied list cheaply.

### Output fields

| Field | Meaning |
|---|---|
| `vodId` | Kick VOD UUID. |
| `title` | Stream session title when exposed. |
| `channel`, `channelId` | Kick channel slug and ID. |
| `uploader`, `uploaderId` | Public channel user identity. |
| `createdAt` | VOD creation timestamp. |
| `durationSeconds` | Duration normalized from Kick milliseconds. |
| `thumbnailUrl` | Public generated VOD thumbnail. |
| `views` | Public view count at retrieval time. |
| `categories` | Public Kick content category names. |
| `mature` | Public mature-content flag when exposed. |
| `sourceUrl` | Canonical supplied Kick VOD URL. |
| `hlsSourceUrl` | Public master HLS playlist URL. |
| `selectedQuality` | Rendition actually selected. |
| `storedFileKey` | Run storage key for the MPEG-TS file. |
| `storedFileUrl` | Apify API URL for the stored file. |
| `storedFileSizeBytes` | Bytes copied successfully. |
| `contentType` | `video/mp2t` for downloaded files. |
| `retrievalStatus` | `downloaded`, `metadata_only`, or `failed`. |
| `error` | Concise per-URL failure reason, otherwise null. |
| `scrapedAt` | UTC retrieval timestamp. |

### Example output

```json
{
  "vodId": "78a39add-ac70-4c16-8fae-9eca007d1cc4",
  "title": "LIVE HERE DRAMA NEWS VIDEOS GAMES",
  "channel": "xqc",
  "channelId": "668",
  "uploader": "xQc",
  "uploaderId": "676",
  "createdAt": "2026-07-29T20:13:48.000000Z",
  "durationSeconds": 4,
  "thumbnailUrl": "https://images.kick.com/video_thumbnails/DsuAwCgUc9Bh/QRBZDFTkhQVg/720.webp",
  "views": 2599,
  "categories": ["Just Chatting"],
  "mature": false,
  "sourceUrl": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4",
  "hlsSourceUrl": "https://stream.kick.com/.../master.m3u8",
  "selectedQuality": "360p30",
  "storedFileKey": "kick-vod-78a39add-ac70-4c16-8fae-9eca007d1cc4-360p30.ts",
  "storedFileSizeBytes": 408336,
  "contentType": "video/mp2t",
  "retrievalStatus": "downloaded",
  "error": null
}
```

Counts and URLs can change as Kick updates public data.
Null means the source did not expose that field.

### Download format and quality

Kick publishes VODs as HLS renditions.
The Actor selects the requested maximum height, or the nearest lower available rendition.
`best` selects the highest advertised stream.
`worst` selects the smallest.

Media segments are concatenated into an MPEG transport stream (`.ts`).
This preserves the HLS audio/video transport without a costly transcoding pass.
Most media players and tools such as FFmpeg can read it directly.
Transcoding or remuxing is intentionally left to downstream workflows.

### How much does it cost to download a Kick VOD?

Pay-per-event pricing has a one-time run-start event and one item event per successfully resolved VOD.
The same item event covers either a stored download or a metadata-only archive record; failed URLs are not charged item events.

The exact active tier prices appear on the Actor pricing tab before a run.
At the BRONZE curve, the run start is $0.0085 and each successful VOD is $0.005468.
That is about $0.014 for one VOD, $0.036 for five VODs, or $0.145 for 25 VODs.
Bulk tier discounts apply automatically according to your Apify plan.

Large files consume more transfer and storage even though the event is per successful file.
Use an appropriate `maxVideoSizeMb` and avoid requesting unnecessary quality.

### Scheduled archive workflow

1. Maintain authorized VOD URLs in your system.
2. Run metadata-only mode on a schedule.
3. Compare `vodId`, `views`, and `retrievalStatus` with prior exports.
4. Submit selected newly seen URLs to a download run.
5. Copy stored files to your long-term storage before run retention expires.
6. Keep the dataset record as the retrieval manifest.

The Actor does not discover new VODs by channel.
Your scheduler or upstream process must supply URLs.

### Integrations

Use Apify integrations to send dataset items to Google Sheets, Make, Zapier, Slack, webhooks, or cloud storage workflows.
A webhook can react when the run succeeds.
The dataset API is suited to manifests and status checks.
The key-value-store API serves the actual `.ts` records.

For durable archiving, copy files out of run storage promptly.
Do not assume temporary run storage is a permanent media library.

### API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~kick-vod-downloader/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4"}],"downloadVideo":false}'
```

Wait for completion, then fetch `defaultDatasetId` items from the run response.
Keep tokens in environment variables rather than source code.

### API with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/kick-vod-downloader').call({
  startUrls: [{ url: 'https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4' }],
  downloadVideo: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API with Python

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/kick-vod-downloader').call(run_input={
    'startUrls': [{'url': 'https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4'}],
    'downloadVideo': False,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### MCP usage

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/kick-vod-downloader"
```

Use the same JSON configuration in **Claude Desktop**, **Cursor**, or **VS Code**:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/kick-vod-downloader"
    }
  }
}
```

Example prompts:

- “Resolve this authorized public Kick VOD and return its archive metadata without downloading it.”
- “Download this short public Kick VOD at 360p with a 20 MB limit.”
- “Build a metadata manifest for these supplied Kick VOD URLs.”

### Limits and failure behavior

- Only exact public Kick VOD URLs are accepted.
- Live channel URLs and clip URLs are rejected.
- Private, deleted, pruned, subscriber-only, or account-gated VODs are unsupported.
- Encrypted HLS renditions are rejected rather than bypassed.
- The maximum is 25 unique URLs per run.
- The file limit is enforced while streaming; a partial file is removed after failure.
- Very long VODs may exceed file limits or run timeout.
- Kick can change its public API or anti-bot behavior.
- No residential proxy fallback is enabled.
- Downloaded output is MPEG-TS, not transcoded MP4.

A mixed run can contain successful and failed dataset rows.
If every URL fails, the Actor run fails with a non-zero status.

### Troubleshooting

**The URL is rejected immediately**

Confirm it matches `https://kick.com/{channel}/videos/{uuid}`.
Do not use a live channel, category, clip, or shortened URL.

**The VOD is unavailable or pruned**

Open it logged out in a normal browser.
If it is no longer anonymously reachable, the Actor will not bypass that restriction.

**The file exceeds the limit**

Choose 360p or `worst`, raise `maxVideoSizeMb` within 500 MB, or use metadata-only mode.

**The run times out**

Process fewer URLs, select a smaller rendition, or archive shorter VODs.

**A player does not recognize the file**

Use a player that supports MPEG-TS or remux it with FFmpeg in your downstream system.

### Responsible use and legality

Download only media you own or are authorized to archive.
Public reachability does not grant copyright ownership or permission to redistribute a work.
Respect Kick’s terms, creator rights, privacy, publicity rights, takedown requests, and applicable law.
Do not use this Actor to bypass access controls, subscriptions, geographic restrictions, DRM, or removed content.
Keep copied media secure and delete it when your lawful purpose expires.
You are responsible for the URLs you submit and how you use the output.

### Related Automation Lab Actors

- [Reddit Public Video Downloader](https://apify.com/automation-lab/reddit-public-video-downloader) archives authorized Reddit-hosted videos and audio.
- [YouTube Thumbnail Downloader](https://apify.com/automation-lab/youtube-thumbnail-downloader) saves public YouTube thumbnail assets and metadata.
- [Kick Streamer & Channel Analytics](https://apify.com/automation-lab/kick-streamer-channel-analytics) is the better choice for public channel discovery and analytics rather than VOD file retrieval.

### FAQ

**Does it need a Kick login?**

No. Supported VODs must be anonymously reachable and public.

**Does it use a proxy?**

No proxy is enabled for the working public API and CDN route.

**Can it record a live stream?**

No. It processes completed public VOD URLs only.

**Can it discover every VOD for a channel?**

No. Supply the exact VOD URLs you are authorized to process.

**Can it output MP4?**

It stores the selected HLS media as MPEG-TS without transcoding.
You can remux or transcode downstream.

**Are failed URLs charged?**

They do not emit an item event.
The one-time start event still applies to the run.

**Where is the video file?**

Use `storedFileUrl` in the dataset or open the run key-value store.

**How long are files retained?**

Retention depends on your Apify storage and plan settings.
Copy important files to durable storage promptly.

# Actor input Schema

## `startUrls` (type: `array`):

One or more URLs matching https://kick.com/{channel}/videos/{uuid}.

## `maxItems` (type: `integer`):

Maximum unique VOD URLs to process.

## `downloadVideo` (type: `boolean`):

Download the selected HLS rendition into the run key-value store. Disable for metadata-only resolution.

## `quality` (type: `string`):

Preferred maximum rendition. If unavailable, the closest lower rendition is used.

## `maxVideoSizeMb` (type: `integer`):

Stop a download before it exceeds this safety limit.

## `maxRequestRetries` (type: `integer`):

Retries for temporary Kick or CDN failures.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4"
    }
  ],
  "maxItems": 1,
  "downloadVideo": true,
  "quality": "480p",
  "maxVideoSizeMb": 20,
  "maxRequestRetries": 2
}
```

# Actor output Schema

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

Dataset containing one typed retrieval record for every processed Kick VOD URL.

## `files` (type: `string`):

Run key-value store containing successfully downloaded MPEG transport-stream files.

# 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 = {
    "startUrls": [
        {
            "url": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4"
        }
    ],
    "maxItems": 1,
    "downloadVideo": true,
    "quality": "480p",
    "maxVideoSizeMb": 20,
    "maxRequestRetries": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/kick-vod-downloader").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 = {
    "startUrls": [{ "url": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4" }],
    "maxItems": 1,
    "downloadVideo": True,
    "quality": "480p",
    "maxVideoSizeMb": 20,
    "maxRequestRetries": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/kick-vod-downloader").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 '{
  "startUrls": [
    {
      "url": "https://kick.com/xqc/videos/78a39add-ac70-4c16-8fae-9eca007d1cc4"
    }
  ],
  "maxItems": 1,
  "downloadVideo": true,
  "quality": "480p",
  "maxVideoSizeMb": 20,
  "maxRequestRetries": 2
}' |
apify call automation-lab/kick-vod-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/kick-vod-downloader"
        }
    }
}

```

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/1XTI1zMMQcFtIqVDr/builds/ENsC4It1HZsH7d3vB/openapi.json
