> This page is for version v1.3 (default).
> For other versions, use one of these documentation indexes:
> - v1.3 (default): https://beta.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://beta.docs.twelvelabs.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://beta.docs.twelvelabs.io/_mcp/server.

# Search a knowledge store

> Search a knowledge store with a natural-language query and receive ranked video clips and images. Filter by type of item, custom metadata, enrichment values, creation time, or capture location, and page through results.

This guide shows you how to search a knowledge store with a natural-language query. The search matches both videos and images: a video result is a clip with a time range, and an image result is the whole image. Each result is ranked by relevance. Use the results in a search interface or a processing pipeline.

Use direct search when a literal query describes what you need and you want the matching clips and images to display or process. For interpretive or subjective queries, or to have [Jockey](/v1.3/agents/concepts/jockey) explain and refine the results, see [agentic search](/v1.3/agents/recipes/agentic-search) instead.

**Key features**:

* **Natural-language queries**: Searches videos and images with a single natural-language query.
* **Video and image results**: Returns a clip with a time range for each video match and the whole image for each image match.
* **Relevance ranking**: Ranks every result by relevance.
* **Modality control**: Matches videos by visual content, audio, or both. Images always match on their visual content.
* **Filters**: Limits the search to the items that you choose.

**Use cases**:

* **In-app search features**: Build content search into your application.
* **Content retrieval**: Find specific moments and images across a large collection without manual review.
* **Targeted lookups**: Filter to a type of item, specific items, custom metadata, enrichment values, creation time, or capture location, then page through the results.

# Key concepts

* **Knowledge store**: A persistent store of your videos and images plus the understanding the platform derives from them - spatiotemporal context, a typed ontology, and embeddings - that together enable corpus-level reasoning.
* **Modalities**: The sources of information the platform searches within a video: visual content and audio (both speech and non-speech sounds). The platform searches images by their visual content. For guidance, see the [Modalities](/v1.3/docs/concepts/modalities) page.

# Prerequisites

You've already added at least one asset to a knowledge store, and the knowledge store item has reached the `ready` status. See the [Add assets to a knowledge store](/v1.3/agents/guides/add-assets) page for details.

# Example

Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values. The example searches both videos and images with a single query, then pages through the results and prints every match.

**`Python`**

```python Python maxlines=42
from twelvelabs import TwelveLabs

client = TwelveLabs(api_key="<YOUR_API_KEY>")
STORE_ID = "<YOUR_KNOWLEDGE_STORE_ID>"

# Step 1: Send the request
result = client.knowledge_stores.search(
    knowledge_store_id=STORE_ID,
    query={"text": "<YOUR_QUERY>"},
    search_options={
        "video": {
            "modalities": ["visual", "audio"],
        }
    },
    # filter={"asset_type": {"eq": "image"}},  # Optional. Narrow results to specific items.
    # filter={"user_metadata": {"category": {"eq": "tutorial"}}, "created_at": {"gte": "2026-09-01T00:00:00Z"}},  # Optional. Narrow results by custom metadata and creation time.
    # group_by="item",  # Optional. Return one result per item instead of per clip.
    # page_size=10,  # Optional. Results per page. Default 10, maximum 50.
    # include_metadata=True,  # Optional. Return a metadata object in each result.
)

while True:
    # Step 2: Process the results
    for hit in result.data:
        if hit.asset_type == "video":
            clip = hit.matches[0]
            print(f"Rank {hit.rank}: video {hit.item_id}  {clip.start_sec}s-{clip.end_sec}s")
            if clip.transcription:
                print(f"  transcription: {clip.transcription}")
        elif hit.asset_type == "image":
            print(f"Rank {hit.rank}: image {hit.item_id}")

    # Step 3: Request the next page
    if not result.next_page_token:
        break
    result = client.knowledge_stores.search(
        knowledge_store_id=STORE_ID,
        query={"text": "<YOUR_QUERY>"},
        search_options={"video": {"modalities": ["visual", "audio"]}},
        page_token=result.next_page_token,
    )
```

**`Node.js`**

```javascript Node.js maxlines=42
import { TwelveLabs } from "twelvelabs-js";

const client = new TwelveLabs({ apiKey: "<YOUR_API_KEY>" });
const storeId = "<YOUR_KNOWLEDGE_STORE_ID>";

// Step 1: Send the request
let result = await client.knowledgeStores.search(storeId, {
  query: { text: "<YOUR_QUERY>" },
  searchOptions: {
    video: {
      modalities: ["visual", "audio"],
    },
  },
  // filter: { assetType: { eq: "image" } }, // Optional. Narrow results to specific items.
  // filter: { userMetadata: { category: { eq: "tutorial" } }, createdAt: { gte: new Date("2026-09-01T00:00:00Z") } }, // Optional. Narrow results by custom metadata and creation time.
  // groupBy: "item", // Optional. Return one result per item instead of per clip.
  // pageSize: 10, // Optional. Results per page. Default 10, maximum 50.
  // includeMetadata: true, // Optional. Return a metadata object in each result.
});

while (true) {
  // Step 2: Process the results
  for (const hit of result.data ?? []) {
    if (hit.assetType === "video") {
      const clip = hit.matches[0];
      console.log(`Rank ${hit.rank}: video ${hit.itemId}  ${clip.startSec}s-${clip.endSec}s`);
      if (clip.transcription) {
        console.log(`  transcription: ${clip.transcription}`);
      }
    } else if (hit.assetType === "image") {
      console.log(`Rank ${hit.rank}: image ${hit.itemId}`);
    }
  }

  // Step 3: Request the next page
  if (!result.nextPageToken) break;
  result = await client.knowledgeStores.search(storeId, {
    query: { text: "<YOUR_QUERY>" },
    searchOptions: { video: { modalities: ["visual", "audio"] } },
    pageToken: result.nextPageToken,
  });
}
```

# Code explanation

#### Python

#### Send the request

Search both videos and images with a single natural-language query. This example matches on visual content and audio.\

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

**Parameters**:

* `knowledge_store_id`: The unique identifier of the knowledge store to search.
* `query`: An object that specifies the search query. Pass the natural-language text in its `text` field.
* `search_options`: An object that controls how videos are matched: by visual content (`visual`) or audio (`audio`, covering both speech and non-speech sounds). Set `modalities` to a subset such as `["visual"]` to match on visual content only. Images always match on their visual content.
* *(Optional)* `filter`: An object that narrows results. Omit to search all items. An item must match all of the fields that you specify. For the fields and their operators, see the [`SearchKnowledgeStoreFilter`](/v1.3/sdk-reference/python/search-knowledge-store#search-a-knowledge-store) class in the SDK reference. Examples:
  * `{"asset_type": {"eq": "image"}}` matches only images.
  * `{"user_metadata": {"category": {"eq": "tutorial"}}}` matches items that have the value `tutorial` for the `category` key.
  * `{"tags": {"metadata": {"event": {"eq": "goal"}}}}` returns only the clips within tags that have the value `goal` for the `event` key.
* *(Optional)* `group_by`: Set to `"item"` to return one result per item, with all matching clips of a video ranked together. Defaults to individual matches.
* *(Optional)* `page_size`: The number of results per page. Default 10, maximum 50.
* *(Optional)* `include_metadata`: Set to `true` to return a `metadata` object in each result. The object has the `system`, `user`, and `item` fields.\


**Return value**: An object of type `SearchKnowledgeStoreResponse` with a field named `data`, which is an array of matches ranked by relevance, and a field named `next_page_token` that appears when more results remain.

#### Process the results

Read each match from the `data` array. The `asset_type` field identifies each match as a video or an image: a video match includes a `matches` array whose clips have the `start_sec`, `end_sec`, and `modalities` fields; an image match has no clip. This example prints each match to the standard output.

#### Request the next page

Each response returns up to `page_size` results (10 by default). When the response includes a `next_page_token` field, more results remain.\

**Function call**: You call the [`knowledge_stores.search`](/v1.3/sdk-reference/python/search-knowledge-store#search-a-knowledge-store) method again with the same request, adding the `page_token` field.\

**Parameters**:

* `page_token`: The `next_page_token` value from the previous response.\


**Return value**: The next page of results. Stop when a response omits the `next_page_token` field.

#### Node.js

#### Send the request

Search both videos and images with a single natural-language query. This example matches on visual content and audio.\

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

**Parameters**: You pass the knowledge store identifier as the first argument and the remaining parameters as properties of a second object.

* `knowledgeStoreId`: The unique identifier of the knowledge store to search.
* `query`: An object that specifies the search query. Pass the natural-language text in its `text` field.
* `searchOptions`: An object that controls how videos are matched: by visual content (`visual`) or audio (`audio`, covering both speech and non-speech sounds). Set `modalities` to a subset such as `["visual"]` to match on visual content only. Images always match on their visual content.
* *(Optional)* `filter`: An object that narrows results. Omit to search all items. An item must match all of the fields that you specify. For the fields and their operators, see the [`SearchKnowledgeStoreFilter`](/v1.3/sdk-reference/node-js/search-knowledge-store#search-a-knowledge-store) object in the SDK reference. Examples:
  * `{ assetType: { eq: "image" } }` matches only images.
  * `{ userMetadata: { category: { eq: "tutorial" } } }` matches items that have the value `tutorial` for the `category` key.
  * `{ tags: { metadata: { event: { eq: "goal" } } } }` returns only the clips within tags that have the value `goal` for the `event` key.
* *(Optional)* `groupBy`: Set to `"item"` to return one result per item, with all matching clips of a video ranked together. Defaults to individual matches.
* *(Optional)* `pageSize`: The number of results per page. Default 10, maximum 50.
* *(Optional)* `includeMetadata`: Set to `true` to return a `metadata` object in each result. The object has the `system`, `user`, and `item` fields.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `SearchKnowledgeStoreResponse` with a field named `data`, which is an array of matches ranked by relevance, and a field named `nextPageToken` that appears when more results remain.

#### Process the results

Read each match from the `data` array. The `assetType` field identifies each match as a video or an image: a video match includes a `matches` array whose clips have the `startSec`, `endSec`, and `modalities` fields; an image match has no clip. This example prints each match to the standard output.

#### Request the next page

Each response returns up to `pageSize` results (10 by default). When the response includes a `nextPageToken` field, more results remain.\

**Function call**: You call the [`knowledgeStores.search`](/v1.3/sdk-reference/node-js/search-knowledge-store#search-a-knowledge-store) method again with the same request, adding the `pageToken` field.\

**Parameters**:

* `pageToken`: The `nextPageToken` value from the previous response.\


**Return value**: The next page of results. Stop when a response omits the `nextPageToken` field.

# Example response

For a query such as "a rocket lifting off the launch pad", a typical response with a video result and an image result looks like this:

```json
{
  "data": [
    {
      "asset_type": "video",
      "rank": 1,
      "item_id": "ksi_069e9870-3c4d-7abc-9012-3456789abcde",
      "matches": [
        {
          "start_sec": 22.5,
          "end_sec": 29.75,
          "modalities": ["visual", "audio"],
          "transcription": "We have a liftoff. Liftoff on Apollo 11."
        }
      ]
    },
    {
      "asset_type": "image",
      "rank": 2,
      "item_id": "ksi_069e1e97-27f8-7a8e-8000-bf32ecd7fc8c"
    }
  ]
}
```

> **Note**
>
> For a video result, the `item_id` field identifies the source video, and the `start_sec` and `end_sec` fields give the start and end offsets of the matching clip, in seconds. Together they locate the exact clip. For an image result, the `item_id` field identifies the whole image. Use these identifiers to play, preview, or display the match in your search results.