Search results

The /search endpoint supports the following parameters that allow you to control pagination behavior:

  • The identifier of the page: The POST method of the /search endpoint returns the first page of results. To retrieve the subsequent page, you must call the GET method of the /search/{page-token} endpoint, passing it the unique identifier of the page you want to retrieve as a path parameter.
  • The number of items on each page: Set the page_limit parameter in the request body when calling the POST method of the /search endpoint. The default value is 10 and the maximum value is 50.

When making the initial request, you call the POST method of the /search endpoint, passing it a page_limit value of X. The response will contain, among other information, the first page of results, the identifier of the next page, and the time when the page expires. To retrieve the rest of the pages, invoke the GET method of the /search/{page-token} endpoint, replacing the {page-token} path parameter with the identifier of the page that you want to retrieve. When the API does not return the identifier of the next page, you've reached the end of the dataset.

📘

Notes

  • The GET method of the /search endpoint returns, among other information, a field named page_info.prev_page_token representing the unique identifier of the previous page. When the API does not return the page_info.prev_page_token field, then this is the first page.
  • The identifiers of the next and previous pages can become invalid when the page expires or items are added or removed. Do not store them in your application. Using an expired or invalid page identifier returns an HTTP 400 token expired or invalid token error.

The API service returns your search results in the form of an array named data, and the page_limit parameter controls the number of elements on each page. When your search results are not grouped, the page_limit parameter specifies the number of matching video fragments on each page. On the other hand, when your search results are grouped by video, the page_limit parameter specifies the number of videos on each page.

For a description of each field in the response, see the API Reference > Make a search Request page.

Examples

Note that, although the example code in this guide is written in Python and Node.js the API is compatible with most programming languages, and you can also use Postman or other REST clients to send requests and view responses.

Prerequisites

  • A valid Twelve Labs account. For details about creating an account and retrieving your API key, see the Authentication page.
  • You’re familiar with the concepts that are described on the Quickstart page.
  • You’ve created at least one index, and the unique identifier of your index is stored in a variable named INDEX_ID. For details, see the Creating indexes page.
  • You’ve uploaded at least one video to your index, and the API service has finished indexing it. For details, see the Uploading videos page.

Retrieving the first page of results

The following example code retrieves the first page of results by calling the POST method of the /search endpoint:

headers = {
    "x-api-key": API_KEY
}

SEARCH_URL = f"{API_URL}/search"

data = {
  "query": "bear chasing a man",
  "index_id": INDEX_ID,
  "search_options": ["visual"]
}

response = requests.post(SEARCH_URL, headers=headers, json=data)
print (f'Status code: {response.status_code}')
pprint(response.json())
const SEARCH_URL = `${API_URL}/search`

const data = {
  "query": "bear chasing a man",
  "index_id": INDEX_ID,
  "search_options": ["visual"]
}

const resp = await axios.post(
  SEARCH_URL,
  data,
  {
    "headers": {
      "x-api-key": API_KEY
    }
  }
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))

The following example output was truncated for brevity:

{
  "search_pool": {
    "total_count": 13,
    "total_duration": 8731,
    "index_id": "639961c9e219c90227c371a2"
  },
  "data": [
    {
      "score": 86.17,
      "start": 173,
      "end": 190,
      "video_id": "63996260ce36463e0199c8c5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221227%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221227T173944Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=23a084fae38430dbb0f7fb05bad5318eafe01eb71328e237cb7ae25ae70924a3"
    },
    {
      "score": 85.4,
      "start": 483,
      "end": 498,
      "video_id": "63996232ce36463e0199c8c3",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996232ce36463e0199c8c3/484.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221227%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221227T173944Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=600e92cdf3ef3f6ccfed67716e8d04bc7a178bc6bdc72ccd13111ee6343e3ccb"
    },
    {
      "score": 84.99,
      "start": 458,
      "end": 478,
      "video_id": "63996260ce36463e0199c8c5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/459.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221227%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221227T173944Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=71b60dbfe0f149c9dd6880c7a1d8a70cdb553364e83ed171c46962f100fc9202"
    }
  ],
  "page_info": {
    "limit_per_page": 10,
    "total_results": 157,
    "page_expired_at": "2022-12-27T17:39:44Z",
    "next_page_token": "9f161112-1e65-43d7-b10f-0914206c307e-1"
  }
}

In this example output, note the following about the page_info object :

  • The next_page_token property shows the identifier of the next page - 9f161112-1e65-43d7-b10f-0914206c307e-1.
  • The page_expired_at property shows the time when this page expires - 2022-12-27T17:39:44Z.
  • The limit_per_page property shows the number of results on this page - 10.
  • The total_result property shows the total number of results - 157.

Retrieving a specific page

The following example code retrieves a specific page by calling the GET method of the /search endpoint, replacing the placeholder surrounded by <> with the identifier of the page you want to retrieve:

headers = {
    "x-api-key": API_KEY
}

SEARCH_URL = f"{API_URL}/search/<YOUR_PAGE_TOKEN>"

response = requests.get(SEARCH_URL, headers=headers)
print (f'Status code: {response.status_code}')
pprint(response.json())
const SEARCH_URL = `${API_URL}/search/<YOUR_PAGE_TOKEN>`

const resp = await axios.get(
  SEARCH_URL,
  {
    "headers": {
      "x-api-key": API_KEY
    }
  }
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))

The following example output was truncated for brevity:

{
  "search_pool": {
    "total_count": 13,
    "total_duration": 8731,
    "index_id": "639961c9e219c90227c371a2"
  },
  "data": [
    {
      "score": 84.98,
      "start": 419,
      "end": 433,
      "video_id": "63996232ce36463e0199c8c3",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996232ce36463e0199c8c3/420.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T061937Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=aa684e88065c75c024c202793c98dc2e3501692b6f14fcea9e9e105ec583f83e"
    },
    {
      "score": 84.52,
      "start": 409,
      "end": 417,
      "video_id": "63a2a2a7ce36463e0199c8e5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63a2a2a7ce36463e0199c8e5/410.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T061936Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=4e519ad017063ca9ee3ec44a75d01291ae55651a68a1a5ffe77a24a940e22b1f"
    },
    {
      "score": 83.78,
      "start": 788,
      "end": 796,
      "video_id": "63996260ce36463e0199c8c5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/789.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T061937Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=0c1d1bbac8abed8e9d20c3ea188337fe38e779bc5ffa27da7714858393389f87"
    }
  ],
  "page_info": {
    "limit_per_page": 10,
    "total_results": 157,
    "page_expired_at": "2022-12-28T06:19:37Z",
    "next_page_token": "dacfcbf3-7a1b-458e-b4af-bf7b0632faf5-2",
    "prev_page_token": "dacfcbf3-7a1b-458e-b4af-bf7b0632faf5-0"
  }
}

In this example output, note the following about the page_info object :

  • The next_page_token property shows the identifier of the next page - dacfcbf3-7a1b-458e-b4af-bf7b0632faf5-2.
  • The page_expired_at property shows the time when this page expires - 2022-12-28T06:19:37Z.
  • The prev_page_token property shows the identifier of the previous page - dacfcbf3-7a1b-458e-b4af-bf7b0632faf5-0.

Specifying limits

The following example code specifies a limit of 3 items on each page using the page_limit parameter:

headers = {
    "x-api-key": API_KEY
}

SEARCH_URL = f"{API_URL}/search"

data = {
  "query": "bear chasing a man",
  "page_limit": 3,
  "index_id": INDEX_ID,
  "search_options": ["visual"]
}

response = requests.post(SEARCH_URL, headers=headers, json=data)
print (f'Status code: {response.status_code}')
pprint(response.json())
const SEARCH_URL = `${API_URL}/search`

const data = {
  "query": "bear chasing a man",
  "page_limit": 3,
  "index_id": INDEX_ID,
  "search_options": ["visual"]
}

const resp = await axios.post(
  SEARCH_URL,
  data,
  {
    "headers": {
      "x-api-key": API_KEY
    }
  }
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))

The output should look similar to the following one:

{
  "search_pool": {
    "total_count": 13,
    "total_duration": 8731,
    "index_id": "639961c9e219c90227c371a2"
  },
  "data": [
    {
      "score": 86.17,
      "start": 173,
      "end": 190,
      "video_id": "63996260ce36463e0199c8c5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T063135Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=5fefe9d67803ac45ad8a8a5720404ef7e571cae29341028a26904e2039d40a1c"
    },
    {
      "score": 86.14,
      "start": 624,
      "end": 630,
      "video_id": "63996246ce36463e0199c8c4",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996246ce36463e0199c8c4/625.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T063135Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=a79633803efb8d501c9c19104d6aa1b6ff270566f9438bd05027dc3c13908f8e"
    },
    {
      "score": 86.03,
      "start": 149,
      "end": 173,
      "video_id": "63996260ce36463e0199c8c5",
      "confidence": "high",
      "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/150.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221228%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221228T063135Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=160dc91ef266c91532e2fe61eb629734645c8a51f89df04d011783ad8edf21b2"
    }
  ],
  "page_info": {
    "limit_per_page": 3,
    "total_results": 157,
    "page_expired_at": "2022-12-28T06:31:35Z",
    "next_page_token": "86d9bd56-9f57-4591-8542-0a6f4926951e-1"
  }
}

In this example output, note that the limit_per_page property of the page_info object shows that the API service returned three items per page.

Using pagination in conjunction with grouping

When the response is grouped by video, you can use the page_limit parameter to specify the number of videos the API service will return on each page. The following example code sets the page limit to three and specifies that the result must be grouped by video:

headers = {
  "x-api-key": API_KEY
}

SEARCH_URL = f"{API_URL}/search"

data = {
  "query": "car accidents",
  "index_id": INDEX_ID,
  "search_options": ["visual"],
  "page_limit": 3,
  "group_by": "video"
}

response = requests.post(SEARCH_URL, headers=headers, json=data)
print(f"Status code: {response.status_code}")
pprint(response.json())

const SEARCH_URL = `${API_URL}/search`

const data = {
  "query": "car accidents",
  "index_id": INDEX_ID,
  "search_options": ["visual"],
  "page_limit": 3,
  "group_by": "video"
}

const resp = await axios.post(
  SEARCH_URL,
  data,
  {
    "headers": {
      "x-api-key": API_KEY
    }
  }
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))

The output should look similar to the following one:

{
  "search_pool": {
    "total_count": 15,
    "total_duration": 10228,
    "index_id": "639961c9e219c90227c371a2"
  },
  "data": [
    {
      "clips": [
        {
          "score": 81.79,
          "start": 117.8359375,
          "end": 125.71875,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "639963a1ce36463e0199c8c7",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/639963a1ce36463e0199c8c7/118.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=b6dc36209991885951423fd2250f7397f46e5a482cf773c13e66025a12831113"
        },
        {
          "score": 76.8,
          "start": 266.765625,
          "end": 270.5,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "639963a1ce36463e0199c8c7",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/639963a1ce36463e0199c8c7/267.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=dbfdfcf8945bf2f2315e2845e5c30f0470e5a3361e734bcb9cf70e461cb00eb5"
        },
        {
          "score": 75.61,
          "start": 422.21875,
          "end": 428.21875,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "639963a1ce36463e0199c8c7",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/639963a1ce36463e0199c8c7/423.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=66612d0c9fac75a5bbbf6ba155992c25f8cd1cd3a2613fae0fd569460cb95db0"
        },
        {
          "score": 74.9,
          "start": 485.53125,
          "end": 489.53125,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "639963a1ce36463e0199c8c7",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/639963a1ce36463e0199c8c7/486.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=927c2f32cb10a7616464f695a4b61ae7e8533c47783c66bea1603aeec896121a"
        }
      ],
      "id": "639963a1ce36463e0199c8c7"
    },
    {
      "clips": [
        {
          "score": 77.29,
          "start": 27.3984375,
          "end": 31.375,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "63b2c707ce36463e0199c906",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63b2c707ce36463e0199c906/28.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=f83a05ba9ea3e87e6564d450056b183bde8d8c4aa02a95ecd050c7f2ca97c979"
        },
        {
          "score": 75.26,
          "start": 565.8125,
          "end": 569.15625,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "63b2c707ce36463e0199c906",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63b2c707ce36463e0199c906/566.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=cbddd6c0464cccba21593bb2f28b2b835567c47dca4dfc7f3e0b51d4b6862cc4"
        }
      ],
      "id": "63b2c707ce36463e0199c906"
    },
    {
      "clips": [
        {
          "score": 75.73,
          "start": 703.90625,
          "end": 706.375,
          "metadata": [
            {
              "type": "visual"
            }
          ],
          "video_id": "6399637ace36463e0199c8c6",
          "confidence": "medium",
          "thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/6399637ace36463e0199c8c6/704.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20230116%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230116T111230Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=0c6e1eddc437bc7a0cfdd17b7927c5adb6850a4ebd41cfe021956c4d7220aeeb"
        }
      ],
      "id": "6399637ace36463e0199c8c6"
    }
  ],
  "page_info": {
    "limit_per_page": 3,
    "total_results": 5,
    "total_inner_matches": 9,
    "page_expired_at": "2023-01-16T11:12:30Z",
    "next_page_token": "59ae2f31-5c86-48be-8dfb-a76433656df5-1"
  }
}

Note the following about this example output:

  • The data array is composed of three objects as specified by the page_limit parameter. Each object corresponds to a video that matches your query and is formed of the following key-value pairs:
    • clips: An array that groups the information about all the matching video fragments in that video.
    • id: The unique identifier of the video that matched your query.
  • The page_info.total_results field shows the number of videos that matched your search query (5).
  • The page_info.total_inner_matches field shows the number of video fragments that matched your query. In this example, a total of nine fragments in five videos matched your query.