# Kick Clips (`maximedupre/kick-clips`) Actor

Find public Kick clips by scope and rank them by views per hour or total views. Enrich one Kick clip URL with metadata, media details, and an optional transcript. Get structured clip data with source links when Kick provides them.

- **URL**: https://apify.com/maximedupre/kick-clips.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Videos, Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 discovered clips

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

### 🎮 Find Public Kick Clips for Your Next Review

Stream researchers, clip editors, and content teams can find public Kick clips by scope, time window, and ranking, or enrich one known Kick clip URL. The dataset returns stable clip IDs, source pages, creator and category details, views, likes, clip age, rank, duration, thumbnails, and a source video link when Kick provides one. For a known clip, you can request media details and a time-aligned transcript, then add a translation. This gives you structured data to review clips and pass source links into your own workflow.

- Search public Kick clips by a chosen scope and ranking with [**Kick Clips Search**](https://apify.com/maximedupre/kick-clips/examples/kick-clips-search).
- Enrich one public Kick clip URL with normalized details using [**Kick Clip Metadata**](https://apify.com/maximedupre/kick-clips/examples/kick-clip-metadata).
- Review one public clip and its returned fields with [**Kick Clips Viewer**](https://apify.com/maximedupre/kick-clips/examples/kick-clips-viewer).
- Use [**Kick Clip Downloader**](https://apify.com/maximedupre/kick-clips/examples/kick-clip-downloader) to get a source video link for a public Kick clip when Kick provides one.
- Request a detected-language transcript with ordered time-aligned segments using [**Kick Clip Transcript**](https://apify.com/maximedupre/kick-clips/examples/kick-clip-transcript).

#### 📊 Kick Clip Data for Research and Workflows

Each dataset row is one public Kick clip. Discovery rows include a rank in the selected scope. Known clip lookups have a null rank and can include media details, a transcript, and an optional translation. Values that Kick does not provide stay null.

#### ▶️ Run Discovery or Enrich One Kick Clip

Choose **Discover clips** to search a global, category, or channel scope. Choose **Enrich a clip URL** when you already have one public Kick clip page. Set a time window, ranking basis, filters, and result limit for discovery. For a known clip, you can request a transcript and choose a translation language.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `findClipsBy` | string | Choose `discover` to find many clips, or `enrich` to read one known Kick clip URL. |
| `discoveryScope` | string | For discovery, choose `global`, `category`, or `channel`. The matching scope field is used. |
| `category` | string | The Kick category name or slug for `category` discovery. It is ignored for other scopes. |
| `channel` | string | The Kick channel name or slug for `channel` discovery. It is ignored for other scopes. |
| `recencyWindow` | string | Limits discovery to `lastHour`, `last24Hours`, `last7Days`, `last30Days`, or `allTime`. |
| `rankBy` | string | Uses `viewsPerHour` for recently rising clips or `totalViews` for the most watched clips. |
| `maxItems` | integer | Stops discovery after this many ranked clips. Leave it empty to return all matching clips until the source is exhausted. |
| `excludeMature` | boolean | When `true`, leaves out clips flagged as mature. |
| `maxDurationSeconds` | integer | Keeps clips at or below this duration in seconds. Leave it empty to allow any duration. |
| `minimumViews` | integer | Keeps clips with at least this many views. Leave it empty to skip this filter. |
| `minimumViewsPerHour` | number | Keeps clips with at least this views-per-hour rate. Leave it empty to skip this filter. |
| `onlyNewClips` | boolean | With recurring runs, returns clips this Actor has not delivered in earlier runs. The first run can return all matching clips. |
| `clipUrl` | string | The public Kick clip URL used when `findClipsBy` is `enrich`. It must use the `kick.com` domain. |
| `includeTranscript` | boolean | For a known clip, requests a detected-language transcript with ordered, time-aligned segments. |
| `translationLanguage` | string | The target language for a requested transcript translation. Leave it empty to keep only the detected language. |

**Work limit**

`maxItems` is the Actor Work Limit for discovery. Leave it empty to return all available matching clips until the source is exhausted. There is no fixed maximum in the input schema.

**Example input**

This is the public input from a successful discovery run.

```json
{
  "findClipsBy": "discover",
  "discoveryScope": "global",
  "recencyWindow": "last7Days",
  "rankBy": "viewsPerHour",
  "maxItems": 25,
  "excludeMature": false,
  "onlyNewClips": false,
  "includeTranscript": false
}
```

#### 🧾 Output

The output schema provides a dataset link. Open that link to view the rows described below. The four tables cover the discovery row, known-clip metadata, transcript, and translation shapes.

**Run output**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetUrl` | string | Link to the dataset that contains the clip rows. |

**Discovery row**

Discovery rows have a rank for their position in the selected scope. The table is complete for the public clip row shape.

| Field | Type | What it does |
| --- | --- | --- |
| `clipId` | string | Stable ID of the Kick clip. |
| `clipUrl` | string | Public Kick page for the clip. |
| `title` | string or null | Title published for the clip. |
| `creator` | object or null | Creator details published with the clip. |
| `creator.channelId` | string or null | Stable ID of the creator channel. |
| `creator.username` | string or null | Creator username on Kick. |
| `category` | string or null | Kick category published for the clip. |
| `publishedAt` | string or null | Time when Kick published the clip. |
| `views` | integer or null | Number of views reported for the clip. |
| `likes` | integer or null | Number of likes reported for the clip. |
| `clipAgeSeconds` | number or null | Clip age at the time of the result, in seconds. |
| `viewsPerHour` | number or null | View rate used for velocity ranking, in views per hour. |
| `rank` | integer or null | Position of the clip in discovery results. |
| `isMature` | boolean or null | Whether Kick flags the clip as mature. |
| `durationSeconds` | number or null | Clip duration in seconds. |
| `videoUrl` | string or null | Dependable source-hosted video URL when Kick provides one. |
| `thumbnailUrl` | string or null | Source thumbnail URL when Kick provides one. |
| `media` | object or null | Technical media details when Kick provides them. |
| `media.fileType` | string or null | Source file type. |
| `media.fileSizeBytes` | integer or null | Source file size in bytes. |
| `media.width` | integer or null | Video width in pixels. |
| `media.height` | integer or null | Video height in pixels. |
| `media.frameRate` | number or null | Video frame rate in frames per second. |
| `media.videoCodec` | string or null | Video codec used by the source file. |
| `media.audioCodec` | string or null | Audio codec used by the source file. |
| `media.bitrateKbps` | number or null | Source file bitrate in kilobits per second. |
| `media.dynamicRange` | string or null | Source video dynamic range when provided. |
| `transcript` | object or null | Requested transcript and optional translation for a known clip. |
| `transcript.detectedLanguage` | string or null | Language detected for the original transcript. |
| `transcript.segments` | array of objects | Ordered time-aligned segments in the original language. |
| `transcript.segments[].startSeconds` | number | Segment start time in seconds. |
| `transcript.segments[].endSeconds` | number | Segment end time in seconds. |
| `transcript.segments[].text` | string | Words spoken in the segment. |
| `transcript.translation` | object or null | Requested translation with the same segment timing. |
| `transcript.translation.language` | string | Target translation language. |
| `transcript.translation.segments` | array of objects | Ordered translated segments aligned to the original transcript. |
| `transcript.translation.segments[].startSeconds` | number | Translated segment start time in seconds. |
| `transcript.translation.segments[].endSeconds` | number | Translated segment end time in seconds. |
| `transcript.translation.segments[].text` | string | Translated words for the segment. |

**Genuine discovery row**

This row came from a successful discovery run.

```json
{
  "clipId": "clip_01M2N8ADTSMHTD7JQ8QH49W65A",
  "clipUrl": "https://kick.com/odablock/clips/clip_01M2N8ADTSMHTD7JQ8QH49W65A",
  "title": "ar 3",
  "creator": {
    "channelId": "2401072",
    "username": "MaxPauly"
  },
  "category": "Just Chatting",
  "publishedAt": "2026-09-16T14:01:24.105Z",
  "views": 1,
  "likes": 0,
  "clipAgeSeconds": 32.853,
  "viewsPerHour": 109.57903387818463,
  "rank": 1,
  "isMature": false,
  "durationSeconds": 180,
  "videoUrl": "https://clips.kick.com/clips/ca/clip_01M2N8ADTSMHTD7JQ8QH49W65A/playlist.m3u8",
  "thumbnailUrl": "https://clips.kick.com/clips/ca/clip_01M2N8ADTSMHTD7JQ8QH49W65A/thumbnail.webp",
  "media": null,
  "transcript": null
}
```

**Known clip metadata row**

Known clip metadata rows have `rank: null`. The table is complete for the metadata shape, including media details when Kick provides them.

| Field | Type | What it does |
| --- | --- | --- |
| `clipId` | string | Stable ID of the Kick clip. |
| `clipUrl` | string | Public Kick page for the clip. |
| `title` | string or null | Title published for the clip. |
| `creator` | object or null | Creator details published with the clip. |
| `creator.channelId` | string or null | Stable ID of the creator channel. |
| `creator.username` | string or null | Creator username on Kick. |
| `category` | string or null | Kick category published for the clip. |
| `publishedAt` | string or null | Time when Kick published the clip. |
| `views` | integer or null | Number of views reported for the clip. |
| `likes` | integer or null | Number of likes reported for the clip. |
| `clipAgeSeconds` | number or null | Clip age at the time of the result, in seconds. |
| `viewsPerHour` | number or null | View rate shown for the clip, in views per hour. |
| `rank` | integer or null | Position in discovery results. It is null for this known clip lookup. |
| `isMature` | boolean or null | Whether Kick flags the clip as mature. |
| `durationSeconds` | number or null | Clip duration in seconds. |
| `videoUrl` | string or null | Dependable source-hosted video URL when Kick provides one. |
| `thumbnailUrl` | string or null | Source thumbnail URL when Kick provides one. |
| `media` | object or null | Technical media details when Kick provides them. |
| `media.fileType` | string or null | Source file type. |
| `media.fileSizeBytes` | integer or null | Source file size in bytes. |
| `media.width` | integer or null | Video width in pixels. |
| `media.height` | integer or null | Video height in pixels. |
| `media.frameRate` | number or null | Video frame rate in frames per second. |
| `media.videoCodec` | string or null | Video codec used by the source file. |
| `media.audioCodec` | string or null | Audio codec used by the source file. |
| `media.bitrateKbps` | number or null | Source file bitrate in kilobits per second. |
| `media.dynamicRange` | string or null | Source video dynamic range when provided. |
| `transcript` | object or null | Requested transcript and optional translation for a known clip. |
| `transcript.detectedLanguage` | string or null | Language detected for the original transcript. |
| `transcript.segments` | array of objects | Ordered time-aligned segments in the original language. |
| `transcript.segments[].startSeconds` | number | Segment start time in seconds. |
| `transcript.segments[].endSeconds` | number | Segment end time in seconds. |
| `transcript.segments[].text` | string | Words spoken in the segment. |
| `transcript.translation` | object or null | Requested translation with the same segment timing. |
| `transcript.translation.language` | string | Target translation language. |
| `transcript.translation.segments` | array of objects | Ordered translated segments aligned to the original transcript. |
| `transcript.translation.segments[].startSeconds` | number | Translated segment start time in seconds. |
| `transcript.translation.segments[].endSeconds` | number | Translated segment end time in seconds. |
| `transcript.translation.segments[].text` | string | Translated words for the segment. |

**Genuine known clip metadata row**

This row came from a successful known-clip run.

```json
{
  "clipId": "clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "clipUrl": "https://kick.com/jugandoconelgordopou/clips/clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "title": "jajajaja siempre lo mismo 😅",
  "creator": {
    "channelId": "101598468",
    "username": "JugandoconelgordoPou"
  },
  "category": "Sunset Riders",
  "publishedAt": "2026-09-16T10:01:19.487Z",
  "views": 1,
  "likes": 0,
  "clipAgeSeconds": 14494.803,
  "viewsPerHour": 0.24836487946748914,
  "rank": null,
  "isMature": false,
  "durationSeconds": 30,
  "videoUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/playlist.m3u8",
  "thumbnailUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/thumbnail.webp",
  "media": {
    "fileType": "video/mp4",
    "fileSizeBytes": 8520939,
    "width": 1280,
    "height": 720,
    "frameRate": 30,
    "videoCodec": "h264",
    "audioCodec": "aac",
    "bitrateKbps": 2046.826,
    "dynamicRange": "SDR"
  },
  "transcript": null
}
```

**Known clip transcript row**

Transcript rows have `rank: null` and a `transcript` object. The table is complete for the transcript shape. A translation is optional.

| Field | Type | What it does |
| --- | --- | --- |
| `clipId` | string | Stable ID of the Kick clip. |
| `clipUrl` | string | Public Kick page for the clip. |
| `title` | string or null | Title published for the clip. |
| `creator` | object or null | Creator details published with the clip. |
| `creator.channelId` | string or null | Stable ID of the creator channel. |
| `creator.username` | string or null | Creator username on Kick. |
| `category` | string or null | Kick category published for the clip. |
| `publishedAt` | string or null | Time when Kick published the clip. |
| `views` | integer or null | Number of views reported for the clip. |
| `likes` | integer or null | Number of likes reported for the clip. |
| `clipAgeSeconds` | number or null | Clip age at the time of the result, in seconds. |
| `viewsPerHour` | number or null | View rate shown for the clip, in views per hour. |
| `rank` | integer or null | Position in discovery results. It is null for this known clip lookup. |
| `isMature` | boolean or null | Whether Kick flags the clip as mature. |
| `durationSeconds` | number or null | Clip duration in seconds. |
| `videoUrl` | string or null | Dependable source-hosted video URL when Kick provides one. |
| `thumbnailUrl` | string or null | Source thumbnail URL when Kick provides one. |
| `media` | object or null | Technical media details when Kick provides them. |
| `media.fileType` | string or null | Source file type. |
| `media.fileSizeBytes` | integer or null | Source file size in bytes. |
| `media.width` | integer or null | Video width in pixels. |
| `media.height` | integer or null | Video height in pixels. |
| `media.frameRate` | number or null | Video frame rate in frames per second. |
| `media.videoCodec` | string or null | Video codec used by the source file. |
| `media.audioCodec` | string or null | Audio codec used by the source file. |
| `media.bitrateKbps` | number or null | Source file bitrate in kilobits per second. |
| `media.dynamicRange` | string or null | Source video dynamic range when provided. |
| `transcript` | object or null | Requested transcript and optional translation for a known clip. |
| `transcript.detectedLanguage` | string or null | Language detected for the original transcript. |
| `transcript.segments` | array of objects | Ordered time-aligned segments in the original language. |
| `transcript.segments[].startSeconds` | number | Segment start time in seconds. |
| `transcript.segments[].endSeconds` | number | Segment end time in seconds. |
| `transcript.segments[].text` | string | Words spoken in the segment. |
| `transcript.translation` | object or null | Requested translation with the same segment timing. |
| `transcript.translation.language` | string | Target translation language. |
| `transcript.translation.segments` | array of objects | Ordered translated segments aligned to the original transcript. |
| `transcript.translation.segments[].startSeconds` | number | Translated segment start time in seconds. |
| `transcript.translation.segments[].endSeconds` | number | Translated segment end time in seconds. |
| `transcript.translation.segments[].text` | string | Translated words for the segment. |

**Genuine known clip transcript row**

This row came from a successful run with a transcript request.

```json
{
  "clipId": "clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "clipUrl": "https://kick.com/jugandoconelgordopou/clips/clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "title": "jajajaja siempre lo mismo 😅",
  "creator": {
    "channelId": "101598468",
    "username": "JugandoconelgordoPou"
  },
  "category": "Sunset Riders",
  "publishedAt": "2026-09-16T10:01:19.487Z",
  "views": 1,
  "likes": 0,
  "clipAgeSeconds": 14494.752,
  "viewsPerHour": 0.24836575334300304,
  "rank": null,
  "isMature": false,
  "durationSeconds": 30,
  "videoUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/playlist.m3u8",
  "thumbnailUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/thumbnail.webp",
  "media": {
    "fileType": "video/mp4",
    "fileSizeBytes": 8520939,
    "width": 1280,
    "height": 720,
    "frameRate": 30,
    "videoCodec": "h264",
    "audioCodec": "aac",
    "bitrateKbps": 2046.826,
    "dynamicRange": "SDR"
  },
  "transcript": {
    "detectedLanguage": "spanish",
    "segments": [
      {
        "startSeconds": 22,
        "endSeconds": 33.304,
        "text": "[Risas]"
      }
    ]
  }
}
```

**Known clip translation row**

Translation rows have `rank: null`, a transcript, and a nested translation. The table is complete for this shape.

| Field | Type | What it does |
| --- | --- | --- |
| `clipId` | string | Stable ID of the Kick clip. |
| `clipUrl` | string | Public Kick page for the clip. |
| `title` | string or null | Title published for the clip. |
| `creator` | object or null | Creator details published with the clip. |
| `creator.channelId` | string or null | Stable ID of the creator channel. |
| `creator.username` | string or null | Creator username on Kick. |
| `category` | string or null | Kick category published for the clip. |
| `publishedAt` | string or null | Time when Kick published the clip. |
| `views` | integer or null | Number of views reported for the clip. |
| `likes` | integer or null | Number of likes reported for the clip. |
| `clipAgeSeconds` | number or null | Clip age at the time of the result, in seconds. |
| `viewsPerHour` | number or null | View rate shown for the clip, in views per hour. |
| `rank` | integer or null | Position in discovery results. It is null for this known clip lookup. |
| `isMature` | boolean or null | Whether Kick flags the clip as mature. |
| `durationSeconds` | number or null | Clip duration in seconds. |
| `videoUrl` | string or null | Dependable source-hosted video URL when Kick provides one. |
| `thumbnailUrl` | string or null | Source thumbnail URL when Kick provides one. |
| `media` | object or null | Technical media details when Kick provides them. |
| `media.fileType` | string or null | Source file type. |
| `media.fileSizeBytes` | integer or null | Source file size in bytes. |
| `media.width` | integer or null | Video width in pixels. |
| `media.height` | integer or null | Video height in pixels. |
| `media.frameRate` | number or null | Video frame rate in frames per second. |
| `media.videoCodec` | string or null | Video codec used by the source file. |
| `media.audioCodec` | string or null | Audio codec used by the source file. |
| `media.bitrateKbps` | number or null | Source file bitrate in kilobits per second. |
| `media.dynamicRange` | string or null | Source video dynamic range when provided. |
| `transcript` | object or null | Requested transcript and optional translation for a known clip. |
| `transcript.detectedLanguage` | string or null | Language detected for the original transcript. |
| `transcript.segments` | array of objects | Ordered time-aligned segments in the original language. |
| `transcript.segments[].startSeconds` | number | Segment start time in seconds. |
| `transcript.segments[].endSeconds` | number | Segment end time in seconds. |
| `transcript.segments[].text` | string | Words spoken in the segment. |
| `transcript.translation` | object or null | Requested translation with the same segment timing. |
| `transcript.translation.language` | string | Target translation language. |
| `transcript.translation.segments` | array of objects | Ordered translated segments aligned to the original transcript. |
| `transcript.translation.segments[].startSeconds` | number | Translated segment start time in seconds. |
| `transcript.translation.segments[].endSeconds` | number | Translated segment end time in seconds. |
| `transcript.translation.segments[].text` | string | Translated words for the segment. |

**Genuine known clip translation row**

This row came from a successful run with a transcript and translation request.

```json
{
  "clipId": "clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "clipUrl": "https://kick.com/jugandoconelgordopou/clips/clip_01M2MTJ9QHMFZYNHS8TAMFF03D",
  "title": "jajajaja siempre lo mismo 😅",
  "creator": {
    "channelId": "101598468",
    "username": "JugandoconelgordoPou"
  },
  "category": "Sunset Riders",
  "publishedAt": "2026-09-16T10:01:19.487Z",
  "views": 1,
  "likes": 0,
  "clipAgeSeconds": 14495.042,
  "viewsPerHour": 0.24836078432887604,
  "rank": null,
  "isMature": false,
  "durationSeconds": 30,
  "videoUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/playlist.m3u8",
  "thumbnailUrl": "https://clips.kick.com/clips/15/clip_01M2MTJ9QHMFZYNHS8TAMFF03D/thumbnail.webp",
  "media": {
    "fileType": "video/mp4",
    "fileSizeBytes": 8520939,
    "width": 1280,
    "height": 720,
    "frameRate": 30,
    "videoCodec": "h264",
    "audioCodec": "aac",
    "bitrateKbps": 2046.826,
    "dynamicRange": "SDR"
  },
  "transcript": {
    "detectedLanguage": "spanish",
    "segments": [
      {
        "startSeconds": 22,
        "endSeconds": 33.304,
        "text": "[Risas]"
      }
    ],
    "translation": {
      "language": "Spanish",
      "segments": [
        {
          "startSeconds": 22,
          "endSeconds": 33.304,
          "text": "[Risas]"
        }
      ]
    }
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. Charges are tied to saved output events. A discovery charge covers each saved discovered clip. A metadata charge covers one saved known-clip enrichment row. Transcript and translation charges cover the requested transcript or translation when produced.

| Event | What it covers |
| --- | --- |
| Discovered clip | One public Kick clip found during discovery, with metadata and a source video URL when available. |
| Clip metadata | Metadata for one supplied public Kick clip, with unavailable source values kept as null. |
| Clip transcript | One detected-language transcript with ordered time-aligned segments for a public Kick clip. |
| Clip translation | One translation of a clip transcript into the requested language with the original segment alignment. |

#### 🔌 Integrations

Use the Apify API to start runs and read the dataset. You can also schedule runs, use webhooks, or export the dataset from Apify.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens when a clip has no video link?

The row still includes the public clip page and the other values Kick provides. `videoUrl` is null when Kick does not expose a dependable source-hosted video URL.

##### Can I look up one known clip instead of discovering clips?

Yes. Set `findClipsBy` to `enrich` and provide one public Kick clip URL. The row has `rank: null` because it was not found in a discovery list.

##### How does views per hour ranking work?

Choose `viewsPerHour` in `rankBy` to put the highest reported view rate first. The returned `viewsPerHour` value shows the rate used for the rank.

##### What happens when I leave Maximum clips empty?

The Actor returns all available matching clips until the source is exhausted. The input schema has no fixed upper limit for this field.

##### Can I request a transcript and translation?

Yes. For a known clip, turn on `includeTranscript`. You can also set `translationLanguage` to keep the original transcript and add aligned translated segments when available.

##### Does this Actor download or store the clip file?

No. It returns the public Kick page and a source-hosted video URL when Kick provides one. It does not store a copy or transform the video.

##### Can it search arbitrary Kick text?

No. Discovery uses the supported global, category, and channel scopes. It is not a web-wide or arbitrary text search.

##### How are unavailable fields handled?

Unavailable source values are returned as `null` instead of being guessed.

##### How are duplicate clips handled?

The first eligible occurrence of a source clip is saved. Later matches for the same clip are ignored, so one row describes that first saved match.

##### Do I need a Kick login or developer API key?

No. The Actor works with public Kick clips and does not require a Kick login or developer API key.

### 📝 Changelog

**v0.0** (16-09-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~kick-clips/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Twitch Scraper](https://apify.com/maximedupre/twitch-scraper) - Collect public Twitch clip and VOD metadata for adjacent live-stream research.
- [YouTube Trending Videos Scraper](https://apify.com/maximedupre/youtube-trending-videos-scraper) - Track ranked public YouTube videos by region and category.
- [TikTok Search Scraper](https://apify.com/maximedupre/tiktok-search-results-scraper) - Search public TikTok videos by keyword for short-form content research.
- [YouTube Shorts Downloader](https://apify.com/maximedupre/youtube-shorts-downloader) - Resolve known public YouTube Shorts into source media links and metadata.
- [TikTok Video Downloader](https://apify.com/maximedupre/tiktok-video-downloader) - Get source media links and metadata from known public TikTok video URLs.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `findClipsBy` (type: `string`):

Choose whether to discover many clips or enrich one known clip.

## `discoveryScope` (type: `string`):

Choose where to look. Fill the matching Category or Channel field when you choose that scope. The other field is ignored.

## `category` (type: `string`):

Enter one Kick category name or slug when Discovery scope is Category. Leave it blank for other scopes.

## `channel` (type: `string`):

Enter one Kick channel name or slug when Discovery scope is Channel. Leave it blank for other scopes.

## `recencyWindow` (type: `string`):

Limit discovery to clips from this time window. All time includes every clip available in the selected scope.

## `rankBy` (type: `string`):

Views per hour puts recently rising clips first. Total views puts the most watched clips first.

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

Stop after this many ranked clips. Leave it blank to return all matching clips until the source is exhausted.

## `excludeMature` (type: `boolean`):

When on, leave out clips flagged as mature.

## `maxDurationSeconds` (type: `integer`):

Leave it blank to allow clips of any duration. The value is in seconds.

## `minimumViews` (type: `integer`):

Return only clips with at least this many views. Leave it blank to skip this filter.

## `minimumViewsPerHour` (type: `number`):

Return only clips with at least this views-per-hour rate. Leave it blank to skip this filter.

## `onlyNewClips` (type: `boolean`):

Use this with recurring runs to return only clips this Actor has not delivered in earlier runs. The first run can return all matching clips.

## `clipUrl` (type: `string`):

Enter one publicly accessible Kick clip URL. Fill this when Enrich a clip URL is selected. It must use the kick.com domain, with an optional www subdomain.

## `includeTranscript` (type: `boolean`):

For the one clip URL, request a detected-language transcript with ordered, time-aligned segments. This is used only when Enrich a clip URL is selected.

## `translationLanguage` (type: `string`):

Enter or choose a target language for the transcript. Leave it blank to keep only the detected language. This is used only when Include transcript is on.

## Actor input object example

```json
{
  "findClipsBy": "discover",
  "discoveryScope": "global",
  "recencyWindow": "last7Days",
  "rankBy": "viewsPerHour",
  "maxItems": 25,
  "excludeMature": false,
  "onlyNewClips": false,
  "includeTranscript": false
}
```

# Actor output Schema

## `datasetUrl` (type: `string`):

Open the clip results.

# 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 = {
    "findClipsBy": "discover",
    "discoveryScope": "global",
    "recencyWindow": "last7Days",
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/kick-clips").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 = {
    "findClipsBy": "discover",
    "discoveryScope": "global",
    "recencyWindow": "last7Days",
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/kick-clips").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 '{
  "findClipsBy": "discover",
  "discoveryScope": "global",
  "recencyWindow": "last7Days",
  "maxItems": 25
}' |
apify call maximedupre/kick-clips --silent --output-dataset

```

## MCP server setup

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

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/H6FJmTmc9vm2BT7Xl/builds/N8HRMGIXYnmyTLAQy/openapi.json
