> This page is for version v1.3 (default).
> For other versions, use one of these documentation indexes:
> - v1.3 (default): https://docs.twelvelabs.io/v1.3/llms.txt

> 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.

# Search

> Find moments in your videos using natural language, images, or both.

Use the TwelveLabs Video Understanding Platform to find specific moments in your video content using natural language queries or reference images. The platform analyzes videos by integrating images, audio, speech, and text, offering a deeper understanding than single-modal methods. It captures complex relationships between these elements, detects subtle details, and supports natural language queries and images for intuitive and precise use.

**Key features**:

* **Improved accuracy**: Multimodal integration enhances accuracy.
* **Easy interaction**: Natural language queries simplify searches.
* **Advanced search**: Enables image-based queries for precise results.
* **Fewer errors:** Multi-faceted analysis reduces misinterpretation.
* **Time savings**: Quickly finds relevant clips without manual review.

**Use cases**:

* **Spoken word search**: Find video segments where specific words or phrases are spoken.
* **Visual element search**: Locate video segments that match descriptions of visual elements or scenes.
* **Action or event search**: Identify video segments that depict specific actions or events.
* **Image similarity search**: Find video segments that visually resemble a provided image.
* **Entity search**: Locate video segments containing specific people, car models, animal species, or branded objects with improved accuracy.

For details on how your usage is measured and billed, see the [Pricing](https://www.twelvelabs.io/pricing) page.

# Key concepts

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

* **Index**: A container that organizes your video content
* **Asset**: Your uploaded content. Once created, you can reference the same asset across multiple operations without uploading the file again.
* **Indexed asset**: An asset that has been indexed and is ready for downstream tasks.

# Workflow

Upload and index your videos before you search them. The platform indexes videos asynchronously. You can search your videos after indexing completes. Search results show video segments that match your search terms.

**Types of search queries**

The platform supports three types of search queries:

* **Text queries**: Search using natural language descriptions of visual elements, actions, sounds, or spoken words
* **Image queries**: Search using images to find visually similar content in your videos
* **Composed queries**: Combine text descriptions with images for more precise results

For guidance on choosing the correct query type, see the [Search with text, image, and composed queries](/v1.3/docs/guides/search/search-with-text-and-image-queries) page.

**Search scope**

You can search within a single index per request. You cannot search at the video level or across multiple indexes simultaneously.

**Customize your search**

You can customize your search in the following ways:

* Specify which modalities to use: visual, audio, or transcription (spoken words)
* Choose how to combine modalities: use the `or` or `and` operators
* For searches within spoken words, select the match type: lexical, semantic, or both

# 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 local files up to 4 GB, see the [Upload and processing methods](/v1.3/docs/concepts/upload-methods) page.
  * **Model capabilities**: See the complete [requirements](/v1.3/docs/concepts/models/marengo/marengo-3-0#video-file-requirements) for resolution, aspect ratio, and supported formats.

* If you wish to use images as queries, ensure that your image file meet the [requirements](/v1.3/docs/concepts/models/marengo/marengo-3-0#image-file-requirements).

# Complete example

Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values.

#### Text queries

**`Python`**

```python Python maxlines=12
import time
from twelvelabs import TwelveLabs

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

# 2. Create an index
# An index is a container for organizing your video content
index = client.indexes.create(
    index_name="<YOUR_INDEX_NAME>",
    models=[{"model_name": "marengo3.0", "model_options": ["visual", "audio"]}]
)
if not index.id:
    raise RuntimeError("Failed to create an index.")
print(f"Created index: id={index.id}")

# 3. 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}")

# 4. 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)

# 5. Index your video
indexed_asset = client.indexes.indexed_assets.create(
    index_id=index.id,
    asset_id=asset.id,
    # enable_video_stream=True
)
print(f"Created indexed asset: id={indexed_asset.id}")

# 6. Monitor the indexing process
print("Waiting for indexing to complete.")
while True:
    indexed_asset = client.indexes.indexed_assets.retrieve(
        index_id=index.id,
        indexed_asset_id=indexed_asset.id
    )
    print(f"  Status={indexed_asset.status}")

    if indexed_asset.status == "ready":
        print("Indexing complete!")
        break
    elif indexed_asset.status == "failed":
        raise RuntimeError("Indexing failed")

    time.sleep(5)

# 7. Perform a search request
search_results = client.search.query(
    index_id=index.id,
    query_text="<YOUR_QUERY>",
    search_options=["visual", "audio"]
    # operator="or" # Optional: Use "and" to find segments matching all modalities
    # transcription_options=["lexical", "semantic"]  # Optional: Control transcription matching, requires "transcription" in search_options)
)

# 8. Process the search results
print("\nSearch results:")
print("Each result shows a video clip that matches your query:\n")
for i, clip in enumerate(search_results):
    print(f"Result {i + 1}:")
    print(f"  Video ID: {clip.video_id}")  # Unique identifier of the video
    print(f"  Rank: {clip.rank}")  # Relevance ranking (1 = most relevant)
    print(f"  Time: {clip.start}s - {clip.end}s", end="\n\n")  # When this moment occurs in the video
```

**`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. Create an index
// An index is a container for organizing your video content
const index = await client.indexes.create({
  indexName: "<YOUR_INDEX_NAME>",
  models: [{ modelName: "marengo3.0", modelOptions: ["visual", "audio"] }]
});
if (!index.id) {
  throw new Error("Failed to create an index.");
}
console.log(`Created index: id=${index.id}`);

// 3. 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}`);

// 4. 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");

// 5. Index your video
let indexedAsset = await client.indexes.indexedAssets.create(index.id, {
  assetId: asset.id,
  enableVideoStream: true
});
console.log(`Created indexed asset: id=${indexedAsset.id}`);

// 6. Monitor the indexing process
console.log("Waiting for indexing to complete.");
while (true) {
  indexedAsset = await client.indexes.indexedAssets.retrieve(
    index.id,
    indexedAsset.id
  );
  console.log(`  Status=${indexedAsset.status}`);

  if (indexedAsset.status === "ready") {
    console.log("Indexing complete!");
    break;
  } else if (indexedAsset.status === "failed") {
    throw new Error("Indexing failed");
  }

  await new Promise(resolve => setTimeout(resolve, 5000));
}

// 7. Perform a search request
const searchResults = await client.search.query({
  indexId: index.id,
  queryText: "<YOUR_QUERY>",
  searchOptions: ["visual", "audio"]
  // operator: "or", // Optional: Use "and" to find segments matching all modalities
  // transcriptionOptions: ["lexical", "semantic"]  // Optional: Control transcription matching, requires "transcription" in searchOptions)
});

// 8. Process the search results
console.log("\nSearch results:");
console.log("Each result shows a video clip that matches your query:\n");
let resultIndex = 0;
for await (const clip of searchResults) {
  console.log(`Result ${++resultIndex}:`);
  console.log(`  Video ID: ${clip.videoId}`);  // Unique identifier of the video
  console.log(`  Rank: ${clip.rank}`);  // Relevance ranking (1 = most relevant)
  console.log(`  Time: ${clip.start}s - ${clip.end}s`);  // When this moment occurs in the video
  console.log();
}
```

#### Image queries

**`Python`**

```python Python maxLines=12
import time
from twelvelabs import TwelveLabs

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

# 2. Create an index
# An index is a container for organizing your video content
index = client.indexes.create(
    index_name="<YOUR_INDEX_NAME>",
    models=[{"model_name": "marengo3.0", "model_options": ["visual", "audio"]}]
)
if not index.id:
    raise RuntimeError("Failed to create an index.")
print(f"Created index: id={index.id}")

# 3. 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}")

# 4. 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)

# 5. Index your video
indexed_asset = client.indexes.indexed_assets.create(
    index_id=index.id,
    asset_id=asset.id,
    # enable_video_stream=True
)
print(f"Created indexed asset: id={indexed_asset.id}")

# 6. Monitor the indexing process
print("Waiting for indexing to complete.")
while True:
    indexed_asset = client.indexes.indexed_assets.retrieve(
        index_id=index.id,
        indexed_asset_id=indexed_asset.id
    )
    print(f"  Status={indexed_asset.status}")

    if indexed_asset.status == "ready":
        print("Indexing complete!")
        break
    elif indexed_asset.status == "failed":
        raise RuntimeError("Indexing failed")

    time.sleep(5)

# 7. Perform a search request
search_results = client.search.query(
    index_id=index.id,
    search_options=["visual"],
    query_media_type="image",
    query_media_url="<YOUR_IMAGE_URL>",
    # Or for a local file: query_media_file=open("<PATH_TO_IMAGE_FILE>", "rb")
    # Or for multiple URLs: query_media_urls=["<YOUR_IMAGE_URL_1>", "<YOUR_IMAGE_URL_2>"]
    # Or for multiple local files: query_media_files=[open("<PATH_TO_IMAGE_FILE_1>", "rb"), open("<PATH_TO_IMAGE_FILE_2>", "rb")]
)

# 8. Process the search results
print("\nSearch results:")
print("Each result shows a video clip that matches your query:\n")
for i, clip in enumerate(search_results):
    print(f"Result {i + 1}:")
    print(f"  Video ID: {clip.video_id}")  # Unique identifier of the video
    print(f"  Rank: {clip.rank}")  # Relevance ranking (1 = most relevant)
    print(f"  Time: {clip.start}s - {clip.end}s")  # When this moment occurs in the video
    print()
```

**`Node.js`**

```javascript Node.js maxLines=12
import { TwelveLabs } from "twelvelabs-js";
// Uncomment the next line if using videoFile instead of videoUrl, or queryMediaFile/queryMediaFiles with fs.createReadStream()
// import * as fs from "fs";

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

// 2. Create an index
// An index is a container for organizing your video content
const index = await client.indexes.create({
  indexName: "<YOUR_INDEX_NAME>",
  models: [{ modelName: "marengo3.0", modelOptions: ["visual", "audio"] }]
});
if (!index.id) {
  throw new Error("Failed to create an index.");
}
console.log(`Created index: id=${index.id}`);

// 3. 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}`);

// 4. 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");

// 5. Index your video
let indexedAsset = await client.indexes.indexedAssets.create(index.id, {
  assetId: asset.id,
  enableVideoStream: true
});
console.log(`Created indexed asset: id=${indexedAsset.id}`);

// 6. Monitor the indexing process
console.log("Waiting for indexing to complete.");
while (true) {
  indexedAsset = await client.indexes.indexedAssets.retrieve(
    index.id,
    indexedAsset.id
  );
  console.log(`  Status=${indexedAsset.status}`);

  if (indexedAsset.status === "ready") {
    console.log("Indexing complete!");
    break;
  } else if (indexedAsset.status === "failed") {
    throw new Error("Indexing failed");
  }

  await new Promise(resolve => setTimeout(resolve, 5000));
}

// 7. Perform a search request
const searchResults = await client.search.query({
  indexId: index.id,
  searchOptions: ["visual"],
  queryMediaType: "image",
  queryMediaUrl: "<YOUR_IMAGE_URL>",
  // Or for a local file: queryMediaFile: fs.createReadStream("<PATH_TO_IMAGE_FILE>")
  // Or for multiple URLs: queryMediaUrls: ["<YOUR_IMAGE_URL_1>", "<YOUR_IMAGE_URL_2>"]
  // Or for multiple local files: queryMediaFiles: [fs.createReadStream("<PATH_TO_IMAGE_FILE_1>"), fs.createReadStream("<PATH_TO_IMAGE_FILE_2>")]
});

// 8. Process the search results
console.log("\nSearch results:");
console.log("Each result shows a video clip that matches your query:\n");
let resultIndex = 0;
for await (const clip of searchResults) {
  resultIndex++;
  console.log(`Result ${resultIndex}:`);
  console.log(`  Video ID: ${clip.videoId}`);  // Unique identifier of the video
  console.log(`  Rank: ${clip.rank}`);  // Relevance ranking (1 = most relevant)
  console.log(`  Time: ${clip.start}s - ${clip.end}s`);  // When this moment occurs in the video
  console.log();
}
```

#### Composed text and image queries

**`Python`**

```python Python maxLines=12
import time
from twelvelabs import TwelveLabs

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

# 2. Create an index
# An index is a container for organizing your video content
index = client.indexes.create(
    index_name="<YOUR_INDEX_NAME>",
    models=[{"model_name": "marengo3.0", "model_options": ["visual", "audio"]}]
)
if not index.id:
    raise RuntimeError("Failed to create an index.")
print(f"Created index: id={index.id}")

# 3. 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}")

# 4. 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)

# 5. Index your video
indexed_asset = client.indexes.indexed_assets.create(
    index_id=index.id,
    asset_id=asset.id
)
print(f"Created indexed asset: id={indexed_asset.id}")

# 6. Monitor the indexing process
print("Waiting for indexing to complete.")
while True:
    indexed_asset = client.indexes.indexed_assets.retrieve(
        index_id=index.id,
        indexed_asset_id=indexed_asset.id
    )
    print(f"  Status={indexed_asset.status}")

    if indexed_asset.status == "ready":
        print("Indexing complete!")
        break
    elif indexed_asset.status == "failed":
        raise RuntimeError("Indexing failed")

    time.sleep(5)

# 7. Perform a search request
search_results = client.search.query(
    index_id=index.id,
    search_options=["visual"],
    query_text="<YOUR_QUERY>",
    query_media_type="image",
    query_media_url="<YOUR_IMAGE_URL>",
    # Or for a local file: query_media_file=open("<PATH_TO_IMAGE_FILE>", "rb")
    # Or for multiple URLs: query_media_urls=["<YOUR_IMAGE_URL_1>", "<YOUR_IMAGE_URL_2>"]
    # Or for multiple local files: query_media_files=[open("<PATH_TO_IMAGE_FILE_1>", "rb"), open("<PATH_TO_IMAGE_FILE_2>", "rb")]
)

# 8. Process the search results
print("\nSearch results:")
print("Each result shows a video clip that matches your query:\n")
for i, clip in enumerate(search_results):
    print(f"Result {i + 1}:")
    print(f"  Video ID: {clip.video_id}")  # Unique identifier of the video
    print(f"  Rank: {clip.rank}")  # Relevance ranking (1 = most relevant)
    print(f"  Time: {clip.start}s - {clip.end}s")  # When this moment occurs in the video
    print()
```

**`Node.js`**

```javascript Node.js maxLines=12
import { TwelveLabs } from "twelvelabs-js";
// Uncomment the next line if using videoFile instead of videoUrl, or queryMediaFile/queryMediaFiles with fs.createReadStream()
// import * as fs from "fs";

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

// 2. Create an index
// An index is a container for organizing your video content
const index = await client.indexes.create({
  indexName: "<YOUR_INDEX_NAME>",
  models: [{ modelName: "marengo3.0", modelOptions: ["visual", "audio"] }],
});
if (!index.id) {
  throw new Error("Failed to create an index.");
}
console.log(`Created index: id=${index.id}`);

// 3. 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}`);

// 4. 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");

// 5. Index your video
let indexedAsset = await client.indexes.indexedAssets.create(index.id, {
  assetId: asset.id,
  enableVideoStream: true,
});
console.log(`Created indexed asset: id=${indexedAsset.id}`);

// 6. Monitor the indexing process
console.log("Waiting for indexing to complete.");
while (true) {
  indexedAsset = await client.indexes.indexedAssets.retrieve(
    index.id,
    indexedAsset.id
  );
  console.log(`  Status=${indexedAsset.status}`);

  if (indexedAsset.status === "ready") {
    console.log("Indexing complete!");
    break;
  } else if (indexedAsset.status === "failed") {
    throw new Error("Indexing failed");
  }

  await new Promise((resolve) => setTimeout(resolve, 5000));
}

// 7. Perform a search request
const searchResults = await client.search.query({
  indexId: index.id,
  searchOptions: ["visual"],
  queryText: "<YOUR_QUERY>",
  queryMediaType: "image",
  queryMediaUrl: "<YOUR_IMAGE_URL>",
  // Or for a local file: queryMediaFile: fs.createReadStream("<PATH_TO_IMAGE_FILE>")
  // Or for multiple URLs: queryMediaUrls: ["<YOUR_IMAGE_URL_1>", "<YOUR_IMAGE_URL_2>"]
  // Or for multiple local files: queryMediaFiles: [fs.createReadStream("<PATH_TO_IMAGE_FILE_1>"), fs.createReadStream("<PATH_TO_IMAGE_FILE_2>")]
});

// 8. Process the search results
console.log("\nSearch results:");
console.log("Each result shows a video clip that matches your query:\n");
let resultIndex = 0;
for await (const clip of searchResults) {
  resultIndex++;
  console.log(`Result ${resultIndex}:`);
  console.log(`  Video ID: ${clip.videoId}`);  // Unique identifier of the video
  console.log(`  Rank: ${clip.rank}`);  // Relevance ranking (1 = most relevant)
  console.log(`  Time: ${clip.start}s - ${clip.end}s`);  // When this moment occurs in the video
  console.log();
}
```

# Code explanation

#### Python

#### Import the SDK and initialize the client

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

**Function call**: You call the [constructor](/v1.3/sdk-reference/python/the-twelve-labs-class#the-initializer) of the `TwelveLabs` class.\

**Parameters**:

* `api_key`: The API key to authenticate your requests to the platform.\


**Return value**: An object of type `TwelveLabs` configured for making API calls.

#### Create an index

Indexes store and organize your video data, allowing you to group related videos. This guide shows how to create one, but you can also use an existing index.\

**Function call**: You call the [`indexes.create`](/v1.3/sdk-reference/python/manage-indexes#create-an-index) function.\

**Parameters**:

* `index_name`: The name of the index.
* `models`: An array specifying your model configuration. This example enables the [Marengo](/v1.3/docs/concepts/models/marengo) video understanding model and specifies that it analyzes visual and audio modalities.

See the [Indexes](/v1.3/docs/concepts/indexes) page for more details on creating an index and specifying the model configuration.\


**Return value**: An object of type `IndexesCreateResponse` containing a field named `id` representing the unique identifier of the newly created index.

#### Upload a video

Upload a video to create an asset.\

**Function call**: You call the [`assets.create`](/v1.3/sdk-reference/python/upload-content/direct-uploads#create-an-asset) function.\

**Parameters**:

* `method`: The upload method for your asset. Use `url` for a publicly accessible or `direct` to upload a local file. This example uses `url`.
* `url` or `file`: The publicly accessible URL of your video or an opened file object in binary read mode. This example uses `url`.

**Return value**: An object of type `Asset`. This object contains, among other information, a field named `id` representing the unique identifier of your asset.

> **Note**
>
> For local files larger than 200 MB, use [multipart uploads](/v1.3/api-reference/upload-content/multipart-uploads). Multipart uploads support automatic retry, progress tracking, parallel chunk uploads, and improved reliability, performance, and observability.

#### Check the status of the asset

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

**Function call**: You call the [`assets.retrieve`](/v1.3/sdk-reference/python/manage-assets#retrieve-an-asset) function.\

**Parameters**:

* `asset_id`: The unique identifier of your asset.\


**Return value**: An object of type `Asset` containing, among other information, a field named `status` representing the current status of the asset. Check this field until its value is `ready`.

#### Index your video

Index your video by adding the asset created in the previous step to an index. This operation is asynchronous.\

**Function call**: You call the [`indexes.indexed_assets.create`](/v1.3/sdk-reference/python/index-content#index-an-asset) function.\

**Parameters**:

* `index_id`: The unique identifier of the index to which the asset will be indexed.
* `asset_id`: The unique identifier of your asset.
* *(Optional)*: `enable_video_stream`: Specifies whether the platform stores the video for streaming. When set to `True`, you can retrieve its URL by calling the [`indexes.indexed_assets.retrieve`](/v1.3/sdk-reference/python/index-content#retrieve-an-indexed-asset) method.

**Return value**: An object of type `IndexedAssetsCreateResponse`. This object contains a field named `id` representing the unique identifier of your indexed asset.

#### Monitor the indexing process

The platform requires some time to index videos. Check the status of the indexing process until it's completed.\

**Function call**: You call the [`indexes.indexed_assets.retrieve`](/v1.3/sdk-reference/python/index-content#retrieve-an-indexed-asset) function.\

**Parameters**:

* `index_id`: The unique identifier of your video index.
* `indexed_asset_id`: The unique identifier of your indexed asset.\


**Return value**: An object of type `IndexedAssetDetailed` containing, among other information, a field named `status` representing the status of the indexing process. Wait until the value of this field is `ready`.

#### Perform a search request

Perform a search within your index using a text or image query or a combination of both.

#### Text queries

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/python/search#make-a-search-request) method.\

**Parameters**:

* `index_id`: The unique identifier of the index.

* `query_text`: Your search query. Note that the platform supports full natural language-based search. The maximum length for a query is 500 tokens.

* `search_options`: The modalities the platform uses when performing a search. This example searches using visual and audio cues. For details, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.

* *(Optional)* `operator`: Combines multiple search options using `or` (default) or `and`. Use `and` to find segments matching all search options. Use `or` to find segments matching any search option.\


* *(Optional)* `transcription_options`: Specifies how the platform matches your query against spoken words. This parameter applies only when `transcription` is included in `search_options`. Available options are `lexical`, `semantic`, or both (default). For details, see the [Transcription options](/v1.3/docs/concepts/modalities#transcription-options) section.\


**Return value**: An object of type `SyncPager[SearchItem]` that can be iterated to access search results. Each item contains the following fields, among other information:

* `video_id`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Image queries

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/python/search#make-a-search-request) method.\

**Parameters**:

* `index_id`: The unique identifier of the index.
* `query_media_type`: The type of query. It must be set to "image".
* `query_media_file`, `query_media_url`, `query_media_files`, or `query_media_urls`: The image or images to use as a query (up to 10). Provide at least one of the following:
  * *(Optional)* `query_media_file`: An opened file object in binary read mode. Use `open(path, 'rb')` to open your local file.\

  * *(Optional)* `query_media_url`: The publicly accessible URL of your image file.\

  * *(Optional)* `query_media_files`: A list of opened file objects in binary read mode.\

  * *(Optional)* `query_media_urls`: A list of publicly accessible URLs.\

* `search_options`: The modalities the platform uses when performing a search. This example searches using visual cues. For guidance on using this parameter, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.\


**Return value**: An object of type `SyncPager[SearchItem]` that can be iterated to access search results. Each item contains the following fields, among other information:

* `video_id`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Composed text and image queries

Combine text descriptions with images for more precise search results. For example, provide an image of a car and use text to specify "red color" to find only red instances of that vehicle.

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/python/search#make-a-search-request) method.\

**Parameters**:

* `index_id`: The unique identifier of the index.
* `query_media_type`: The type of query. It must be set to "image".
* `query_media_file`, `query_media_url`, `query_media_files`, or `query_media_urls`: The image or images to use as a query (up to 10). Provide at least one of the following:
  * *(Optional)* `query_media_file`: An opened file object in binary read mode. Use `open(path, 'rb')` to open your local file.\

  * *(Optional)* `query_media_url`: The publicly accessible URL of your image file.\

  * *(Optional)* `query_media_files`: A list of opened file objects in binary read mode.\

  * *(Optional)* `query_media_urls`: A list of publicly accessible URLs.\

* `query_text`: The text description that refines your image query. Use this to specify additional criteria or context.\

* `search_options`: The modalities the platform uses when performing a search. This example searches using visual cues. For guidance on using this parameter, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.\


**Return value**: An object of type `SyncPager[SearchItem]` that can be iterated to access search results. Each item contains the following fields, among other information:

* `video_id`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Process the search results

This example iterates over the results using a `for` loop to display the search results to the standard output. Each result includes the video ID, relevance ranking, and the time range where the match occurs.\


#### Node.js

#### Import the SDK and initialize the client

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

**Function call**: You call the [constructor](/v1.3/sdk-reference/node-js/the-twelve-labs-class#the-constructor) of the `TwelveLabs` class.\

**Parameters**: You pass all parameters as properties of a single object.

* `apiKey`: The API key to authenticate your requests to the platform.\


**Return value**: An object of type `TwelveLabs` configured for making API calls.

#### Create an index

Indexes store and organize your video data, allowing you to group related videos. This guide shows how to create one, but you can also use an existing index.\

**Function call**: You call the [`indexes.create`](/v1.3/sdk-reference/node-js/manage-indexes#create-an-index) function.\

**Parameters**: You pass all parameters as properties of a single object.

* `indexName`: The name of the index.
* `models`: An array specifying your model configuration. This example enables the [Marengo](/v1.3/docs/concepts/models/marengo) video understanding model and specifies that it analyzes visual and audio modalities.

See the [Indexes](/v1.3/docs/concepts/indexes) page for more details on creating an index and specifying the model configuration.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `IndexesCreateResponse` containing a field named `id` representing the unique identifier of the newly created index.

#### Upload a video

Upload a video to create an asset.\

**Function call**: You call the [`assets.create`](/v1.3/sdk-reference/node-js/upload-content/direct-uploads#create-an-asset) function.\

**Parameters**: You pass all parameters as properties of a single object.

* `method`: The upload method for your asset. Use `url` for a publicly accessible or `direct` to upload a local file. This example uses `url`.
* `url` or `file`: The publicly accessible URL of your video or an opened file object in binary read mode. This example uses `url`.

**Return value**: An `HttpResponsePromise` that resolves to an object of type `Asset`. This object contains, among other information, a field named `id` representing the unique identifier of your asset.

> **Note**
>
> For local files larger than 200 MB, use [multipart uploads](/v1.3/api-reference/upload-content/multipart-uploads). Multipart uploads support automatic retry, progress tracking, parallel chunk uploads, and improved reliability, performance, and observability.

#### Check the status of the asset

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

**Function call**: You call the [`assets.retrieve`](/v1.3/sdk-reference/node-js/manage-assets#retrieve-an-asset) function.\

**Parameters**: You pass the parameter as a positional argument.

* `assetId`: The unique identifier of your asset.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `Asset` containing, among other information, a field named `status` representing the current status of the asset. Check this field until its value is `ready`.

#### Index your video

Index your video by adding the asset created in the previous step to an index. This operation is asynchronous.\

**Function call**: You call the [`indexes.indexedAssets.create`](/v1.3/sdk-reference/node-js/index-content#create-an-indexed-asset) function.\

**Parameters**: You pass the first parameter as a positional argument, and the remaining parameters as properties of a single object.

* `indexId`: The unique identifier of the index to which the asset will be indexed.
* `assetId`: The unique identifier of your asset.
* *(Optional)*: `enableVideoStream`: Specifies whether the platform stores the video for streaming. When set to `true`, you can retrieve its URL by calling the [`indexes.indexedAssets.retrieve`](/v1.3/sdk-reference/node-js/index-content#retrieve-an-indexed-asset) method.

**Return value**: An `HttpResponsePromise` that resolves to an object of type `IndexedAssetsCreateResponse`. This object contains a field named `id` representing the unique identifier of your indexed asset.

#### Monitor the indexing process

The platform requires some time to index videos. Check the status of the indexing process until it's completed.\

**Function call**: You call the [`indexes.indexedAssets.retrieve`](/v1.3/sdk-reference/node-js/index-content#retrieve-an-indexed-asset) function.\

**Parameters**: You pass all parameters as positional arguments.

* `indexId`: The unique identifier of your video index.
* `indexedAssetId`: The unique identifier of your indexed asset.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `IndexedAssetDetailed` containing, among other information, a field named `status` representing the status of your task. Wait until the value of this field is `ready`.

#### Perform a search request

Perform a search within your index using a text or image query or a combination of both.

#### Text queries

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/node-js/search#make-a-search-request) method.\

**Parameters**: You pass all parameters as properties of a single object.

* `indexId`: The unique identifier of the index.

* `queryText`: Your search query. The platform supports full natural language-based search. The maximum length for a query is 500 tokens.

* `searchOptions`: The modalities the platform uses when performing a search. This example searches using visual and audio cues. For details, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.

* *(Optional)* `operator`: Combines multiple search options using `or` (default) or `and`. Use `and` to find segments matching all search options. Use `or` to find segments matching any search option. \


* *(Optional)* `transcriptionOptions`: Specifies how the platform matches your query against spoken words. This parameter applies only when `transcription` is included in `searchOptions`. Available options are `lexical`, `semantic`, or both (default). For details, see the [Transcription options](/v1.3/docs/concepts/modalities#transcription-options) section.\


**Return value**: An object of type `Promise<core.Page<TwelvelabsApi.SearchItem>>` that can be iterated to access search results. Each item contains the following fields, among other information:

* `videoId`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Image queries

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/node-js/search#make-a-search-request) method.\

**Parameters**: You pass all parameters as properties of a single object.

* `indexId`: The unique identifier of the index.
* `queryMediaType`: The type of query. It must be set to "image".
* `queryMediaFile`, `queryMediaUrl`, `queryMediaFiles`, or `queryMediaUrls`: The image or images to use as a query (up to 10). Provide at least one of the following:
  * *(Optional)* `queryMediaFile`: A local image file. Pass a `fs.ReadStream` using `fs.createReadStream("<PATH_TO_IMAGE_FILE>")`.\

  * *(Optional)* `queryMediaUrl`: The publicly accessible URL of your image file.\

  * *(Optional)* `queryMediaFiles`: A list of local images. Pass `fs.ReadStream` objects using `fs.createReadStream("<PATH>")`.\

  * *(Optional)* `queryMediaUrls`: A list of publicly accessible URLs of your images.\

* `searchOptions`: The modalities the platform uses when performing a search. This example searches using visual cues. For guidance on using this parameter, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.\


**Return value**: An object of type `Promise<core.Page<TwelvelabsApi.SearchItem>>` that can be iterated to access search results. Each item contains the following fields, among other information:

* `videoId`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Composed text and image queries

Combine text descriptions with images for more precise search results. For example, provide an image of a car and use text to specify "red color" to find only red instances of that vehicle.

**Function call**: You call the [`search.query`](/v1.3/sdk-reference/node-js/search#make-a-search-request) method.\

**Parameters**: You pass all parameters as properties of a single object.

* `indexId`: The unique identifier of the index.
* `queryMediaType`: The type of query. It must be set to "image".
* `queryMediaFile`, `queryMediaUrl`, `queryMediaFiles`, or `queryMediaUrls`: The image or images to use as a query (up to 10). Provide at least one of the following:
  * *(Optional)* `queryMediaFile`: A local image file. Pass a `fs.ReadStream` using `fs.createReadStream("<PATH_TO_IMAGE_FILE>")`.\

  * *(Optional)* `queryMediaUrl`: The publicly accessible URL of your image file.\

  * *(Optional)* `queryMediaFiles`: A list of local images. Pass `fs.ReadStream` objects using `fs.createReadStream("<PATH>")`.\

  * *(Optional)* `queryMediaUrls`: A list of publicly accessible URLs of your images.\

* `queryText`: The text description that refines your image query. Use this to specify additional criteria or context.\

* `searchOptions`: The modalities the platform uses when performing a search. This example searches using visual cues. For guidance on using this parameter, see the [Search options](/v1.3/docs/concepts/modalities#search-options) section.\


**Return value**: An object of type `Promise<core.Page<TwelvelabsApi.SearchItem>>` that can be iterated to access search results. Each item contains the following fields, among other information:

* `videoId`: The unique identifier of the video that matched your search terms.
* `start`: The start time of the matching video clip, expressed in seconds.
* `end`: The end time of the matching video clip, expressed in seconds.
* `rank`: The relevance ranking assigned by the model. Lower numbers indicate higher relevance, starting with 1 for the most relevant result.

#### Process the search results

This example iterates over the results using a `for` loop to display the search results to the standard output. Each result includes the video ID, relevance ranking, and the time range where the match occurs.

# Next steps

* Learn more about [searching with text, image, and composed queries](/v1.3/docs/guides/search/search-with-text-and-image-queries) for best practices and advanced techniques.
* Explore [entity search](/v1.3/docs/guides/search/entity-search) to find specific people in your videos.
* Learn [query engineering](/v1.3/docs/guides/search/query-engineering) techniques to refine your search queries.
* Apply [grouping](/v1.3/docs/guides/search/grouping) to cluster search results from the same video together.
* Implement [filtering](/v1.3/docs/guides/search/filtering) to narrow down results based on specific criteria.