> 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 a knowledge store

> Search a knowledge store with a natural-language query and receive ranked video clips and images. Filter by item type or item, 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.

**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 or specific items, 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. Return only one type, or restrict to specific items.
    # 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 the system and user metadata of each item.
)

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. Return only one type, or restrict to specific items.
  // 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 the system and user metadata of each item.
});

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 to one type of item (`{"asset_type": {"eq": "image"}}`) or to specific items (an `item_id` condition). Omit to search all items.
* *(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 the system and user metadata of each item.\


**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 to one type of item (`{ assetType: { eq: "image" } }`) or to specific items (an `itemId` condition). Omit to search all items.
* *(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 the system and user metadata of each item.\


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