Upload from a direct URL

This guide shows how you can upload a video file from a publicly accessible URL The platform will retrieve the file directly from the specified URL, so your application doesn't have to store the video locally and upload it.

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


  • You’re familiar with the concepts that are described on the Platform overview 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 Create indexes page.
  • The URL of the video that you want to upload is stored in a variable named VIDEO_URL.
  • Your video must meet the following requirements:
    • Video resolution: Must be greater or equal than 360p and less or equal than 4K. For consistent search results, Twelve Labs recommends you upload 360p videos.
    • Duration: For Marengo, it must be between 4 seconds and 2 hours (7,200s). For Pegasus, it must be between 5 seconds and 30 minutes (1800s).
    • File size: Must not exceed 2 GB.
      If you require different options, send us an email at [email protected].
    • Audio track: If the conversation engine option is selected, the video you're uploading must contain an audio track.


  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 unique identifier of your index, the 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 unique identifier of your index, the 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 POST method of the /tasks endpoint and store the result in a variable named response:

    response = requests.post(TASKS_URL, headers={"x-api-key": API_KEY}, json=data)
    let config = {
        method: 'post',
        url: TASKS_URL,
        headers: headers,
        data : formData
    let resp = await axios(config)
    let 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) The platform must have finished indexing your video before it becomes searchable. You can use the GET method of the /tasks/{_id} endpoint to monitor the indexing process. Construct the URL for retrieving the status of your video indexing task based on the TASK_ID variable you’ve declared in the previous step, and 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={"x-api-key": API_KEY})
        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)



    • 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 Webhooks section.
  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",
      "updated_at": "2022-12-08T11: 34: 50.474Z",
      "video_id": "6391c8a669ff3402ec515aba"