> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.reka.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.reka.ai/_mcp/server.

# Clip Generation API (Reka Clip)

> Generate short highlight clips from longer videos

> **Info**
>
> For chat over text, images and short videos, use the OpenAI-compatible [Chat Completions API](/chat/overview).

## Usage

There are two ways to generate clips from your videos:

* **Option 1: 2‑step workflow**
  * Submit a job with `POST /v1/clips`
  * Poll job status with `GET /v1/clips/{id}` until completed
* **Option 2: Single streaming request**
  * Submit a job to `POST /v1/clips` with `stream=true` to receive real‑time progress updates (SSE)

## Option 1: Submit and poll

### Submit a generation job

### Endpoint

* `POST /v1/clips`

### Headers

* `Content-Type: application/json`
* `X-Api-Key: YOUR_API_KEY`

### Request body

`video_urls` (array\[string], required): URLs of input videos

* Must contain at least one URL
* Supports YouTube, Twitch, direct MP4 links

`prompt` (string, optional): Description of the clip to generate

* Defaults to `Create an engaging short video highlighting the best moments`

`generation_config` (object, optional):

| Field                  | Type                     | Default     | Notes                                 |
| ---------------------- | ------------------------ | ----------- | ------------------------------------- |
| `template`             | `moments \| compilation` | **moments** | Generation style                      |
| `num_generations`      | integer (1–3)            | **1**       | Number of clips to generate           |
| `min_duration_seconds` | integer ≥ 0              | **0**       | Minimum clip length                   |
| `max_duration_seconds` | integer (1–600)          | **90**      | Maximum clip length                   |
| `source_start_time`    | integer                  | —           | Start time for source video (seconds) |
| `source_end_time`      | integer                  | —           | End time for source video (seconds)   |

\


`rendering_config` (object, optional):

| Field            | Type                                       | Default   | Notes                                                                                                       |
| ---------------- | ------------------------------------------ | --------- | ----------------------------------------------------------------------------------------------------------- |
| `show_watermark` | boolean                                    | **false** | Display Reka watermark                                                                                      |
| `subtitles`      | boolean                                    | **true**  | Enable subtitles                                                                                            |
| `aspect_ratio`   | `9:16 \| 9:16-split \| 16:9 \| 4:5 \| 1:1` | **9:16**  | Output aspect ratio. \*Note: `9:16-split` means the clip will include split screen reframing where optimal. |
| `resolution`     | `240 \| 360 \| 480 \| 720 \| 1080`         | **720**   | 1080p may incur HD processing fee                                                                           |
| `caption_style`  | object                                     | —         | Optional subtitle styling configuration (see below)                                                         |

* Resolution and HD processing: The API tries to deliver the requested resolution. If it delivers a lower one, you are not charged the HD fee.

`caption_style` (object, optional):

| Field               | Type                                                             | Default       | Notes                                      |
| ------------------- | ---------------------------------------------------------------- | ------------- | ------------------------------------------ |
| `desired_font_size` | number (60–120)                                                  | **120**       | Subtitle font size                         |
| `text_transform`    | `initial \| uppercase \| lowercase`                              | **uppercase** | Text casing                                |
| `text_color`        | hex string                                                       | **#FFFFFF**   | ![](/_fern-files/reka-ai.docs.buildwithfern.com/3613b1f0b3d1d566e1dd8c642ab2826fcccc3644beed16d89431031bb3b7620b/docs/assets/text_white.png)       |
| `highlight_color`   | hex string                                                       | **#FF7E4F**   | ![](/_fern-img/914d8ff367cdf18e7e46ca39f49dfe2fabfc687c205a1972c265851e25b3bf3d.webp) |
| `stroke_color`      | hex string                                                       | **#000000**   | ![](/_fern-img/f5581933cde7d07d997c96ba78ad64e6e424f002fa9c7261b91f750e0ae13985.webp)     |
| `position`          | `top \| middle \| bottom`                                        | **bottom**    | Subtitle position                          |
| `font_family`       | `BebasNeue \| Bangers \| RobotoCondensed \| Lato \| CaptionFont` | **BebasNeue** | ![](/_fern-img/907dea6984a81b1b849b4545efec58e79869e68ffeabf9c980843660817b75dc.webp)       |

* Validation: The API ignores unsupported keys and invalid or out-of-range values.

### Request example

#### Bash

```bash
curl -X POST "https://vision-agent.api.reka.ai/v1/clips" \
  -H "X-Api-Key: $REKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_urls": ["https://www.youtube.com/watch?v=U0Cd8jbj5zg"],
    "prompt": "Create an engaging short video highlighting the best moments",
    "generation_config": {
      "template": "moments",
      "num_generations": 3,
      "min_duration_seconds": 0,
      "max_duration_seconds": 60
    },
    "rendering_config": {
      "subtitles": true,
      "aspect_ratio": "9:16",
      "resolution": 720,
      "caption_style": {
            "desired_font_size": 120,
            "text_transform": "uppercase",
            "text_color": "#FFFFFF",
            "highlight_color": "#FF7E4F",
            "stroke_color": "#000000",
            "position": "middle",
            "font_family": "BebasNeue"
          }
    }
  }'
```

#### Python

```python
import requests, json

BASE_URL = "https://vision-agent.api.reka.ai"
API_KEY = "YOUR_API_KEY"  # or use an environment variable

endpoint_url = f"{BASE_URL}/v1/clips"
payload = {
    "video_urls": ["https://www.youtube.com/watch?v=U0Cd8jbj5zg"],
    "prompt": "Create an engaging short video highlighting the best moments",
    "generation_config": {
        "template": "moments",
        "num_generations": 3,
        "min_duration_seconds": 0,
        "max_duration_seconds": 60,
    },
    "rendering_config": {
        "subtitles": True,
        "aspect_ratio": "9:16",
        "resolution": 720,
        "caption_style": {
              "desired_font_size": 120,
              "text_transform": "uppercase",
              "text_color": "#FFFFFF",
              "highlight_color": "#FF7E4F",
              "stroke_color": "#000000",
              "position": "middle",
              "font_family": "BebasNeue"
            }
    },
}
headers = {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
}

response = requests.post(endpoint_url, headers=headers, json=payload)
response.raise_for_status()
result = response.json()
print(json.dumps(result, indent=2))

generation_id = result["id"]
```

### Response example (job accepted)

```json
{
  "id": "156b59b3-82a2-4619-99c5-954d80d3e254",
  "status": "queued",
  "created_at": "2026-01-17T19:23:20.878691+00:00",
  "updated_at": "2026-01-17T19:23:20.878691+00:00",
  "generation_config": {
    "template": "moments",
    "num_generations": 3,
    "min_duration_seconds": 0,
    "max_duration_seconds": 60
  },
  "rendering_config": {
    "subtitles": true,
    "aspect_ratio": "9:16",
    "resolution": 720,
    "caption_style": {
          "desired_font_size": 120,
          "text_transform": "uppercase",
          "text_color": "#FFFFFF",
          "highlight_color": "#FF7E4F",
          "stroke_color": "#000000",
          "position": "middle",
          "font_family": "BebasNeue"
        }
  },
  "video_urls": [
    "https://www.youtube.com/watch?v=1vM3Xsiwsao"
  ],
  "prompt": "Create an engaging short video highlighting the best moments"
}
```

A newly submitted job starts with `status` set to `queued`.

Save the `id`. You need it to check generation status.

### Check generation status

* `GET /v1/clips/{id}`

Returns job metadata and, when `status` is `completed`, an `output` array with generated clips.

### Request example

#### Bash

```bash
GEN_ID="YOUR_GENERATION_ID"
curl -X GET "https://vision-agent.api.reka.ai/v1/clips/${GEN_ID}" \
  -H "X-Api-Key: $REKA_API_KEY" \
  -H "Content-Type: application/json" | jq .
```

#### Python

```python
url = f"{BASE_URL}/v1/clips/{generation_id}"
headers = {"X-Api-Key": API_KEY}

resp = requests.get(url, headers=headers)
resp.raise_for_status()
status = resp.json()
print(json.dumps(status, indent=2))
```

### Response example (processing)

```json
{
  "id": "be22635b-8d25-4c7a-b885-b1dcba82973d",
  "status": "processing",
  "created_at": "2026-01-18T19:10:13.36329+00:00",
  "updated_at": "2026-01-18T19:10:13.36329+00:00",
  "generation_config": {
    "template": "moments",
    "num_generations": 3,
    "min_duration_seconds": 0,
    "max_duration_seconds": 60
  },
  "rendering_config": {
    "subtitles": true,
    "aspect_ratio": "9:16"
  },
  "video_urls": [
    "https://www.youtube.com/watch?v=x6-vh91YnuY"
  ],
  "prompt": "Create an engaging short video highlighting the best moments",
  "output": [],
  "error_message": null
}
```

The `status` field shows the job's current stage, `processing` in this example.

#### Job lifecycle

A job moves through these states:

```mermaid
---
title: Job lifecycle
---

stateDiagram-v2
    direction LR
    [*] --> queued
    state preparation{
        direction LR
        
        queued --> starting
        starting --> downloading
        downloading --> indexing
    }
    
    state ai{
        direction LR
        
        indexing --> preprocessing
        preprocessing --> processing
    }

    processing  --> completed
    completed --> [*]
```

Once the status is `completed`, the response includes the generated clips:

### Response example (completed)

```json
{
  "id": "156b59b3-82a2-4619-99c5-954d80d3e254",
  "status": "completed",
  "created_at": "2026-01-17T19:23:20.878691+00:00",
  "updated_at": "2026-01-17T19:27:03.650333+00:00",
  "generation_config": {
    "template": "moments",
    "num_generations": 3,
    "min_duration_seconds": 0,
    "max_duration_seconds": 60
  },
  "rendering_config": {
    "subtitles": true,
    "aspect_ratio": "9:16"
  },
  "video_urls": [
    "https://www.youtube.com/watch?v=1vM3Xsiwsao"
  ],
  "prompt": "Create an engaging short video highlighting the best moments",
  "output": [
    {
      "title": "Marcelo's Wild Family Party Stories",
      "video_url": "https://guardian-user-uploads-prod.cdn.reka.ai/org-a10e5eec-1028-49fa-9144-ef676e3328e1/reels/2ab608e5b0d7704b521aae004d1d7b2c",
      "caption": "When your cousins make you do the most unhinged things at family parties 😭💀 Marcelo's comedy is unmatched!",
      "hashtags": [
        "#MarceloHernandez",
        "#StandUp",
        "#Comedy",
        "#FamilyParty",
        "#Cousins",
        "#LiveComedy",
        "#Funny",
        "#Relatable",
        "#Netflix",
        "#AmericanBoy"
      ],
      "ai_score": 82
    },
    {
      "title": "The Ultimate Test Fail Story",
      "video_url": "https://guardian-user-uploads-prod.cdn.reka.ai/org-a10e5eec-1028-49fa-9144-ef676e3328e1/reels/53b91df6844880cf225d617dc0e2b282",
      "caption": "POV: You feel like a genius on a test but forget to write your NAME 💀 Marcelo's story is too relatable!",
      "hashtags": [
        "#MarceloHernandez",
        "#TestFail",
        "#Epic",
        "#Relatable",
        "#Comedy",
        "#StoryTime",
        "#Funny",
        "#Netflix",
        "#AmericanBoy",
        "#LateNight"
      ],
      "ai_score": 88
    },
    {
      "title": "Marcelo's Viral Sebastian Maniscalco Impression Tutorial",
      "video_url": "https://guardian-user-uploads-prod.cdn.reka.ai/org-a10e5eec-1028-49fa-9144-ef676e3328e1/reels/702d8d67dff7cae2c2b06dedead0de05",
      "caption": "When someone asks you to break down your viral SNL impression 😂 Marcelo's Sebastian is TOO accurate!",
      "hashtags": [
        "#MarceloHernandez",
        "#SebastianManiscalco",
        "#SNLImpression",
        "#Viral",
        "#Tutorial",
        "#Comedy",
        "#Impression",
        "#BehindTheScenes",
        "#TalkShow",
        "#Perfect"
      ],
      "ai_score": 92
    }
  ],
  "error_message": null
}
```

## Option 2: Streaming in one request

Set `stream: true` to receive Server-Sent Events (SSE) with progress updates until completion.

### Request example

#### Bash

```bash
curl -N -X POST "https://vision-agent.api.reka.ai/v1/clips" \
  -H "X-Api-Key: $REKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_urls": [
      "https://demo-videos-bucket-reka.s3.eu-west-2.amazonaws.com/evYsMdBrFXc.mp4"
    ],
    "prompt": "Create an engaging short video highlighting the best moments",
    "generation_config": {
      "template": "moments",
      "num_generations": 1
    },
    "rendering_config": {
      "subtitles": true,
      "aspect_ratio": "9:16",
      "resolution": 720,
      "caption_style": {
        "desired_font_size": 120,
        "text_transform": "uppercase",
        "text_color": "#FFFFFF",
        "highlight_color": "#FF7E4F",
        "stroke_color": "#000000",
        "position": "middle",
        "font_family": "BebasNeue"
      }
    },
    "stream": true
  }'
```

#### Python

```python
import requests, json
from typing import Generator, Dict, Any

endpoint_url = f"{BASE_URL}/v1/clips"
payload = {
    "video_urls": ["https://demo-videos-bucket-reka.s3.eu-west-2.amazonaws.com/evYsMdBrFXc.mp4"],
    "prompt": "Create an engaging short video highlighting the best moments",
    "generation_config": {
        "template": "moments",
        "num_generations": 1,
        "min_duration_seconds": 0,
        "max_duration_seconds": 90,
    },
    "rendering_config": {
        "subtitles": True,
        "aspect_ratio": "9:16",
    "resolution": 1080,
    "caption_style": {
          "desired_font_size": 120,
          "text_transform": "uppercase",
          "text_color": "#FFFFFF",
          "highlight_color": "#FF7E4F",
          "stroke_color": "#000000",
          "position": "middle",
          "font_family": "BebasNeue"
        }
    },
    "stream": True,
}
headers = {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
}

def stream_events(response) -> Generator[Dict[str, Any], None, None]:
    last_data = None
    for line in response.iter_lines():
        if not line:
            continue
        decoded = line.decode("utf-8")
        if decoded.startswith("data: "):
            try:
                data = json.loads(decoded[6:])
                if data != last_data:
                    yield data
                last_data = data
            except json.JSONDecodeError:
                pass

with requests.post(endpoint_url, headers=headers, json=payload, stream=True) as r:
    r.raise_for_status()
    for event in stream_events(r):
        print(json.dumps(event, indent=2))
```

### Streaming event example

```json
{
  "id": "ada0bc6f-3540-4bb2-baa0-308e9fcf1d06",
  "status": "preprocessing",
  "created_at": "2026-01-18T19:28:49.839838+00:00",
  "updated_at": "2026-01-18T19:29:33.202844+00:00",
  "generation_config": {
    "template": "moments",
    "num_generations": 1,
    "min_duration_seconds": 0,
    "max_duration_seconds": 90
  },
  "rendering_config": {
    "subtitles": true,
    "aspect_ratio": "9:16"
  },
  "video_urls": [
    "https://www.youtube.com/watch?v=9JbE_HtiewI"
  ],
  "prompt": "Create an engaging short video highlighting the best moments"
}
```

The `status` field shows the job's current stage, `preprocessing` in this example. See [Job Lifecycle](#job-lifecycle) for the full progression.

### Error response example

```json
{
  "id": "11add419-fc2e-4491-98fd-e0b362103ff1",
  "status": "failed",
  "created_at": "2026-01-18T19:23:05.649501+00:00",
  "updated_at": "2026-01-18T19:24:16.798044+00:00",
  "generation_config": {
    "template": "moments",
    "num_generations": 1,
    "min_duration_seconds": 0,
    "max_duration_seconds": 90
  },
  "rendering_config": {
    "subtitles": true,
    "aspect_ratio": "9:16"
  },
  "video_urls": [
    "https://www.youtube.com/watch?v=x6-vh91YnuY"
  ],
  "prompt": "Create an engaging short video highlighting the best moments",
  "error_message": "This preview of Reka Clip is limited to videos with a maximum duration of 2 hours.\nPlease contact us if you need support for longer videos!"
}
```

If a generation fails, the job enters a terminal `failed` state and includes an `error_message` describing the cause.

## Resources

Code examples in Python, Node.js and C# are on [**Reka AI's Github**](https://github.com/reka-ai/clip-api-examples).

For an example of Reka Clip in n8n, see the [**n8n template**](https://n8n.io/workflows/12926-generate-ai-video-clips-from-youtube-using-reka-vision-api-and-gmail/).

To try this API without code, use [**Reka Clip**](https://clip.reka.ai). Paste a YouTube or Twitch link and it generates clips.