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

# Create Clips

> Create AI-powered short clips from long-form videos, steered by natural-language prompts for editorial control over count, duration, focus, and tone

> **For AI agents:** a documentation index is at [/llms.txt](/llms.txt). Every page is also available as markdown, just append `.md` to the URL.

## Overview

Transform long-form videos into engaging short clips using AI. This endpoint analyzes your video content and automatically extracts the most engaging moments, creating viral-ready clips optimized for social media platforms.

For finer editorial control, pass a natural-language `prompt` describing what kinds of clips you want — clip count, duration, focus, exclusions, editorial mode, and tone are all under your direction. Without a prompt, the AI falls back to virality-driven selection. See [Prompt](#prompt) below for capabilities and examples.

## Rate Limiting

This endpoint is rate limited to 10 requests per minute per API key.

<Note>
  You must provide either `sourceUrl` or `uploadId`, but not both.
</Note>

## Video Requirements

<CardGroup cols={2}>
  <Card title="Duration" icon="clock">
    **Minimum:** 1 minute\
    **Maximum:** 3 hours
  </Card>

  <Card title="File Size" icon="scale">
    **Maximum:** 10 GB
  </Card>

  <Card title="Format" icon="file-video">
    MP4 or MOV with valid video streams
  </Card>

  <Card title="Content Type" icon="microphone">
    Works best with dialogue-rich content
  </Card>
</CardGroup>

## Plan Limits

| Plan    | Max Resolution | Concurrent Projects |
| ------- | -------------- | ------------------- |
| Creator | 1080p          | 3                   |
| Studio  | 4K (2160p)     | 10                  |

Higher-tier plans allow you to process more videos simultaneously and export at higher resolutions.

<Note>
  The Automation API requires an active subscription. [View pricing](https://reap.video/pricing) to compare plans.
</Note>

## Orientation & Cropping

`exportOrientation` is the single knob for cropping: `portrait` (9:16) and `square` (1:1) automatically crop the source, while `landscape` (16:9) keeps the original framing. Face tracking (`centerStage`) only applies while cropping.

<Warning>
  **Behavior change.** The request field `reframeClips` has been removed — cropping now follows `exportOrientation` alone, and legacy payloads still sending `reframeClips` have it ignored. Previously, `exportOrientation: "portrait"` without `reframeClips: true` was silently downgraded to landscape; the same request now crops to portrait as asked. If your integration relied on `reframeClips: false` to keep the original framing, send `exportOrientation: "landscape"` (or omit the field — landscape is the default).
</Warning>

<Warning>
  **Preview feature.** `prompt` is available for general use but is still being refined. The field itself, its name, and its 1000-character limit are stable — what may shift is how the AI interprets a given instruction and the set of directives it honors. We recommend treating `prompt` as production-ready for experimentation and internal tooling, and pinning critical workflows to specific prompts you have tested end-to-end.

  See [Prompt](#prompt) below for capabilities and examples.
</Warning>

## Response

<ResponseField name="id" type="string">
  Unique project identifier
</ResponseField>

<ResponseField name="title" type="string">
  Project title (usually the filename)
</ResponseField>

<ResponseField name="thumbnail" type="string">
  Thumbnail URL for the project
</ResponseField>

<ResponseField name="billedDuration" type="number">
  Duration in seconds that will be billed to your account
</ResponseField>

<ResponseField name="status" type="string">
  Current processing status

  * `processing` - Video is being analyzed and clips are being generated
  * `completed` - All clips have been generated successfully
  * `failed` - Processing failed due to an error
</ResponseField>

<ResponseField name="projectType" type="string">
  Type of project (always "clipping" for this endpoint)
</ResponseField>

<ResponseField name="source" type="string">
  Source of the video content

  * `Upload` - Uploaded file
  * `Youtube` - YouTube URL
</ResponseField>

<ResponseField name="genre" type="string">
  Video genre used for AI analysis
</ResponseField>

<ResponseField name="topics" type="array">
  Array of identified topics in the video
</ResponseField>

<ResponseField name="clipDurations" type="array">
  Array of clip duration preferences
</ResponseField>

<ResponseField name="selectedStart" type="number">
  Start time in seconds for processing (null if entire video)
</ResponseField>

<ResponseField name="selectedEnd" type="number">
  End time in seconds for processing (null if entire video)
</ResponseField>

<ResponseField name="exportResolution" type="integer">
  Output resolution for the clips
</ResponseField>

<ResponseField name="exportOrientation" type="string">
  Output orientation for the clips
</ResponseField>

<ResponseField name="captionsPreset" type="string">
  Caption style preset ID (null if captions disabled)
</ResponseField>

<ResponseField name="enableCaptions" type="boolean">
  Whether captions are enabled
</ResponseField>

<ResponseField name="enableEmojis" type="boolean">
  Whether emojis are added to captions
</ResponseField>

<ResponseField name="enableHighlights" type="boolean">
  Whether keyword highlighting is enabled
</ResponseField>

<ResponseField name="language" type="string">
  Primary language of the video content
</ResponseField>

<ResponseField name="dubbingLanguage" type="string">
  Target dubbing language (null if not applicable)
</ResponseField>

<ResponseField name="translateTranscription" type="boolean">
  Whether transcription will be translated
</ResponseField>

<ResponseField name="translationLanguages" type="array">
  Array of languages for translation
</ResponseField>

<ResponseField name="transcriptionScript" type="string">
  Script format for transcription ("native" or "roman")
</ResponseField>

<ResponseField name="metadata" type="object">
  Video file metadata including duration, resolution, format, etc.
</ResponseField>

<ResponseField name="urls" type="object">
  Project URLs and assets (populated when processing completes)
</ResponseField>

<ResponseField name="createdAt" type="integer">
  Unix timestamp when the project was created
</ResponseField>

<ResponseField name="updatedAt" type="integer">
  Unix timestamp when the project was last updated
</ResponseField>

## Example Request

<CodeGroup>
  ```bash cURL with Upload theme={"system"}
  curl -X POST "https://public.reap.video/api/v1/automation/create-clips" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "uploadId": "65f1a2b3c4d5e6f7a8b9c0d1",
      "genre": "talking",
      "exportResolution": 1080,
      "exportOrientation": "portrait",
      "captionsPreset": "system_beasty",
      "enableEmojis": true,
      "enableHighlights": true,
      "language": "en",
      "clipDurations": [[30, 60], [60, 90]],
      "topics": ["product launch", "customer testimonials"],
      "prompt": "Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing."
    }'
  ```

  ```bash cURL with YouTube theme={"system"}
  curl -X POST "https://public.reap.video/api/v1/automation/create-clips" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "sourceUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "genre": "talking",
      "exportResolution": 720,
      "exportOrientation": "square",
      "captionsPreset": "system_minimal",
      "clipDurations": [[0, 30]],
      "topics": ["highlights"],
      "prompt": "Give me 3 short, punchy highlight clips suitable for TikTok."
    }'
  ```

  ```javascript JavaScript theme={"system"}
  const response = await fetch('https://public.reap.video/api/v1/automation/create-clips', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      uploadId: '65f1a2b3c4d5e6f7a8b9c0d1',
      genre: 'talking',
      exportResolution: 1080,
      exportOrientation: 'portrait',
      captionsPreset: 'system_beasty',
      enableEmojis: true,
      enableHighlights: true,
      language: 'en',
      clipDurations: [[30, 60], [60, 90]],
      topics: ['product launch', 'customer testimonials'],
      prompt: 'Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing.'
    })
  });

  const project = await response.json();
  console.log('Project created:', project.id);
  ```

  ```python Python theme={"system"}
  import requests

  headers = {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
  }

  data = {
      'uploadId': '65f1a2b3c4d5e6f7a8b9c0d1',
      'genre': 'talking',
      'exportResolution': 1080,
      'exportOrientation': 'portrait',
      'captionsPreset': 'system_beasty',
      'enableEmojis': True,
      'enableHighlights': True,
      'language': 'en',
      'clipDurations': [[30, 60], [60, 90]],
      'topics': ['product launch', 'customer testimonials'],
      'prompt': 'Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing.'
  }

  response = requests.post(
      'https://public.reap.video/api/v1/automation/create-clips',
      headers=headers,
      json=data
  )

  project = response.json()
  print(f'Project created: {project["id"]}')
  ```

  ```php PHP theme={"system"}
  <?php
  $data = [
      'uploadId' => '65f1a2b3c4d5e6f7a8b9c0d1',
      'genre' => 'talking',
      'exportResolution' => 1080,
      'exportOrientation' => 'portrait',
      'captionsPreset' => 'system_beasty',
      'enableEmojis' => true,
      'enableHighlights' => true,
      'language' => 'en',
      'clipDurations' => [[30, 60], [60, 90]],
      'topics' => ['product launch', 'customer testimonials'],
      'prompt' => 'Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing.'
  ];

  $ch = curl_init('https://public.reap.video/api/v1/automation/create-clips');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer YOUR_API_KEY',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
  $project = json_decode($response, true);
  echo 'Project created: ' . $project['id'] . "\n";
  ?>
  ```

  ```go Go theme={"system"}
  package main
  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io/ioutil"
      "net/http"
  )
  func main() {
      url := "https://public.reap.video/api/v1/automation/create-clips"
      data := map[string]interface{}{
          "uploadId": "65f1a2b3c4d5e6f7a8b9c0d1",
          "genre": "talking",
          "exportResolution": 1080,
          "exportOrientation": "portrait",
              "captionsPreset": "system_beasty",
          "enableEmojis": true,
          "enableHighlights": true,
          "language": "en",
          "clipDurations": [][]int{{30, 60}, {60, 90}},
          "topics": []string{"product launch", "customer testimonials"},
          "prompt": "Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing.",
      }
      payload, _ := json.Marshal(data)
      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
      req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")
      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()
      body, _ := ioutil.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```

  ```java Java theme={"system"}
  import java.io.*;
  import java.net.HttpURLConnection;
  import java.net.URL;
  public class CreateClipsExample {
      public static void main(String[] args) throws Exception {
          URL url = new URL("https://public.reap.video/api/v1/automation/create-clips");
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
          conn.setRequestMethod("POST");
          conn.setRequestProperty("Authorization", "Bearer YOUR_API_KEY");
          conn.setRequestProperty("Content-Type", "application/json");
          conn.setDoOutput(true);
          String jsonInputString = "{\"uploadId\":\"65f1a2b3c4d5e6f7a8b9c0d1\",\"genre\":\"talking\",\"exportResolution\":1080,\"exportOrientation\":\"portrait\",\"captionsPreset\":\"system_beasty\",\"enableEmojis\":true,\"enableHighlights\":true,\"language\":\"en\",\"clipDurations\":[[30,60],[60,90]],\"topics\":[\"product launch\",\"customer testimonials\"],\"prompt\":\"Highlight reel of the most quotable founder moments — keep clips under 60 seconds and skip any segments about pricing.\"}";
          try (OutputStream os = conn.getOutputStream()) {
              os.write(jsonInputString.getBytes("utf-8"));
          }
          BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
          StringBuilder response = new StringBuilder();
          String responseLine;
          while ((responseLine = br.readLine()) != null) {
              response.append(responseLine.trim());
          }
          System.out.println("Project created: " + response.toString());
      }
  }
  ```
</CodeGroup>

## Example Response

<CodeGroup>
  <CodeGroup.Tab label="200 OK">
    ```json theme={"system"}
    {
      "id": "65f1a2b3c4d5e6f7a8b9c0d2",
      "title": "My Educational Video",
      "thumbnail": "https://cdn.reap.video/thumbnails/65f1a2b3c4d5e6f7a8b9c0d2.jpg",
      "billedDuration": 1800.5,
      "status": "processing",
      "projectType": "clipping",
      "source": "Upload",
      "genre": "talking",
      "topics": ["product launch", "customer testimonials"],
      "clipDurations": [[30, 60], [60, 90]],
      "selectedStart": 0,
      "selectedEnd": null,
      "exportResolution": 1080,
      "exportOrientation": "portrait",
      "captionsPreset": "system_beasty",
      "enableCaptions": true,
      "enableEmojis": true,
      "enableHighlights": true,
      "language": "en",
      "dubbingLanguage": null,
      "translateTranscription": false,
      "translationLanguages": [],
      "transcriptionScript": "native",
      "metadata": {
        "duration": 1800.5,
        "width": 1920,
        "height": 1080,
        "fps": 30,
        "bitrate": 5000000,
        "size": 450000000,
        "codec": "h264"
      },
      "urls": {},
      "createdAt": 1710000000,
      "updatedAt": 1710000000
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="400 Bad Request">
    ```json theme={"system"}
    {
      "detail": "You must provide either sourceUrl or uploadId, but not both"
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="401 Unauthorized">
    ```json theme={"system"}
    {
      "detail": "Unauthorized - Invalid or missing API key"
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="404 Not Found">
    ```json theme={"system"}
    {
      "detail": "Upload not found"
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="422 Unprocessable Entity">
    ```json theme={"system"}
    {
      "detail": "Invalid video format or duration. Video must be between 1 minute and 3 hours."
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="429 Too Many Requests">
    ```json theme={"system"}
    {
      "detail": "Too Many Requests - Rate limit of 10 requests per minute exceeded"
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="429 Concurrent Project Limit">
    ```json theme={"system"}
    {
      "detail": "Maximum concurrent projects reached. Please wait for the current projects to complete."
    }
    ```
  </CodeGroup.Tab>

  <CodeGroup.Tab label="500 Internal Server Error">
    ```json theme={"system"}
    {
      "detail": "Internal Server Error - Something went wrong on our end"
    }
    ```
  </CodeGroup.Tab>
</CodeGroup>

## Processing Workflow

1. **Upload Analysis** - Video is analyzed for content, speakers, and key moments
2. **AI Clipping** - Our AI identifies the most engaging segments for clips
3. **Processing** - Clips are generated with your specified settings
4. **Completion** - Use [Get Project Status](/api-reference/get-project-status) to monitor progress
5. **Download** - Retrieve clips using [Get Project Clips](/api-reference/get-project-clips)

## Best Practices

* **Content Quality**: Videos with clear speech and engaging content produce better clips
* **Duration**: Longer videos (10+ minutes) typically yield more clip options
* **Genre Selection**: Choose the correct genre for optimal AI analysis
* **Caption Presets**: Use captions for better engagement on social platforms
* **Resolution**: Higher resolutions are better for professional content but take longer to process
* **Clip Durations**: Combine multiple ranges (e.g. `[[30,60],[60,90]]`) to get a variety of clip lengths suited to different platforms. Use shorter for Reels/TikTok, longer for YouTube Shorts
* **Prompt**: Reach for `prompt` when you have specific editorial intent — clip count, duration caps, focus, exclusions, or tone. Topics is the lighter-weight choice for "just bias toward these themes." Keep prompts concrete (1–3 sentences); pin a tested prompt for production workflows since AI interpretation may evolve while the field is in preview
* **Topics**: Be specific with topic strings to get more relevant clips; broad topics like `"highlights"` cast a wider net while narrow ones like `"pricing breakdown"` are more precise

## Clip Duration Ranges

Use `clipDurations` to control the length of generated clips. Each value is a `[min, max]` pair in seconds.

| Value        | Label            |
| ------------ | ---------------- |
| `[0, 30]`    | Under 30 seconds |
| `[30, 60]`   | 30s – 60s        |
| `[60, 90]`   | 60s – 90s        |
| `[90, 180]`  | 90s – 3 minutes  |
| `[180, 300]` | 3 – 5 minutes    |

You can pass multiple ranges to get a mix of clip lengths. When omitted, the AI determines optimal durations based on the content.

## Topics

Use `topics` to steer the AI toward specific subjects in your video. Pass an array of short topic strings (e.g. `["product demo", "pricing"]`) and the AI will prioritize segments that match those themes. When omitted, the AI selects the most engaging topics automatically. For richer control — clip count, duration caps, editorial modes, exclusions, and tone — use the [Prompt](#prompt) field instead.

## Prompt

<Info>
  `prompt` is a preview feature — see the [Preview note](#rate-limiting) at the top of this page. The field schema is stable; how the AI interprets a given prompt may evolve.
</Info>

Use `prompt` to describe in plain language what kinds of clips you want. The instruction (max 1000 characters) is parsed by an LLM into a structured plan that drives clip count, duration, content focus, exclusions, and editorial style. When the prompt and a candidate moment conflict, the prompt wins over generic virality scoring.

### What you can do

* **Set how many clips to produce** — "give me 5 clips", "just one highlight reel"
* **Cap clip length** — "each under 30 seconds", "5-minute deep dives"
* **Focus on specific topics, speakers, or themes** — "only the section about pricing", "moments where the host disagrees with the guest"
* **Exclude segments** — "skip the intro and sponsor reads", "no tangents about politics"
* **Pick an editorial mode** — highlight reel, trailer, compilation, hooks-only, quotes, Q\&A, listicle, storytelling, educational, stats and facts, tips and advice, reaction moments, controversy, topic-focused
* **Steer tone and style** — "prefer high-energy delivery", "open each clip with the key claim"

### Example prompts

The 14 prompts below cover the supported editorial modes. Use them verbatim, edit them to fit your video, or write your own.

<AccordionGroup>
  <Accordion title="Highlight reel">
    Build a highlight reel of the very best moments in the video — peak energy, the strongest reactions, the most quotable lines, and the biggest emotional or visual climaxes. Prioritize moments that would still feel powerful out of context, and skip filler, intros, or set-up.
  </Accordion>

  <Accordion title="Trailer">
    Generate a teaser-style trailer — pick suspenseful, attention-grabbing moments that hook the viewer without giving everything away. Look for cliffhangers, intriguing questions, bold setups, and emotional peaks that make viewers want to watch the full video.
  </Accordion>

  <Accordion title="Compilation">
    Create a compilation of similar moments from across the video — clips that share a common theme, tone, or topic. Group them so they feel cohesive when watched back-to-back as a single themed reel.
  </Accordion>

  <Accordion title="Topic focused">
    Find clips centered on a single topic or theme. Focus on moments where the speaker discusses one specific subject in depth, and skip tangents or unrelated digressions.
  </Accordion>

  <Accordion title="Hooks only">
    Extract only the strongest hooks — the opening lines, bold statements, or attention-grabbing moments designed to stop a viewer mid-scroll. Look for surprising claims, questions, or pattern-interrupts.
  </Accordion>

  <Accordion title="Quotes">
    Pull out the most quotable lines — punchy one-liners, memorable phrases, or sharp insights that work as standalone soundbites and would read well as text overlays or pull-quotes.
  </Accordion>

  <Accordion title="Educational">
    Find educational moments — clear explanations, lessons, frameworks, or insights that teach the viewer something new. Prioritize clips that deliver real value or impart knowledge concisely.
  </Accordion>

  <Accordion title="Listicle">
    Build a listicle-style breakdown — moments where the speaker enumerates points, steps, reasons, or tips in order. Look for "first…", "second…", "three reasons…", and similar list-driven structures.
  </Accordion>

  <Accordion title="Storytelling">
    Pick out storytelling moments — narrative arcs with setup, conflict, and payoff. Look for personal anecdotes, case studies, or any segment where the speaker takes the viewer on a journey.
  </Accordion>

  <Accordion title="Q&A">
    Find clear question-and-answer exchanges — interview questions paired with strong responses, or moments where the speaker fields and addresses a specific question. Each clip should make sense as a standalone Q\&A pair.
  </Accordion>

  <Accordion title="Stats and facts">
    Surface moments containing notable statistics, data points, or factual claims. Look for numbers, percentages, comparisons, or verified facts that lend credibility and would catch a viewer's attention.
  </Accordion>

  <Accordion title="Tips and advice">
    Extract practical tips and advice — short, actionable recommendations the audience can apply immediately. Each clip should deliver one concrete piece of guidance, not vague philosophy.
  </Accordion>

  <Accordion title="Reaction moments">
    Find strong reaction moments — surprise, shock, laughter, awe, or visible emotional responses from anyone on screen. Look for facial expressions and unfiltered reactions that capture the moment's energy.
  </Accordion>

  <Accordion title="Controversy">
    Surface controversial or polarizing moments — strong opinions, callouts, or statements likely to spark debate. Look for clips that take a clear stance or make claims people would react to in the comments.
  </Accordion>
</AccordionGroup>

### Using `prompt` and `topics` together

You can send either field, both, or neither:

* **`prompt` only** — full natural-language control. Drives clip count, duration, focus, exclusions, and mode.
* **`topics` only** — the AI auto-maps to a topic-focused mode and prioritizes the listed themes.
* **Both** — the prompt wins on conflict; topics act as additional guidance the prompt can refine or override.
* **Neither** — the AI falls back to baseline virality-driven selection.

### Limits and validation

* **Length:** up to 1000 characters. Longer prompts are rejected at request validation.
* **Sanitization:** prompts are Unicode-normalized and stripped of zero-width, bidi, and other control characters. Multi-language printable text and emoji are preserved.
* **Rejection:** prompts that attempt jailbreaks, ask for unsupported instructions, or otherwise can't be processed return a `400` with a plain-language reason in the response body.

## Use Cases

<CardGroup cols={2}>
  <Card title="Content Agencies" icon="building">
    Scale video production for multiple clients with automated, prompt-driven clipping workflows
  </Card>

  <Card title="Media Companies" icon="newspaper">
    Repurpose long-form content into platform-optimized clips with editorial prompts that match each show's voice
  </Card>

  <Card title="EdTech Platforms" icon="graduation-cap">
    Extract key teaching moments from lectures at scale, steered by prompts that target concepts and learning objectives
  </Card>

  <Card title="SaaS Products" icon="layers">
    Add prompt-controlled video clipping to your product without building the AI selection layer from scratch
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /automation/create-clips
openapi: 3.1.0
info:
  title: Reap Automation API
  description: AI-powered video processing automation API
  version: 1.0.0
servers:
  - url: https://public.reap.video/api/v1
security:
  - bearerAuth: []
paths:
  /automation/create-clips:
    post:
      summary: Create Clips
      description: Create AI-powered short clips from long-form videos
      operationId: createClips
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateClipsRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutomationProject'
components:
  schemas:
    CreateClipsRequest:
      type: object
      properties:
        sourceUrl:
          type: string
          description: YouTube URL to process (alternative to uploadId)
        uploadId:
          type: string
          description: Upload ID from a previously uploaded file (alternative to sourceUrl)
        exportOrientation:
          type: string
          enum:
            - landscape
            - portrait
            - square
          default: landscape
          description: >-
            Output orientation for the clips — the single knob for cropping.
            'portrait' (9:16) and 'square' (1:1) auto-crop the source;
            'landscape' (16:9) keeps the original framing with no crop. The
            legacy reframeClips field is ignored if sent.
        exportResolution:
          type: integer
          enum:
            - 720
            - 1080
            - 1440
            - 2160
          default: 720
          description: Output resolution for the clips
        captionsPreset:
          type: string
          nullable: true
          description: Caption style preset ID (null to disable captions)
        enableEmojis:
          type: boolean
          default: false
          description: Whether to add emojis to captions
        enableHighlights:
          type: boolean
          default: false
          description: Whether to highlight keywords in captions
        language:
          type: string
          nullable: true
          description: >-
            Primary language of the video content (auto-detected if not
            provided)
        translationLanguage:
          type: string
          nullable: true
          description: Language to translate captions to
        transcriptionScript:
          type: string
          enum:
            - native
            - roman
          default: native
          description: Script format for transcription output
        genre:
          type: string
          enum:
            - talking
            - screenshare
            - gaming
          default: talking
          description: Video genre for better AI analysis
        selectedStart:
          type: number
          nullable: true
          description: Start time in seconds for processing
        selectedEnd:
          type: number
          nullable: true
          description: End time in seconds for processing
        clipDurations:
          type: array
          items:
            type: array
            items:
              type: integer
          default: []
          description: >-
            Preferred clip duration ranges as [min, max] pairs in seconds. Valid
            ranges: [0,30], [30,60], [60,90], [90,180], [180,300]. When omitted,
            the AI determines optimal durations.
        topics:
          type: array
          items:
            type: string
          default: []
          description: >-
            Topic preferences to guide the AI when selecting clip segments. For
            example: ["product launch", "customer testimonials"]. When omitted,
            the AI selects the most engaging topics automatically.
        prompt:
          type: string
          maxLength: 1000
          default: ''
          description: >-
            Preview feature — schema is stable, AI interpretation may evolve.
            Free-form natural-language instruction (max 1000 chars) that guides
            what kinds of clips the AI selects — for example 'highlight reel of
            the funniest moments' or 'only product-demo segments under 30
            seconds'. Can control clip count, duration, content scope,
            exclusions, editorial mode, and tone. Overrides generic virality
            scoring when the prompt and a candidate moment conflict. When
            omitted, the AI uses standard virality-driven selection.
    AutomationProject:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        thumbnail:
          type: string
        billedDuration:
          type: number
        status:
          type: string
          enum:
            - queued
            - prepped
            - draft
            - processing
            - finalizing
            - completed
            - invalid
            - expired
            - failed
            - error
        projectType:
          type: string
          enum:
            - clipping
            - captions
            - reframe
            - dubbing
            - transcription
        source:
          type: string
          enum:
            - Upload
            - Youtube
            - Vimeo
            - TwitchVod
            - Twitter
            - RumbleEmbed
            - Generic
        genre:
          $ref: '#/components/schemas/VideoGenre'
        topics:
          type: array
          items:
            type: string
        clipDurations:
          type: array
          items:
            type: array
            items:
              type: integer
        selectedStart:
          type: number
          nullable: true
        selectedEnd:
          type: number
          nullable: true
        exportResolution:
          type: integer
        exportOrientation:
          $ref: '#/components/schemas/VideoOrientation'
        captionsPreset:
          type: string
          nullable: true
        enableCaptions:
          type: boolean
        enableEmojis:
          type: boolean
        enableHighlights:
          type: boolean
        language:
          type: string
          nullable: true
        dubbingLanguage:
          type: string
          nullable: true
        translateTranscription:
          type: boolean
        translationLanguages:
          type: array
          items:
            type: string
        transcriptionScript:
          $ref: '#/components/schemas/TranscriptionScript'
        metadata:
          $ref: '#/components/schemas/VideoFileMeta'
        urls:
          $ref: '#/components/schemas/ProjectUrls'
        createdAt:
          type: integer
        updatedAt:
          type: integer
    VideoGenre:
      type: string
      enum:
        - talking
        - screenshare
        - gaming
      default: talking
    VideoOrientation:
      type: string
      enum:
        - landscape
        - portrait
        - square
    TranscriptionScript:
      type: string
      enum:
        - native
        - roman
      default: native
    VideoFileMeta:
      type: object
      properties:
        width:
          type: integer
        height:
          type: integer
        aspectRatio:
          type: string
        size:
          type: number
        bitrate:
          type: number
        fps:
          type: number
        duration:
          type: number
        rotation:
          type: integer
        resolution:
          type: integer
        codec:
          type: string
        codecFullName:
          type: string
        codecTag:
          type: string
        format:
          type: string
        formatFullName:
          type: string
    ProjectUrls:
      type: object
      description: >-
        Presigned URLs for the project's assets. URLs expire — always use the
        most recent API response. The transcription_* subtitle/text exports are
        only present on transcription projects.
      properties:
        videoFile:
          type: string
          description: Presigned URL of the processed source video
        audioFile:
          type: string
          description: Presigned URL of the extracted audio track
        transcription:
          type: string
          description: >-
            Presigned URL of the word-level transcript JSON (the translated
            version when translation ran). Lets API consumers audit content
            without video playback.
        transcription_srt:
          type: string
          description: SRT subtitles — transcription projects only
        transcription_vtt:
          type: string
          description: WebVTT subtitles — transcription projects only
        transcription_csv:
          type: string
          description: CSV transcript — transcription projects only
        transcription_txt:
          type: string
          description: Plain-text transcript — transcription projects only
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````