Upload from a URL

In this guide you'll learn how to upload a video file from a publicly accessible URL. The API service will retrieve the file directly from the specified URL, so your application doesn't have to store the video locally and upload the bytes.

For a description of each field in the request and response, see the API Reference > Create a video indexing task page.

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.


  • Your video must meet the following requirements:
    • Video resolution: must be greater or equal than 360p and less than 1080p (FHD)
    • Duration: must be between 10 seconds and 2 hours (7,200s)
      If you require different options, send us an email at support[at]twelvelabs.io.
  • 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 an index, and the unique identifier of your index is stored in a variable named INDEX_ID. For details, see the Creating indexes page.
  • The URL of your video is stored in a variable named VIDEO_URL.


  • For consistent search results, Twelve Labs recommends you upload 360p videos.


  1. Declare the /tasks endpoint:

    TASKS_URL = f"{API_URL}/tasks"
    const TASKS_URL = `${API_URL}/tasks`
  2. If you're using Python, declare a dictionary named data and use it to store the index ID, language, and the URL of your video. If you're using Node.js, declare a variable named formData of type FormData and use it to store the index ID, language, and the URL of your video:

    data = {
      "index_id": INDEX_ID,
      "language": "en",
      "video_url": VIDEO_URL,
    let formData = new FormData()
    formData.append('index_id', INDEX_ID)
    formData.append('language', 'en')
    formData.append('video_url', VIDEO_URL)
  3. Upload your video. Call the /tasks endpoint and store the result in a variable named response:

    response = requests.post(TASKS_URL, headers=headers, data=data)
    config = {
        method: 'post',
        url: TASKS_URL,
        headers: headers,
        data : formData
    resp = await axios(config)
    response = await resp.data
  4. Store the ID of your task in a variable named TASK_ID and print the status code and response:

    TASK_ID = response.json().get("_id")
    print (f"Status code: {response.status_code}")
    pprint (response.json())
    const TASK_ID = response._id
    console.log(`Status code: ${resp.status}`)

    The output should look similar to the following one:

    Status code: 200
      "_id": "6396bf71a62a34ad8ad3ed20"
  5. (Optional) You can use the /tasks/{_id} endpoint to monitor the indexing process. Wait until the status shows as ready:

    TASK_STATUS_URL = f"{API_URL}/tasks/{TASK_ID}"
    while True:
        response = requests.get(TASK_STATUS_URL, headers=headers)
        STATUS = response.json().get("status")
        if STATUS == "ready":
    const TASK_STATUS_URL = `${API_URL}/tasks/${TASK_ID}`
    const uploadResp = await new Promise((res) => {
      const interval = setInterval(async () => {
          const { data: response } = await axios.get(
                    headers: {
                        "x-api-key": API_KEY
            if (response.status == "ready") {
        }, 1000);
  6. (Optional) Store the unique identifier of your video in a variable named VIDEO_ID:

    VIDEO_ID = response.json().get('video_id')
    const VIDEO_ID = uploadResp.video_id
  7. (Optional) Print the unique identifier of your video, the status code, and the response:

    print (f"Status code: {STATUS}")
    print(f"VIDEO ID: {VIDEO_ID}")
    pprint (response.json())
    console.log(`Status code: ${uploadResp.status}`)
    console.log(`VIDEO_ID: ${VIDEO_ID}`)

    The output should look similar to the following one:

    Status code: 200
    VIDEO ID: 6391c8a669ff3402ec515aba
    {'_id': '6391c89afb14854546891276',
      'created_at': '2022-12-08T11:20:58.859Z',
      'estimated_time': '2022-12-08T11:34:54.585Z',
      'index_id': '6391c88bfb14854546891275',
      'metadata': {'duration': 810.84,
        'filename': 'best-racing-moments.mp4',
        'height': 480,
        'width': 854},
      'status': 'ready',
      'type': 'index_task_info',
      'updated_at': '2022-12-08T11:34:50.474Z',
      'video_id': '6391c8a669ff3402ec515aba'}



  • For details about the possible statuses, see the Tasks page.
  • You can also use webhooks to monitor the status of the indexing process. For details, see the Using webhooks section.