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

# Segment videos

> Quickstart: segment videos into structured, timestamped data. Working example with core parameters.

This quickstart guide provides a simplified introduction to segmenting videos into structured, timestamped data using the TwelveLabs Video Understanding Platform. It includes the following:

* A basic working example
* Minimal implementation details
* Core parameters for common use cases

For a comprehensive guide, see the [Segment videos](/v1.3/docs/guides/segment-videos) guide.

# Key concepts

This section explains the key concepts and terminology used in this guide:

* **Asset**: Your uploaded content. Once created, you can reference the same asset across multiple operations without uploading the file again.
* **Segment definition**: A description of a type of segment you want to extract. Each definition includes a unique identifier, a natural language description, and optional custom fields.
* **Segment field**: A custom metadata field to extract for each segment. Each field has a name, a type, and a description.

# Workflow

This guide shows how to upload your video as an asset, create an asynchronous segmentation task with Pegasus 1.5, and parse the timestamped metadata from the results.

# Prerequisites

* To use the platform, you need an API key:

  If you don't have an account, [sign up](https://playground.twelvelabs.io/) for a free account.

  Go to the [API Keys](https://playground.twelvelabs.io/dashboard/api-keys) page.

  If you need to create a new key, select the **Create API Key** button. Enter a name and set the expiration period. The default is 12 months.

  Select the **Copy** icon next to your key to copy it to your clipboard.

* Depending on the programming language you are using, install the TwelveLabs SDK by entering one of the following commands:

  **`Python`**

  ```shell Python
  pip install --upgrade twelvelabs
  ```

  **`Node.js`**

  ```shell Node.js
  yarn add twelvelabs-js@latest # or npm install twelvelabs-js@latest
  ```

* Your videos must meet the following requirements:
  * **Upload limits**: Public video URLs up to 4 GB or local videos up to 200 MB. For a video up to 10 GB, use multipart uploads. See the [Upload and processing methods](/v1.3/docs/concepts/upload-methods) page for details.

  * **Analysis method**: The video can be up to 2 hours long, or up to 4 hours when you analyze only a portion of it. You can analyze between 1 second and 2 hours.

  * **Model capabilities**: See the complete requirements for [videos](/v1.3/docs/concepts/models/pegasus#video-file-requirements)

# Starter code

Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values. The example defines a single segment type (`scenes`) with three custom fields to illustrate the shape. Adapt the segment definitions to match what you want to extract from your videos.

**`Python`**

```Python Python maxLines=12
import json
import time
from twelvelabs import TwelveLabs
from twelvelabs.types import AsyncResponseFormat, VideoContext_AssetId

# 1. Initialize the client
client = TwelveLabs(api_key="<YOUR_API_KEY>")

# 2. Upload a video
asset = client.assets.create(
    method="url",
    url="<YOUR_VIDEO_URL>" # Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
    # Or use method="direct" and file=open("<PATH_TO_VIDEO_FILE>", "rb") to upload a local file up to 200 MB
)
print(f"Created asset: id={asset.id}")

# 3. Check the status of the asset
print("Waiting for asset to be ready...")
while True:
    asset = client.assets.retrieve(asset.id)
    if asset.status == "ready":
        print("Asset is ready")
        break
    if asset.status == "failed":
        raise RuntimeError(f"Asset processing failed: id={asset.id}")
    time.sleep(5)

# 4. Create a video segmentation task
video = VideoContext_AssetId(asset_id=asset.id)
task = client.analyze_async.tasks.create(
    video=video,
    model_name="pegasus1.5",
    analysis_mode="time_based_metadata",
    response_format=AsyncResponseFormat(
        type="segment_definitions",
        segment_definitions=[
            {
                "id": "scenes",
                "description": "Segment the video into distinct scenes based on changes in setting, topic, or visual composition",
                "fields": [
                    {
                        "name": "sentiment",
                        "type": "string",
                        "description": "The overall sentiment of this scene",
                        "enum": ["positive", "negative", "neutral"]
                    },
                    {
                        "name": "key_objects",
                        "type": "array",
                        "description": "Notable objects visible in the scene",
                        "items": {"type": "string"}
                    },
                    {
                        "name": "contains_speech",
                        "type": "boolean",
                        "description": "Whether the scene contains speech or dialogue"
                    }
                ]
            }
        ]
    )
)
print(f"Task ID: {task.task_id}")

# 5. Monitor the status
while True:
    task = client.analyze_async.tasks.retrieve(task.task_id)
    if task.status == "ready":
        print("Task completed")
        break
    elif task.status in ("failed", "canceled"):
        message = task.error.message if task.error else f"Task ended with status: {task.status}"
        raise RuntimeError(message)
    else:
        print("Task still processing...")
        time.sleep(5)

# 6. Parse and process the results
data = json.loads(task.result.data)
for segment in data["scenes"]:
    print(f"\n[{segment['start_time']:.1f}s - {segment['end_time']:.1f}s]")
    meta = segment["metadata"]
    print(f"  Sentiment: {meta['sentiment']}")
    print(f"  Key objects: {', '.join(meta['key_objects'])}")
    print(f"  Contains speech: {meta['contains_speech']}")
```

**`Node.js`**

```JavaScript Node.js maxLines=12
import { TwelveLabs } from "twelvelabs-js";
// Uncomment the next line if uploading a local file
// import fs from "fs";

// 1. Initialize the client
const client = new TwelveLabs({ apiKey: "<YOUR_API_KEY>" });

// 2. Upload a video
const asset = await client.assets.create({
  method: "url",
  url: "<YOUR_VIDEO_URL>", // Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
  // Or use method: "direct" and file: fs.createReadStream("<PATH_TO_VIDEO_FILE>") to upload a local file up to 200 MB
});
console.log(`Created asset: id=${asset.id}`);

// 3. Check the status of the asset
console.log("Waiting for asset to be ready...");
let readyAsset = await client.assets.retrieve(asset.id);
while (readyAsset.status !== "ready" && readyAsset.status !== "failed") {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  readyAsset = await client.assets.retrieve(asset.id);
}
if (readyAsset.status === "failed") {
  throw new Error(`Asset processing failed: id=${asset.id}`);
}
console.log("Asset is ready");

// 4. Create a video segmentation task
const { taskId } = await client.analyzeAsync.tasks.create({
  video: { type: "asset_id", assetId: asset.id },
  modelName: "pegasus1.5",
  analysisMode: "time_based_metadata",
  responseFormat: {
    type: "segment_definitions",
    segmentDefinitions: [
      {
        id: "scenes",
        description:
          "Segment the video into distinct scenes based on changes in setting, topic, or visual composition",
        fields: [
          {
            name: "sentiment",
            type: "string",
            description: "The overall sentiment of this scene",
            enum: ["positive", "negative", "neutral"],
          },
          {
            name: "key_objects",
            type: "array",
            description: "Notable objects visible in the scene",
            items: { type: "string" },
          },
          {
            name: "contains_speech",
            type: "boolean",
            description: "Whether the scene contains speech or dialogue",
          },
        ],
      },
    ],
  },
});
console.log(`Task ID: ${taskId}`);

// 5. Monitor the status
let task = await client.analyzeAsync.tasks.retrieve(taskId);
while (!["ready", "failed", "canceled"].includes(task.status)) {
  console.log("Task still processing...");
  await new Promise((resolve) => setTimeout(resolve, 5000));
  task = await client.analyzeAsync.tasks.retrieve(taskId);
}

if (task.status !== "ready") {
  throw new Error(task.error?.message ?? `Task ended with status: ${task.status}`);
}
console.log("Task completed");

// 6. Parse and process the results
const data = JSON.parse(task.result.data);
for (const segment of data.scenes) {
  console.log(
    `\n[${segment.start_time.toFixed(1)}s - ${segment.end_time.toFixed(1)}s]`
  );
  const meta = segment.metadata;
  console.log(`  Sentiment: ${meta.sentiment}`);
  console.log(`  Key objects: ${meta.key_objects.join(", ")}`);
  console.log(`  Contains speech: ${meta.contains_speech}`);
}
```

# Code explanation

#### Import the SDK and initialize the client

Create a client instance to interact with the TwelveLabs Video Understanding Platform.

#### Upload a video

Upload a video to create an asset.

#### Check the status of the asset

Asset processing is asynchronous. Poll the status of the asset until it is `ready` before you use it.

#### Create a video segmentation task

Define the segments and fields you want to extract. Set the `analysis_mode` parameter to `time_based_metadata` and pass your segment definitions in the `response_format` parameter.

#### Monitor the status

Poll the task until it reaches a terminal `ready`, `failed`, or `canceled` state. Process `result.data` only when the status is `ready`.

#### Parse and process the results

The `result.data` field is a JSON-encoded string. This example parses it, then displays the timestamps and custom metadata for each segment to the standard output.