# Kick Scraper: Streamers, Live Streams, VODs & Clips (`scrapewise/kick-scraper`) Actor

Scrape Kick.com streamer profiles, live streams, VODs and clips: followers, verified badge, live viewers, category, language filters and social links. Daily only-new mode. No login needed.

- **URL**: https://apify.com/scrapewise/kick-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Social media, Videos
- **Features:** Limited permissions
- **Stats:** 6 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.30 / 1,000 kick item delivereds

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

## Kick.com Scraper - Streamers, Live Streams, VODs & Clips

Kick.com Scraper turns Kick's public data into flat rows: streamer profiles with followers, verification, bio and social links, the top live streams right now by category and language, past broadcasts (VODs), clips, and categories with live viewers. It needs no login. It is used by influencer agencies vetting creators, sponsors looking for the most-watched streams in a category, and streaming analytics products tracking viewers over time.

### At a glance

| Apify plan | Per row | Per 1,000 rows |
|---|---|---|
| Free | US$ 0.0030 | US$ 3.00 |
| Bronze | US$ 0.0027 | US$ 2.70 |
| Silver | US$ 0.0025 | US$ 2.50 |
| Gold and above | US$ 0.0023 | US$ 2.30 |

- One charge per row, whatever the mode: a channel, a live stream, a VOD, a clip or a category. 100 creator profiles cost US$ 0.30.
- No monthly fee and no start fee. Channels that do not exist, empty filters and blocked requests are free rows with an `errorCode`.

### Quick start

The default input returns two channel profiles:

```json
{ "mode": "channels", "channelNames": ["westcol", "https://kick.com/adinross", "@amouranth"] }
```

A real row from 2026-10-21, trimmed:

```json
{
  "type": "channel",
  "channelName": "westcol",
  "channelUrl": "https://kick.com/westcol",
  "channelId": 669746,
  "displayName": "Westcol",
  "bio": null,
  "followersCount": 4425252,
  "verified": true,
  "hasSubscriptions": true,
  "isLive": false,
  "recentCategories": ["IRL", "Minecraft", "Just Chatting", "Among Us"],
  "instagram": "https://www.instagram.com/westcol",
  "twitter": "https://x.com/WestCOL",
  "youtube": "https://www.youtube.com/channel/UCEg_iK8FKwZfpRMn4-AnnnQ",
  "tiktok": "https://www.tiktok.com/@westcol",
  "scrapedAt": "2026-10-21T20:19:00.449Z"
}
```

When the channel is live, `isLive` is `true` and `currentViewers`, `currentStreamTitle`, `currentCategory`, `currentStreamLanguage`, `currentStreamTags` and `startedAt` are filled.

### Modes

| Mode | Input | One row per | Typical use |
|---|---|---|---|
| `channels` | channel names or URLs | channel | creator vetting, follower tracking, live check |
| `liveStreams` | optional categories, languages, min viewers, tags | live stream | top streams now, sponsor discovery |
| `videos` | channel names or URLs | past broadcast (VOD) | views, peak viewers and duration of recent streams |
| `clips` | channels, categories, or nothing for trending | clip | viral moments, highlight research |
| `categories` | nothing (top N) or category slugs | category | category viewers leaderboard |
| `search` | keywords | channel | find streamers by name |

Every row has a `type` (`channel`, `livestream`, `video`, `clip`, `category`) and `scrapedAt`, so modes can share one pipeline. Top 50 live streams in Just Chatting in Spanish with at least 50 viewers:

```json
{ "mode": "liveStreams", "categories": ["just-chatting"], "languages": ["es"], "minViewers": 50, "maxResults": 50 }
```

The 100 most viewed clips of a channel: `{ "mode": "clips", "channelNames": ["westcol"], "clipSort": "view", "clipPeriod": "all", "maxResults": 100 }`.

### Switching from another Kick actor? Your existing input works

| Field you already send | Here |
|---|---|
| `mode`: `channel_details` / `live_streams`, `top_channels`, `livestreams` / `subcategories` | `channels` / `liveStreams` / `categories` |
| `mode`: `channel_videos` with `videoType` `videos` or `clips` | `videos` or `clips` |
| `channelSlugs`, `channelUrls`, `startUrls`, `watchlist` | Same as `channelNames` |
| `category`, `categorySlugs` | Same as `categories` |
| `livestreamLanguages`, `livestreamTags`, `searchKeywords` | Same as `languages`, `tags`, `searchQueries` |
| `maxItems` | Same as `maxResults` |

Output names follow the common convention (`channelName`, `displayName`, `followersCount`, `isLive`, `currentViewers`, `currentCategory`, `currentStreamTitle`, `viewers`, `thumbnailUrl`), so most mappings keep working.

### Output examples

Real rows from 2026-09-15 (live stream and category) and 2026-10-21 (video).

```json
{
  "type": "livestream",
  "rank": 2,
  "channelName": "alabinha5",
  "title": "JOGANDO OUTROS JOGOS e REACTS | 3 DIAS PRO NOVO FIFA",
  "viewers": 2534,
  "category": "Just Chatting",
  "categorySlug": "just-chatting",
  "language": "pt",
  "isMature": false,
  "startedAt": "2026-09-15T12:19:23Z",
  "isLive": true
}
```

```json
{
  "type": "video",
  "videoId": "5657c461-6ef3-49b8-a8bf-54ccbf5acbfb",
  "channelName": "westcol",
  "title": "FINAL DEL DEDSAFIO BROOOOOOTHEEEEEEEER",
  "views": 5001476,
  "peakViewers": 1233572,
  "duration": 19454,
  "durationFormatted": "5:24:14",
  "category": "Minecraft",
  "startedAt": "2026-10-17T22:21:42Z",
  "videoUrl": "https://stream.kick.com/.../media/hls/master.m3u8"
}
```

```json
{
  "type": "category",
  "rank": 1,
  "name": "Grand Theft Auto V (GTA)",
  "slug": "grand-theft-auto-v",
  "parentCategory": "Games",
  "viewers": 269060,
  "tags": ["Shooter", "Action", "Open World"]
}
```

Clip rows carry `clipId`, `title`, `url`, `views`, `likes`, `duration`, `category`, `createdAt`, `thumbnailUrl` and an HLS `videoUrl`.

#### Main fields

| Field | Types | Description |
|---|---|---|
| `channelName`, `displayName`, `channelUrl`, `channelId` | channel, livestream, video, clip | Slug as in kick.com/<slug>, display name, link, numeric id |
| `followersCount` | channel, category | Followers (category only with slug input) |
| `verified`, `isAffiliate`, `isBanned`, `hasSubscriptions`, `vodEnabled` | channel | Channel flags |
| `bio`, `avatarUrl`, `bannerUrl`, `recentCategories` | channel | Public profile |
| `instagram`, `twitter`, `youtube`, `tiktok`, `facebook`, `discord`, `socialLinks` | channel | Social links set by the streamer |
| `isLive`, `currentViewers`, `currentStreamTitle`, `currentCategory`, `startedAt` | channel | Current live stream, if any |
| `rank`, `viewers`, `title`, `language`, `tags`, `isMature` | livestream | Live stream now, ranked by viewers |
| `views`, `peakViewers`, `duration`, `durationFormatted`, `videoUrl` | video | VOD stats and HLS playlist |
| `category`, `categorySlug`, `parentCategory` | livestream, video, clip | Category of the content |
| `input`, `error`, `errorCode` | all | Input line that produced the row; error info (not charged) |

#### Error codes (never charged)

`CHANNEL_NOT_FOUND`, `INVALID_CHANNEL`, `CATEGORY_NOT_FOUND`, `INVALID_CATEGORY`, `NO_RESULTS`, `CHANNEL_UNAVAILABLE`, `BLOCKED`. Each comes as a row with `error` and `errorCode`. The run fails only when Kick blocked every retry and nothing was delivered, so one bad name in a list of 500 does not ruin the run.

### Only new VODs, clips and streams

Turn on `onlyNew` and save the input as a Task with a daily Schedule. What each channel, category or live filter already delivered is kept in the key-value store `kick-scraper-only-new` in your account, and each run delivers, and charges, only what is new:

- `videos`: broadcasts published since the last run (the first run marks the channel's VOD list as seen).
- `clips`: clips created since the last run, read newest first.
- `liveStreams`: each live stream once, even if it is still live on the next run.

A day with nothing new costs nothing for results. `onlyNew` does nothing in `channels`, `search` and `categories`, which are fresh snapshots. Delete the store to start over.

### Limitations

- **VODs:** Kick shows the 24 most recent past broadcasts per channel.
- **Live streams** are a snapshot of the moment of the run; schedule the Actor every 15 or 60 minutes for a viewer history. Category and language filters are applied by Kick; `minViewers` and `tags` on top.
- **Search** returns up to 20 channels per keyword, Kick's own limit.
- **Gambling, casino and betting categories are not collected** in any mode (24 categories under Kick's `gambling` parent). Names that only look like gambling, such as chat-roulette, are collected.
- **Chat messages and viewer data are not collected**, nor the username of who created a clip.

### FAQ

**How fast is it?**
600 top live streams took 31 seconds, 500 clips of a channel 44 seconds, two channel profiles 3 seconds.

**Can I monitor if a streamer is live?**
Yes. Run `channels` on a schedule and read `isLive`, `currentViewers`, `currentStreamTitle` and `currentCategory`.

**Why did I get fewer rows than `maxResults`?**
The channel has fewer VODs or clips, fewer streams match the filters right now, or Kick's limits apply. You pay only for rows delivered.

**Can I call it from the API, n8n, Make, Zapier or an AI agent?**
Yes: `scrapewise/kick-scraper` through the Apify API, the Apify app in those tools, or the MCP server at `https://mcp.apify.com/?actors=scrapewise/kick-scraper`.

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapewise~kick-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" -d '{"mode": "liveStreams", "languages": ["en"], "maxResults": 100}'
```

**Is scraping Kick legal?**
The Actor collects only public data anyone can see on kick.com without an account. Follow Kick's terms and the data protection laws of your country.

### Changelog

- **2026-10-04:** `onlyNew` for daily schedules in `videos`, `clips` and `liveStreams`.
- **2026-09-15 (0.1.7):** gambling, casino and betting categories blocked by parent category, word and slug.
- **2026-09-15:** first version with six modes and input names of other Kick scrapers accepted.

Something broke or you need a field? Open an issue on the Issues tab; issues are answered the same day.

# Actor input Schema

## `mode` (type: `string`):

What each row is. Channel profiles: one row per channel with followers, verification, socials and live status. Live streams now: the top streams by viewers, optionally by category, language, viewers or tags. Past broadcasts: the VODs of channels. Clips: of channels, of categories, or trending when both are empty. Categories: ranked by live viewers. Search: channels matching keywords. Every row costs the same (US$ 3.00 per 1,000 on the Free plan). Mode names of other Kick scrapers (channel_details, live_streams, top_channels, channel_videos with videoType, livestreams, subcategories) also work.

## `channelNames` (type: `array`):

Used by Channel profiles, Past broadcasts and Clips. One per line, as a name (westcol), @westcol, kick.com/westcol or a full https://kick.com/westcol URL. Each channel gives one profile row, or up to 'Max results' VODs or clips. A name that does not exist returns a free CHANNEL_NOT_FOUND row. If empty, profiles and VODs use westcol and adinross, and clips returns trending clips. Also accepts 'channelSlugs', 'channelUrls', 'startUrls' and 'watchlist'.

## `searchQueries` (type: `array`):

Used by Search. Keywords, one per line, for example valorant or poker. Each keyword returns up to 20 matching channels (Kick's own limit), each with the full channel profile. A keyword with no match returns a free NO_RESULTS row. Also accepts 'searchKeywords'.

## `categories` (type: `array`):

Category slugs as in the Kick URL (just-chatting, grand-theft-auto-v, counter-strike-2) or kick.com/category/... URLs, one per line. In Live streams and Clips it filters to these categories; in Categories mode it returns these categories with followers and live viewers instead of the top list. Leave empty for all categories. Unknown slugs return a free CATEGORY_NOT_FOUND row. Also accepts 'category' and 'categorySlugs'.

## `languages` (type: `array`):

Live streams only. Two-letter language codes of the streams, one per line, for example en, es, tr or de. Kick applies the filter, so the top list is ranked within these languages. Empty means all languages. Also accepts 'livestreamLanguages'.

## `minViewers` (type: `integer`):

Live streams only. Skip streams with fewer current viewers than this, for example 50 to leave out small streams. Default 0 keeps every stream. Skipped streams are not charged.

## `tags` (type: `array`):

Live streams only. Keep only streams with at least one of these tags, case-insensitive, one per line, for example English or Drops. Empty keeps every stream. Also accepts 'livestreamTags'.

## `sortBy` (type: `string`):

Live streams only. The top streams are always selected by current viewers; Most recently started first only re-orders that selection by 'startedAt'. Default: most viewers first, with 'rank' 1, 2, 3...

## `clipSort` (type: `string`):

Clips only. Most viewed (default) or Newest first. With 'Only new items' on, clips are always read newest first so the run can stop at the first clip already delivered.

## `clipPeriod` (type: `string`):

Clips only. Time window Kick applies to the clip list: last 24 hours, last 7 days, last 30 days or all time (default). Combine Last 7 days with Most viewed for the week's top clips.

## `maxResults` (type: `integer`):

Past broadcasts and Clips: maximum per channel or category (Kick serves only the 24 most recent VODs per channel). Live streams, Categories and Search: maximum for the run or per keyword. Ignored by Channel profiles, which return one row per channel. Default 30. You pay per row, so this caps the cost: 30 rows cost US$ 0.09. Also accepts 'maxItems'.

## `onlyNew` (type: `boolean`):

For daily schedules in Past broadcasts, Clips and Live streams. Remembers what each channel, category or live filter already delivered (in the key-value store 'kick-scraper-only-new' in your account) and skips it on later runs: skipped items are not charged and do not count toward 'Max results'. Clips switch to newest first. The first run on a channel marks its whole VOD list as seen, so later runs bring only new broadcasts. Not used in Channel profiles, Search and Categories. Delete the store to start over. Default off.

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

The default Apify Proxy works for Kick; a request blocked on every retry becomes a free BLOCKED row. Change it only if you have a reason to use another proxy group.

## Actor input object example

```json
{
  "mode": "channels",
  "channelNames": [
    "westcol",
    "adinross"
  ],
  "minViewers": 0,
  "sortBy": "viewers",
  "clipSort": "view",
  "clipPeriod": "all",
  "maxResults": 30,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (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 = {
    "mode": "channels",
    "channelNames": [
        "westcol",
        "adinross"
    ],
    "maxResults": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/kick-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 = {
    "mode": "channels",
    "channelNames": [
        "westcol",
        "adinross",
    ],
    "maxResults": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/kick-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 '{
  "mode": "channels",
  "channelNames": [
    "westcol",
    "adinross"
  ],
  "maxResults": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/kick-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/kick-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/5T0qiHkvdShqIwJsY/builds/aSjjJ7dJ0nffaStEU/openapi.json
