> ## Documentation Index
> Fetch the complete documentation index at: https://docs.transcriptmagic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kick

> Fetch transcripts from public Kick clips.

```http theme={null}
POST https://api.transcriptmagic.com/api/kick/transcript
```

Public Kick **clips** are supported — both the `kick.com/{channel}/clips/{clip_id}` page and the `kick.com/{channel}?clip={clip_id}` share link work. Clips that don't have captions (most of them) are transcribed with AI automatically, so you get a transcript either way — as long as the clip is 2 minutes or shorter (see the FAQ).

<Warning>
  **Clips only.** VODs (`kick.com/{channel}/videos/…`), past broadcasts, live streams, and channel pages are not supported and return `400 Invalid URL`.
</Warning>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.transcriptmagic.com/api/kick/transcript \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"url":"https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ"}'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.transcriptmagic.com/api/kick/transcript",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={"url": "https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ"},
  )

  data = response.json()
  print(data["transcript"])         # plain string
  print(data["transcript_source"])  # "native" or "ai"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.transcriptmagic.com/api/kick/transcript", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ url: "https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ" }),
  });

  const data = await response.json();
  console.log(data.transcript);        // plain string
  console.log(data.transcript_source); // "native" or "ai"
  ```

  ```go Go theme={null}
  package main

  import (
  	"bytes"
  	"encoding/json"
  	"fmt"
  	"net/http"
  )

  func main() {
  	body, _ := json.Marshal(map[string]string{
  		"url": "https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ",
  	})

  	req, _ := http.NewRequest("POST",
  		"https://api.transcriptmagic.com/api/kick/transcript",
  		bytes.NewBuffer(body))
  	req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
  	req.Header.Set("Content-Type", "application/json")

  	resp, _ := http.DefaultClient.Do(req)
  	defer resp.Body.Close()

  	var data struct {
  		Transcript       string `json:"transcript"`
  		TranscriptSource string `json:"transcript_source"`
  	}
  	json.NewDecoder(resp.Body).Decode(&data)
  	fmt.Println(data.Transcript)
  }
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init('https://api.transcriptmagic.com/api/kick/transcript');

  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer YOUR_API_KEY',
      'Content-Type: application/json',
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
      'url' => 'https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ',
  ]));

  $response = curl_exec($ch);
  curl_close($ch);

  $data = json_decode($response, true);
  echo $data['transcript'];
  ```
</CodeGroup>

## Response

```json theme={null}
{
  "success": true,
  "id": "clip_01M3SXGX1A2VJ81RFM56NM8ZZQ",
  "url": "https://kick.com/xqc/clips/clip_01M3SXGX1A2VJ81RFM56NM8ZZQ",
  "transcript": "Okay chat, watch this. No way that just happened...",
  "transcript_source": "ai",
  "credits": 994
}
```

<ResponseField name="transcript" type="string" required>
  The clip transcript as a plain string. No per-line timing.
</ResponseField>

<ResponseField name="transcript_source" type="string">
  `"native"` when the clip had captions, `"ai"` when it was transcribed with AI. Both cost the same.
</ResponseField>

<ResponseField name="id" type="string">
  Kick clip ID (e.g. `"clip_01M3SXGX1A2VJ81RFM56NM8ZZQ"`).
</ResponseField>

<ResponseField name="url" type="string">
  The clip URL that was transcribed.
</ResponseField>

<ResponseField name="credits" type="integer" required>
  Your remaining credit balance after this call.
</ResponseField>

There is no title, thumbnail, timestamps, or `videoUrls` field in the Kick response.

## Supported URL formats

| Format | Example |
| - | - |
| Clip page | `https://kick.com/{channel}/clips/{clip_id}` |
| Share link | `https://kick.com/{channel}?clip={clip_id}` |

Clip IDs look like `clip_01M3SXGX…`. Share links (`?clip=`), `www.`, query strings, and fragments are normalized to `https://kick.com/{channel}/clips/{clip_id}` server-side, so every form resolves to the same cached transcript. VOD and channel URLs without a clip ID are rejected with `400 Invalid URL. Please provide a valid Kick clip URL.`

## FAQ

<AccordionGroup>
  <Accordion title="Can I transcribe a VOD or a live stream?">
    No — this endpoint is for **clips only**. VODs, past broadcasts, and live streams are rejected with `400 Invalid URL. Please provide a valid Kick clip URL.` Clip the part you need on Kick, then send the clip URL.
  </Accordion>

  <Accordion title="Are there length limits?">
    AI transcription (used when a clip has no captions, which is most Kick clips) is capped at 2 minutes. Longer clips return `422` with `code: "too_long"` and are not charged. Don't retry these — the result won't change.
  </Accordion>

  <Accordion title="What if the clip has no captions?">
    Most clips don't, and that's fine — they're transcribed with AI automatically. `transcript_source` tells you which path was used. AI-transcribed clips take a little longer to return.
  </Accordion>

  <Accordion title="How much does it cost?">
    1 credit per clip, whether the transcript came from captions or AI. Errors and cache hits are free.
  </Accordion>

  <Accordion title="Do deleted or private clips work?">
    No. Only publicly viewable clips can be transcribed. Deleted or unavailable clips return `404 No transcript available for this video`. You won't be charged.
  </Accordion>

  <Accordion title="Does the response include timestamps?">
    No. Kick clip transcripts are returned as plain text — there is no per-line timing.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.