> This page is for version v1.3 (default).
> For other versions, use one of these documentation indexes:
> - v1.3 (default): https://docs.twelvelabs.io/v1.3/llms.txt

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

# Create a video indexing task

POST https://api.twelvelabs.io/v1.3/tasks
Content-Type: multipart/form-data

This method will be removed in a future version. New implementations should use [direct](/v1.3/api-reference/upload-content/direct-uploads) or [multipart](/v1.3/api-reference/upload-content/multipart-uploads) uploads followed by [separate indexing](/v1.3/api-reference/index-content/create).This method creates a video indexing task that uploads and indexes a video in a single operation.You can no longer add videos to an index that has only Pegasus 1.2 enabled. When you add videos to an index that has both Marengo and Pegasus 1.2 enabled, the platform indexes them with Marengo only.Upload options:- **Local file**: Use the `video_file` parameter.
- **Publicly accessible URL**: Use the `video_url` parameter.Your videos must meet requirements based on your workflow:- **Search**: [Marengo requirements](/v1.3/docs/concepts/models/marengo/marengo-3-0#video-file-requirements).
- **Video analysis**: [Pegasus requirements](/v1.3/docs/concepts/models/pegasus/pegasus-1-6#video-file-requirements).
- If you want to both search and analyze your videos, the most restrictive requirements apply.
- This method allows you to upload files up to 2 GB in size. To upload larger files, use the [Multipart Upload API](/v1.3/api-reference/upload-content/multipart-uploads)Indexes have limits on video hours and video count. For details, see the [Video hours and video count limits](/v1.3/docs/concepts/indexes#video-hours-and-video-count-limits) section.This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.

Reference: https://docs.twelvelabs.io/api-reference/videos/tasks/create

## Authentication

- `x-api-key` header (required) — Your API key. You can find your API key on the API Keys page.

## Request

### Body (multipart/form-data)

This endpoint expects a multipart form containing an optional file.

- `index_id` (string, required) — The unique identifier of the index to which the video is being uploaded.
- `video_file` (file, optional) — Specify this parameter to upload a video from your local file system.
- `video_url` (string, optional) — Specify this parameter to upload a video from a publicly accessible URL.
- `enable_video_stream` (boolean, optional) — This parameter indicates if the platform stores the video for streaming. When set to `true`, the platform stores the video, and you can retrieve its URL by calling the [`GET`](/v1.3/api-reference/videos/retrieve) method of the `/indexes/{index-id}/videos/{video-id}` endpoint. You can then use this URL to access the stream over the HLS protocol.
- `user_metadata` (string, optional) — Metadata that helps you categorize your videos. You can specify a list of keys and values. Keys are strings, and values can be a string, a number, a boolean, or an array of strings. Send an integer wider than 53 bits (-9007199254740991 to 9007199254740991), and any identifier you want preserved verbatim, as a string. Send this value as a JSON-encoded string.

## Response

### 200

A video indexing task has successfully been created.

- `_id` (string, optional) — A string representing the unique identifier of your video indexing task.
- `video_id` (string, optional) — A string representing the unique identifier of the video associated with the specified video indexing task.

## Errors

### 400 Bad Request Error

The request has failed.

- `code` (string, optional) — A string representing the code associated with the error. See the [Error codes](/v1.3/api-reference/error-codes) page for details.
- `message` (string, optional) — A human-readable string describing the error, intended to be suitable for display in a user interface.

## Examples

**Request**

```json
{
  "index_id": "6298d673f1090f1100476d4c",
  "video_file": "<file: @/Users/john/Documents/01.mp4>"
}
```

**Response**

```json
{
  "_id": "62a1ec6d9ea24f052b971a0f",
  "video_id": "62a1ec6d9ea24f052b971a0f"
}
```

**SDK Code**

```python
import requests

url = "https://api.twelvelabs.io/v1.3/tasks"

files = { "video_file": "open('@/Users/john/Documents/01.mp4', 'rb')" }
payload = {
    "index_id": "6298d673f1090f1100476d4c",
    "video_url": ,
    "enable_video_stream": ,
    "user_metadata": 
}
headers = {"x-api-key": "<apiKey>"}

response = requests.post(url, data=payload, files=files, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.twelvelabs.io/v1.3/tasks';
const form = new FormData();
form.append('index_id', '6298d673f1090f1100476d4c');
form.append('video_file', '@/Users/john/Documents/01.mp4');
form.append('video_url', '');
form.append('enable_video_stream', '');
form.append('user_metadata', '');

const options = {method: 'POST', headers: {'x-api-key': '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.twelvelabs.io/v1.3/tasks"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"index_id\"\r\n\r\n6298d673f1090f1100476d4c\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"; filename=\"01.mp4\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"enable_video_stream\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"user_metadata\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.twelvelabs.io/v1.3/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"index_id\"\r\n\r\n6298d673f1090f1100476d4c\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"; filename=\"01.mp4\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"enable_video_stream\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"user_metadata\"\r\n\r\n\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.twelvelabs.io/v1.3/tasks")
  .header("x-api-key", "<apiKey>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"index_id\"\r\n\r\n6298d673f1090f1100476d4c\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"; filename=\"01.mp4\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"enable_video_stream\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"user_metadata\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.twelvelabs.io/v1.3/tasks', [
  'multipart' => [
    [
        'name' => 'index_id',
        'contents' => '6298d673f1090f1100476d4c'
    ],
    [
        'name' => 'video_file',
        'filename' => '@/Users/john/Documents/01.mp4',
        'contents' => null
    ]
  ]
  'headers' => [
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.twelvelabs.io/v1.3/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"index_id\"\r\n\r\n6298d673f1090f1100476d4c\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"; filename=\"01.mp4\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"enable_video_stream\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"user_metadata\"\r\n\r\n\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["x-api-key": "<apiKey>"]
let parameters = [
  [
    "name": "index_id",
    "value": "6298d673f1090f1100476d4c"
  ],
  [
    "name": "video_file",
    "fileName": "@/Users/john/Documents/01.mp4"
  ],
  [
    "name": "video_url",
    "value": 
  ],
  [
    "name": "enable_video_stream",
    "value": 
  ],
  [
    "name": "user_metadata",
    "value": 
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://api.twelvelabs.io/v1.3/tasks")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```