Skip to navigation

Search a knowledge store

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 explain and refine the results, see 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, an item collection, custom metadata, enrichment values, creation time, capture location, or item tags, 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 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 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.

from twelvelabs import TwelveLabs
client = TwelveLabs(api_key="<YOUR_API_KEY>")
STORE_ID = "<YOUR_KNOWLEDGE_STORE_ID>"
# Step 1: Send the request
search_args = {
"knowledge_store_id": STORE_ID,
"query": {"text": "<YOUR_QUERY>"},
"search_options": {
"video": {
"modalities": ["visual", "audio"],
}
},
# Uncomment one "filter" line. To combine fields, put them in one object.
# "filter": {"asset_type": {"eq": "image"}}, # Optional. Narrow results by type of item.
# "filter": {"item_collection_id": {"eq": "<YOUR_ITEM_COLLECTION_ID>"}}, # Optional. Narrow results to the items in an item collection.
# "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.
}
result = client.knowledge_stores.search(**search_args)
while True:
# Step 2: Process the results
for hit in result.data:
if hit.asset_type == "video":
for clip in hit.matches:
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(
**search_args, page_token=result.next_page_token
)

Code explanation

1

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 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 class in the SDK reference. Examples:
    • {"asset_type": {"eq": "image"}} matches only images.
    • {"item_collection_id": {"eq": "<YOUR_ITEM_COLLECTION_ID>"}} matches only the items in that item collection. An item collection is a named collection of items in a knowledge store. To create an item collection and retrieve its identifier, see Create an item collection.
    • {"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. A tag marks a moment or a range of a video item. To create one, see Create an item tag.
  • (Optional) group_by: Set to "item" to return one result per item, with all matching clips of a video ranked together. Defaults to "none", which returns 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. The data field is an array of matches ranked by relevance. The effective_search_options field shows the video options that the search applied. The next_page_token field appears when more results remain.

2

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. Each clip in the array has the start_sec, end_sec, and modalities fields. It also has the transcription field when spoken-word data is available for the clip, whichever modalities matched. An image match has no clip. This example prints every clip and every image to the standard output.

3

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 method again with the same request, adding the page_token field.
Parameters:

  • page_token: The next_page_token value from the previous response. The token identifies the original search, so the platform ignores any search fields that you send with it.

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

Exclude items and filter custom metadata by range

Use the nin operator of the item_id field to exclude every clip and image of the listed items. Combine it with numeric and date ranges in the user_metadata field. Pass the object as the filter argument:

filter = {
"item_id": {"nin": ["ksi_069e9870-3c4d-7abc-9012-3456789abcde"]},
"user_metadata": {
"published_at": {"gte": "2026-09-29T00:00:00Z"},
"creator_follower_count": {"gte": 100000},
"duration": {"lte": 60},
},
}

Every condition must match. gte and lte include the boundary value and can be combined on one key. Numeric ranges match numeric scalars, and date ranges match RFC 3339 timestamps with a timezone. In Node.js, pass a date as a Date object. Missing, malformed, null, and array values do not match a range.

All three keys in this example, published_at, creator_follower_count, and duration, are custom metadata that you stored on the source asset or the knowledge store item. The duration key matches your custom metadata, not the system_metadata.duration field. The created_at field filters by the creation time of the item, not by the dates in your custom metadata.

When you set item collection, metadata, enrichment, creation time, or location conditions, the platform counts the items that match all of them. The count includes metadata ranges and the items that you include or exclude with the item_id field. If more than 10,000 items match, the platform returns a 422 error with the metadata_filter_too_broad code before it searches. Narrow the conditions and retry.

Example response

A response includes the next_page_token field when more results remain. 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:

{
"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"
}
],
"next_page_token": "eyJwYWdlIjoyfQ==",
"effective_search_options": {
"video": {
"modalities": ["visual", "audio"]
}
}
}
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.