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

# Embed a query

> Create a single embedding from text, images, video, and audio synchronously.

This guide shows how you can create an embedding for a query using the Marengo 3.5 video understanding model. For complete specifications and input requirements, see the [Marengo 3.5](/v1.3/docs/concepts/models/marengo/marengo-3-5) page.

The Marengo video understanding model generates embeddings for all modalities in the same latent space. This shared space enables any-to-any searches across different types of content.

For details on how your usage is measured and billed, see the [Pricing](https://www.twelvelabs.io/pricing) page.

# Key concepts

This section explains the key concepts and terminology used in this guide:

* **Asset**: Your uploaded content. Once created, you can reference the same asset across multiple operations without uploading the file again.
* **Embedding**: Vector representation of your content.
* **Media source**: One image, video, or audio input that the platform combines into your embedding.

# Workflow

This guide shows how to combine text and media sources into a single embedding for retrieving matching content. This example combines text with an image and uploads the image as an asset. You can also pass a URL or base64-encoded data inline instead of creating an asset; both are shown as commented-out lines in the code examples. To upload other types of content, see [Upload and processing methods](/v1.3/docs/concepts/upload-methods).

The platform processes your request synchronously and returns the embedding in the response. Provide text, media sources, or both, and combine up to 10 media sources in one request.

**Customize your embeddings**

You can name a media source and reference it from your text, truncate text that exceeds the 2,000-token limit, and request a per-dimension uncertainty vector.

Use these embeddings for similarity search, content classification, clustering, recommendations, or Retrieval-Augmented Generation (RAG).

# Prerequisites

* To use the platform, you need an API key:

  If you don't have an account, [sign up](https://playground.twelvelabs.io/) for a free account.

  Go to the [API Keys](https://playground.twelvelabs.io/dashboard/api-keys) page.

  If you need to create a new key, select the **Create API Key** button. Enter a name and set the expiration period. The default is 12 months.

  Select the **Copy** icon next to your key to copy it to your clipboard.

* Depending on the programming language you are using, install the TwelveLabs SDK by entering one of the following commands:

  **`Python`**

  ```shell Python
  pip install --upgrade twelvelabs
  ```

  **`Node.js`**

  ```shell Node.js
  yarn add twelvelabs-js@latest # or npm install twelvelabs-js@latest
  ```

* Your media files must meet the following requirements:
  * **Request limits**: Your text can be up to 2,000 tokens, and you can combine up to 10 media sources. Each media source can be up to 32 MB, and video and audio up to 30 seconds. A PDF file also has a page allowance of 16 pages for each MB of file size. A 0.5 MB file is allowed 16 pages, and a 4 MB file is allowed 64 pages. Plain text and Markdown files have no page allowance. These limits apply whether you provide a URL, base64-encoded data, or an asset identifier. For longer or larger files, see the [Embed content at scale](/v1.3/docs/guides/create-embeddings/at-scale) page.
  * **Model capabilities**: See the complete [input requirements](/v1.3/docs/concepts/models/marengo/marengo-3-5#input-requirements) for Marengo 3.5.

# Complete example

Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values.

**`Python`**

```Python Python maxLines=12
import time
from twelvelabs import TwelveLabs, MultiInputRequest, MultiInputMediaSource

# 1. Initialize the client
client = TwelveLabs(api_key="<YOUR_API_KEY>")

# 2. Upload an image
asset = client.assets.create(
    method="url",
    url="<YOUR_IMAGE_URL>" # Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
    # Or use method="direct" and file=open("<PATH_TO_IMAGE_FILE>", "rb") to upload a local file up to 32 MB
)
print(f"Created asset: id={asset.id}")

# 3. Check the status of the asset
print("Waiting for asset to be ready...")
while True:
    asset = client.assets.retrieve(asset.id)
    if asset.status == "ready":
        print("Asset is ready")
        break
    if asset.status == "failed":
        raise RuntimeError(f"Asset processing failed: id={asset.id}")
    time.sleep(5)

# 4. Create an embedding for your query
response = client.embed.v_2.create(
    input_type="multi_input",
    model_name="marengo3.5",
    multi_input=MultiInputRequest(
        input_text="<YOUR_TEXT>",
        # To reference a media source from your text, name the source below and use <@name>:
        # input_text="A person wearing <@outfit>",
        # Omit media_sources to create an embedding from your text alone:
        media_sources=[
            MultiInputMediaSource(
                media_type="image", # Or "video", "audio", or "document"
                asset_id=asset.id,
                # url="<YOUR_MEDIA_URL>", # Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
                # base_64_string="<BASE_64_ENCODED_DATA>",
                # name="outfit", # Required when input_text references this media source
            ),
            # Add up to 10 media sources. The platform processes them in the order they appear:
            # MultiInputMediaSource(media_type="image", asset_id="<YOUR_ASSET_ID>", name="accessory"),
        ],
    ),
    # auto_truncate=True, # Truncate text above 2,000 tokens instead of returning an error
    # embedding_uncertainty=True, # Valid only when the request embeds text alone or media alone
    # embedding_dimension=512, # Queries and stored embeddings must share the same length
)

# 5. Process the results
print(f"Number of embeddings: {len(response.data)}")
if response.metadata is not None and response.metadata.embedding_dimension is not None:
    print(f"Embedding dimensions (metadata.embedding_dimension): {response.metadata.embedding_dimension}")
for embedding_data in response.data:
    print(f"Embedding dimensions: {len(embedding_data.embedding)}")
    print(f"First 10 values: {embedding_data.embedding[:10]}")
    if embedding_data.embedding_uncertainty is not None:
        print(f"First 10 uncertainty values: {embedding_data.embedding_uncertainty[:10]}")
```

**`Node.js`**

```JavaScript Node.js maxLines=12
import { TwelveLabs } from "twelvelabs-js";
// Uncomment the next line if uploading a local file
// import fs from "fs";

// 1. Initialize the client
const client = new TwelveLabs({ apiKey: "<YOUR_API_KEY>" });

// 2. Upload an image
const asset = await client.assets.create({
  method: "url",
  url: "<YOUR_IMAGE_URL>", // Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
  // Or use method: "direct" and file: fs.createReadStream("<PATH_TO_IMAGE_FILE>") to upload a local file up to 32 MB
});
console.log(`Created asset: id=${asset.id}`);

// 3. Check the status of the asset
console.log("Waiting for asset to be ready...");
let readyAsset = await client.assets.retrieve(asset.id);
while (readyAsset.status !== "ready" && readyAsset.status !== "failed") {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  readyAsset = await client.assets.retrieve(asset.id);
}
if (readyAsset.status === "failed") {
  throw new Error(`Asset processing failed: id=${asset.id}`);
}
console.log("Asset is ready");

// 4. Create an embedding for your query
const response = await client.embed.v2.create({
    inputType: "multi_input",
    modelName: "marengo3.5",
    multiInput: {
        inputText: "<YOUR_TEXT>",
        // To reference a media source from your text, name the source below and use <@name>:
        // inputText: "A person wearing <@outfit>",
        // Omit mediaSources to create an embedding from your text alone:
        mediaSources: [
            {
                mediaType: "image", // Or "video", "audio", or "document"
                assetId: asset.id,
                // url: "<YOUR_MEDIA_URL>", // Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported
                // base64String: "<BASE_64_ENCODED_DATA>",
                // name: "outfit", // Required when inputText references this media source
            },
            // Add up to 10 media sources. The platform processes them in the order they appear:
            // { mediaType: "image", assetId: "<YOUR_ASSET_ID>", name: "accessory" },
        ],
    },
    // autoTruncate: true, // Truncate text above 2,000 tokens instead of returning an error
    // embeddingUncertainty: true, // Valid only when the request embeds text alone or media alone
    // embeddingDimension: 512, // Queries and stored embeddings must share the same length
});

// 5. Process the results
console.log(`Number of embeddings: ${response.data.length}`);
if (response.metadata?.embeddingDimension != null) {
    console.log(`Embedding dimensions (metadata.embeddingDimension): ${response.metadata.embeddingDimension}`);
}
for (const embeddingData of response.data) {
    console.log(`Embedding dimensions: ${embeddingData.embedding.length}`);
    console.log(`First 10 values: ${embeddingData.embedding.slice(0, 10)}`);
    if (embeddingData.embeddingUncertainty != null) {
        console.log(`First 10 uncertainty values: ${embeddingData.embeddingUncertainty.slice(0, 10)}`);
    }
}
```

# Code explanation

#### Python

#### Import the SDK and initialize the client

Create a client instance to interact with the TwelveLabs Video Understanding Platform.\

**Function call**: You call the [constructor](/v1.3/sdk-reference/python/the-twelve-labs-class#the-initializer) of the `TwelveLabs` class.\

**Parameters**:

* `api_key`: The API key to authenticate your requests to the platform.\


**Return value**: An object of type `TwelveLabs` configured for making API calls.

#### Upload an image

Upload an image file to create an asset.\

**Function call**: You call the [`assets.create`](/v1.3/sdk-reference/python/upload-content/direct-uploads#create-an-asset) function.\

**Parameters**:

* `method`: The upload method for your asset. Use `url` for a publicly accessible or `direct` to upload a local file. This example uses `url`.
* `url` or `file`: The publicly accessible URL of your image file or an opened file object in binary read mode. This example uses `url`.

**Return value**: An object of type `Asset`. This object contains, among other information, a field named `id` representing the unique identifier of your asset.

#### Check the status of the asset

Asset processing is asynchronous. Poll the status of the asset until it is `ready` before you use it.\

**Function call**: You call the [`assets.retrieve`](/v1.3/sdk-reference/python/manage-assets#retrieve-an-asset) function.\

**Parameters**:

* `asset_id`: The unique identifier of your asset.\


**Return value**: An object of type `Asset` containing, among other information, a field named `status` representing the current status of the asset. Check this field until its value is `ready`.

#### Create an embedding for your query

**Function call**: You call the [`embed.v_2.create`](/v1.3/sdk-reference/python/create-embeddings-v-2/create-sync-embeddings#create-sync-embeddings) function.\

**Parameters**:

* `input_type`: The type of content. Set this parameter to `multi_input`.
* `model_name`: The embedding model to use. This example uses `marengo3.5`.
* *(Optional)* `auto_truncate`: Set this parameter to `true` to truncate your text when it exceeds 2,000 tokens. The default is `false`, which returns a `400` error instead.
* *(Optional)* `embedding_uncertainty`: Set this parameter to `true` to receive a `data[].embedding_uncertainty` field in the response, representing a per-dimension uncertainty vector with the same length as the `embedding` array. A higher value shows lower confidence in that dimension. Set this parameter to `true` only when your request embeds text only, or media only. A request that combines text with media sources returns a `400` error.
* *(Optional)* `embedding_dimension`: The number of dimensions of the embedding: `128`, `256`, or `512`. The default is `512`. A query and the embeddings you compare it against must share the same length, so use the same value as for your stored embeddings.
* `multi_input`: A `MultiInputRequest` object containing the following properties:

  * *(Optional)* `input_text`: The text to include in the embedding. The maximum length is 2,000 tokens. To reference a specific media source, use the `<@name>` format, where `name` matches the `name` field of that media source.
  * *(Optional)* `media_sources`: An array of up to 10 `MultiInputMediaSource` objects. The platform processes them in the order they appear. Each object contains the following properties:
    * `media_type`: The type of media. Valid values are `image`, `video`, `audio`, and `document`.
    * The source of the media file. Specify one of the following:
      * `asset_id`: The unique identifier of an asset from a previous upload.
      * `url`: The publicly accessible URL of the media file.
      * `base_64_string`: The base64-encoded media data.

        This example uses the identifier of the asset created in the previous step.
    * *(Optional)* `name`: A unique name for this media source. This property is required when `input_text` references this media source.

  Provide `input_text`, `media_sources`, or both.

**Return value**: An object of type `EmbeddingSuccessResponse` with the following fields:

* `data`: A list of embedding objects. A request that combines text with media sources returns one embedding in this list. Each embedding object includes:
  * `embedding`: An array of floats representing the embedding vector.
  * `embedding_uncertainty`: A per-dimension uncertainty vector with the same length as the `embedding` array. A higher value shows lower confidence in that dimension. Present when the request sets `embedding_uncertainty` to `true`.
  * `embedding_option`: The type of embedding generated.
* `metadata.embedding_dimension`: The number of dimensions of the embeddings this request returns. Only Marengo 3.5 returns this field.
* `usage`: Token counts for your request.

#### Process the results

This example prints the number of embeddings, their dimensions, and the first 10 values of each embedding, plus the conditional fields from the previous step when present.

#### Node.js

#### Import the SDK and initialize the client

Create a client instance to interact with the TwelveLabs Video Understanding Platform.\

**Function call**: You call the [constructor](/v1.3/sdk-reference/node-js/the-twelve-labs-class#the-constructor) of the `TwelveLabs` class.\

**Parameters**: You pass all parameters as properties of a single object.

* `apiKey`: The API key to authenticate your requests to the platform.\


**Return value**: An object of type `TwelveLabs` configured for making API calls.

#### Upload an image file

Upload an image file to create an asset.\

**Function call**: You call the [`assets.create`](/v1.3/sdk-reference/node-js/upload-content/direct-uploads#create-an-asset) function.\

**Parameters**: You pass all parameters as properties of a single object.

* `method`: The upload method for your asset. Use `url` for a publicly accessible or `direct` to upload a local file. This example uses `url`.
* `url` or `file`: The publicly accessible URL of your image file or an opened file object in binary read mode. This example uses `url`.

**Return value**: An `HttpResponsePromise` that resolves to an object of type `Asset`. This object contains, among other information, a field named `id` representing the unique identifier of your asset.

#### Check the status of the asset

Asset processing is asynchronous. Poll the status of the asset until it is `ready` before you use it.\

**Function call**: You call the [`assets.retrieve`](/v1.3/sdk-reference/node-js/manage-assets#retrieve-an-asset) function.\

**Parameters**: You pass the parameter as a positional argument.

* `assetId`: The unique identifier of your asset.\


**Return value**: An `HttpResponsePromise` that resolves to an object of type `Asset` containing, among other information, a field named `status` representing the current status of the asset. Check this field until its value is `ready`.

#### Create an embedding for your query

**Function call**: You call the [`embed.v2.create`](/v1.3/sdk-reference/node-js/create-embeddings-v-2/create-sync-embeddings#create-sync-embeddings) function.\

**Parameters**:

* `inputType`: The type of content. Set this parameter to `multi_input`.
* `modelName`: The embedding model to use. This example uses `marengo3.5`.
* *(Optional)* `autoTruncate`: Set this parameter to `true` to truncate your text when it exceeds 2,000 tokens. The default is `false`, which returns a `400` error instead.
* *(Optional)* `embeddingUncertainty`: Set this parameter to `true` to receive a `data[].embeddingUncertainty` field in the response, representing a per-dimension uncertainty vector with the same length as the `embedding` array. A higher value shows lower confidence in that dimension. Set this parameter to `true` only when your request embeds text only, or media only. A request that combines text with media sources returns a `400` error.
* *(Optional)* `embeddingDimension`: The number of dimensions of the embedding: `128`, `256`, or `512`. The default is `512`. A query and the embeddings you compare it against must share the same length, so use the same value as for your stored embeddings.
* `multiInput`: An object containing the following properties:

  * *(Optional)* `inputText`: The text to include in the embedding. The maximum length is 2,000 tokens. To reference a specific media source, use the `<@name>` format, where `name` matches the `name` field of that media source.
  * *(Optional)* `mediaSources`: An array of up to 10 objects. The platform processes them in the order they appear. Each object contains the following properties:
    * `mediaType`: The type of media. Valid values are `image`, `video`, `audio`, and `document`.
    * The source of the media file. Specify one of the following:
      * `assetId`: The unique identifier of an asset from a previous upload.
      * `url`: The publicly accessible URL of the media file.
      * `base64String`: The base64-encoded media data.

        This example uses the identifier of the asset created in the previous step.
    * *(Optional)* `name`: A unique name for this media source. This property is required when `inputText` references this media source.

  Provide `inputText`, `mediaSources`, or both.

**Return value**: An `HttpResponsePromise` that resolves to an object of type `EmbeddingSuccessResponse` with the following fields:

* `data`: A list of embedding objects. A request that combines text with media sources returns one embedding in this list. Each embedding object includes:
  * `embedding`: An array of floats representing the embedding vector.
  * `embeddingUncertainty`: A per-dimension uncertainty vector with the same length as the `embedding` array. A higher value shows lower confidence in that dimension. Present when the request sets `embeddingUncertainty` to `true`.
  * `embeddingOption`: The type of embedding generated.
* `metadata.embeddingDimension`: The number of dimensions of the embeddings this request returns. Only Marengo 3.5 returns this field.
* `usage`: Token counts for your request.

#### Process the results

This example prints the number of embeddings, their dimensions, and the first 10 values of each embedding, plus the conditional fields from the previous step when present.